Find and update existing open order

This commit is contained in:
Maikel Linke
2024-08-30 17:03:55 +10:00
parent 827e37cada
commit caa6d284f0
4 changed files with 283 additions and 12 deletions

View File

@@ -31,7 +31,8 @@ class BackorderJob < ApplicationJob
end
def self.place_backorder(order, linked_variants)
backorder = FdcBackorderer.new.find_or_build_order(order)
orderer = FdcBackorderer.new
backorder = orderer.find_or_build_order(order)
catalog = load_catalog(order.distributor.owner)
linked_variants.each_with_index do |variant, index|
@@ -44,16 +45,7 @@ class BackorderJob < ApplicationJob
backorder.lines << line
end
lines = backorder.lines
offers = lines.map(&:offer)
products = offers.map(&:offeredItem)
session = build_sale_session(order)
json = DfcIo.export(backorder, *lines, *offers, *products, session)
api = DfcRequest.new(order.distributor.owner)
# Create order via POST:
api.call(FDC_ORDERS_URL, json)
backorderer.send_order(order, backorder)
# Once we have transformations and know the quantities in bulk products
# we will need to increase on_hand by the ordered quantity.

View File

@@ -7,6 +7,64 @@ class FdcBackorderer
FDC_NEW_ORDER_URL = "#{FDC_ORDERS_URL}/#".freeze
def find_or_build_order(ofn_order)
OrderBuilder.new_order(ofn_order, FDC_NEW_ORDER_URL)
remote_order = find_open_order(ofn_order.distributor.owner)
remote_order || OrderBuilder.new_order(ofn_order, FDC_NEW_ORDER_URL)
end
def find_open_order(user)
graph = import(user, FDC_ORDERS_URL)
open_orders = graph&.select do |o|
o.semanticType == "dfc-b:Order" && o.orderStatus[:path] == "Held"
end
return if open_orders.blank?
# If there are multiple open orders, we don't know which one to choose.
# We want the order we placed for the same distributor in the same order
# cycle before. So here are some assumptions for this to work:
#
# * We see only orders for our distributor. The endpoint URL contains the
# the distributor name and is currently hardcoded.
# * There's only one open order cycle at a time. Otherwise we may select
# an order of an old order cycle.
# * Orders are finalised when the order cycle closes. So _Held_ orders
# always belong to an open order cycle.
# * We see only our own orders. This assumption is wrong. The Shopify
# integration places held orders as well and they are visible to us.
#
# Unfortunately, the endpoint doesn't tell who placed the order.
# TODO: We need to remember the link to the order locally.
# Or the API is updated to include the orderer.
#
# For now, we just guess:
open_orders.last.tap do |order|
# The DFC Connector doesn't recognise status values properly yet.
# So we are overriding the value with something that can be exported.
order.orderStatus = "dfc-v:Held"
end
end
def import(user, url)
api = DfcRequest.new(user)
json = api.call(url)
DfcIo.import(json)
end
def send_order(ofn_order, backorder)
lines = backorder.lines
offers = lines.map(&:offer)
products = offers.map(&:offeredItem)
session = build_sale_session(ofn_order)
json = DfcIo.export(backorder, *lines, *offers, *products, session)
api = DfcRequest.new(ofn_order.distributor.owner)
if backorder.semanticId == FDC_NEW_ORDER_URL
# Create order via POST:
api.call(FDC_ORDERS_URL, json)
else
# Update existing:
api.call(backorder.semanticId, json)
end
end
end

File diff suppressed because one or more lines are too long

View File

@@ -4,13 +4,35 @@ require 'spec_helper'
RSpec.describe FdcBackorderer do
let(:order) { create(:completed_order_with_totals) }
let(:account) {
OidcAccount.new(
uid: "testdfc@protonmail.com",
refresh_token: ENV.fetch("OPENID_REFRESH_TOKEN"),
updated_at: 1.day.ago,
)
}
before do
order.distributor.owner.oidc_account = account
end
describe "#find_or_build_order" do
it "builds an order object" do
account.updated_at = Time.zone.now
stub_request(:get, FdcBackorderer::FDC_ORDERS_URL)
.to_return(status: 200, body: "{}")
backorder = subject.find_or_build_order(order)
expect(backorder.semanticId).to match %r{^https.*/\#$}
expect(backorder.lines).to eq []
end
it "finds an order object", vcr: true do
backorder = subject.find_or_build_order(order)
expect(backorder.semanticId).to match %r{^https.*/[0-9]+$}
expect(backorder.lines.count).to eq 1
end
end
end