Add needed quantities to existing line items

This commit is contained in:
Maikel Linke
2024-09-04 16:12:37 +10:00
parent caa6d284f0
commit a7a38890f4
7 changed files with 402 additions and 52 deletions

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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