mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-04 22:16:08 +00:00
Add needed quantities to existing line items
This commit is contained in:
@@ -4,10 +4,6 @@ class BackorderJob < ApplicationJob
|
||||
FDC_BASE_URL = "https://env-0105831.jcloud-ver-jpe.ik-server.com/api/dfc/Enterprises/test-hodmedod"
|
||||
FDC_CATALOG_URL = "#{FDC_BASE_URL}/SuppliedProducts".freeze
|
||||
FDC_ORDERS_URL = "#{FDC_BASE_URL}/Orders".freeze
|
||||
FDC_SALE_SESSION_URL = "#{FDC_BASE_URL}/SalesSession/#".freeze
|
||||
|
||||
# The FDC implementation needs special ids for new objects:
|
||||
FDC_ORDER_LINES_URL = "#{FDC_ORDERS_URL}/#/OrderLines".freeze
|
||||
|
||||
queue_as :default
|
||||
|
||||
@@ -35,17 +31,15 @@ class BackorderJob < ApplicationJob
|
||||
backorder = orderer.find_or_build_order(order)
|
||||
catalog = load_catalog(order.distributor.owner)
|
||||
|
||||
linked_variants.each_with_index do |variant, index|
|
||||
linked_variants.each do |variant|
|
||||
needed_quantity = -1 * variant.on_hand
|
||||
offer = best_offer(catalog, variant)
|
||||
|
||||
# Order lines are enumerated in the FDC API:
|
||||
line = build_order_line(offer, needed_quantity)
|
||||
line.semanticId = "#{FDC_ORDER_LINES_URL}/#{index}"
|
||||
backorder.lines << line
|
||||
line = orderer.find_or_build_order_line(backorder, offer)
|
||||
line.quantity = line.quantity.to_i + needed_quantity
|
||||
end
|
||||
|
||||
backorderer.send_order(order, backorder)
|
||||
orderer.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.
|
||||
@@ -54,16 +48,6 @@ class BackorderJob < ApplicationJob
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_order_line(offer, quantity)
|
||||
OrderLineBuilder.build(offer, quantity)
|
||||
end
|
||||
|
||||
def self.build_sale_session(order)
|
||||
SaleSessionBuilder.build(order.order_cycle).tap do |session|
|
||||
session.semanticId = FDC_SALE_SESSION_URL
|
||||
end
|
||||
end
|
||||
|
||||
def self.best_offer(catalog, variant)
|
||||
link = variant.semantic_links[0]
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ class FdcBackorderer
|
||||
FDC_BASE_URL = "https://env-0105831.jcloud-ver-jpe.ik-server.com/api/dfc/Enterprises/test-hodmedod"
|
||||
FDC_ORDERS_URL = "#{FDC_BASE_URL}/Orders".freeze
|
||||
FDC_NEW_ORDER_URL = "#{FDC_ORDERS_URL}/#".freeze
|
||||
FDC_SALE_SESSION_URL = "#{FDC_BASE_URL}/SalesSession/#".freeze
|
||||
|
||||
def find_or_build_order(ofn_order)
|
||||
remote_order = find_open_order(ofn_order.distributor.owner)
|
||||
@@ -44,6 +45,33 @@ class FdcBackorderer
|
||||
end
|
||||
end
|
||||
|
||||
def find_or_build_order_line(order, offer)
|
||||
find_order_line(order, offer) || build_order_line(order, offer)
|
||||
end
|
||||
|
||||
def build_order_line(order, offer)
|
||||
# Order lines are enumerated in the FDC API and we must assign a unique
|
||||
# semantic id. We need to look at current ids to avoid collisions.
|
||||
# existing_ids = order.lines.map do |line|
|
||||
# line.semanticId.match(/[0-9]+$/).to_s.to_i
|
||||
# end
|
||||
# next_id = existing_ids.max.to_i + 1
|
||||
|
||||
# Suggested by FDC team:
|
||||
next_id = order.lines.count + 1
|
||||
|
||||
OrderLineBuilder.build(offer, 0).tap do |line|
|
||||
line.semanticId = "#{order.semanticId}/OrderLines/#{next_id}"
|
||||
order.lines << line
|
||||
end
|
||||
end
|
||||
|
||||
def find_order_line(order, offer)
|
||||
order.lines.find do |line|
|
||||
line.offer.offeredItem.semanticId == offer.offeredItem.semanticId
|
||||
end
|
||||
end
|
||||
|
||||
def import(user, url)
|
||||
api = DfcRequest.new(user)
|
||||
json = api.call(url)
|
||||
@@ -54,17 +82,24 @@ class FdcBackorderer
|
||||
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:
|
||||
session = build_sale_session(ofn_order)
|
||||
json = DfcIo.export(backorder, *lines, *offers, *products, session)
|
||||
api.call(FDC_ORDERS_URL, json)
|
||||
else
|
||||
# Update existing:
|
||||
api.call(backorder.semanticId, json)
|
||||
json = DfcIo.export(backorder, *lines, *offers, *products)
|
||||
api.call(backorder.semanticId, json, method: :put)
|
||||
end
|
||||
end
|
||||
|
||||
def build_sale_session(order)
|
||||
SaleSessionBuilder.build(order.order_cycle).tap do |session|
|
||||
session.semanticId = FDC_SALE_SESSION_URL
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,15 +13,15 @@ class DfcRequest
|
||||
@user = user
|
||||
end
|
||||
|
||||
def call(url, data = nil)
|
||||
def call(url, data = nil, method: nil)
|
||||
begin
|
||||
response = request(url, data)
|
||||
response = request(url, data, method:)
|
||||
rescue Faraday::UnauthorizedError, Faraday::ForbiddenError
|
||||
raise unless token_stale?
|
||||
|
||||
# If access was denied and our token is stale then refresh and retry:
|
||||
refresh_access_token!
|
||||
response = request(url, data)
|
||||
response = request(url, data, method:)
|
||||
end
|
||||
|
||||
response.body
|
||||
@@ -29,9 +29,11 @@ class DfcRequest
|
||||
|
||||
private
|
||||
|
||||
def request(url, data = nil)
|
||||
def request(url, data = nil, method: nil)
|
||||
only_public_connections do
|
||||
if data
|
||||
if method == :put
|
||||
connection.put(url, data)
|
||||
elsif data
|
||||
connection.post(url, data)
|
||||
else
|
||||
connection.get(url)
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -31,6 +31,8 @@ RSpec.describe BackorderJob do
|
||||
semantic_id: product_link
|
||||
)
|
||||
BackorderJob.check_stock(order)
|
||||
|
||||
expect(variant.on_hand).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -35,4 +35,33 @@ RSpec.describe FdcBackorderer do
|
||||
expect(backorder.lines.count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "#find_or_build_order_line" do
|
||||
it "add quantity to an existing line item", vcr: true do
|
||||
catalog = BackorderJob.load_catalog(order.distributor.owner)
|
||||
backorder = subject.find_or_build_order(order)
|
||||
existing_line = backorder.lines[0]
|
||||
|
||||
# The FDC API returns different ids for the same offer.
|
||||
# In order to test that we can still match it, we are retrieving
|
||||
# the catalog offer here which is different to the offer on the
|
||||
# existing order line.
|
||||
ordered_product = existing_line.offer.offeredItem
|
||||
catalog_product = catalog.find do |i|
|
||||
i.semanticId == ordered_product.semanticId
|
||||
end
|
||||
catalog_offer = BackorderJob.offer_of(catalog_product)
|
||||
|
||||
# The API response is missing this connection:
|
||||
catalog_offer.offeredItem = catalog_product
|
||||
|
||||
# Just confirm that we got good test data from the API:
|
||||
expect(backorder.semanticId).to match %r{^https.*/[0-9]+$}
|
||||
expect(backorder.lines.count).to eq 1
|
||||
|
||||
found_line = subject.find_or_build_order_line(backorder, catalog_offer)
|
||||
|
||||
expect(found_line).to eq existing_line
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user