mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-26 01:33:22 +00:00
Find and update existing open order
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
199
spec/fixtures/vcr_cassettes/FdcBackorderer/_find_or_build_order/finds_an_order_object.yml
vendored
Normal file
199
spec/fixtures/vcr_cassettes/FdcBackorderer/_find_or_build_order/finds_an_order_object.yml
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user