Import simple DFC SuppliedProduct

OFN products and variants need more data like a price but the DFC
stores that in a different object. We may get a larger graph containing
that information but we don't have any test data yet.
This commit is contained in:
Maikel Linke
2023-05-25 17:20:20 +10:00
parent df9e1ac2b4
commit ec8c710e3a
5 changed files with 78 additions and 1 deletions

View File

@@ -1,10 +1,22 @@
# frozen_string_literal: true
require "data_food_consortium/connector/connector"
# Controller used to provide the SuppliedProducts API for the DFC application
# SuppliedProducts are products that are managed by an enterprise.
module DfcProvider
class SuppliedProductsController < DfcProvider::BaseController
before_action :check_enterprise
rescue_from JSON::LD::JsonLdError::LoadingDocumentFailed, with: -> do
head :bad_request
end
def create
supplied_product = import.first
product = SuppliedProductBuilder.import(supplied_product)
product.supplier = current_enterprise
product.save!
end
def show
product = SuppliedProductBuilder.supplied_product(variant)
@@ -27,6 +39,10 @@ module DfcProvider
private
def import
DfcLoader.connector.import(request.body)
end
def variant
@variant ||=
VariantFetcher.new(current_enterprise).scope.find(params[:id])

View File

@@ -26,4 +26,19 @@ class QuantitativeValueBuilder < DfcBuilder
DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT.PIECE
end
end
def self.apply(quantity, product)
product.variant_unit, product.variant_unit_name =
case quantity.unit
when DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT.LITRE
["volume", "liter"]
when DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT.GRAM
["weight", "gram"]
else
["items", "items"]
end
product.variant_unit_scale = 1
product.unit_value = quantity.value
end
end

View File

@@ -15,4 +15,16 @@ class SuppliedProductBuilder < DfcBuilder
quantity: QuantitativeValueBuilder.quantity(variant),
)
end
def self.import(supplied_product)
Spree::Product.new(
name: supplied_product.name,
description: supplied_product.description,
price: 0, # will be in DFC Offer
primary_taxon: Spree::Taxon.first, # dummy value until we have a mapping
shipping_category: DefaultShippingCategory.find_or_create,
).tap do |product|
QuantitativeValueBuilder.apply(supplied_product.quantity, product)
end
end
end

View File

@@ -3,7 +3,7 @@
DfcProvider::Engine.routes.draw do
resources :enterprises, only: [:show] do
resources :catalog_items, only: [:index, :show, :update]
resources :supplied_products, only: [:show, :update]
resources :supplied_products, only: [:create, :show, :update]
end
resources :persons, only: [:show]
end

View File

@@ -8,6 +8,40 @@ describe "SuppliedProducts", type: :request do
let!(:product) { create(:simple_product, supplier: enterprise ) }
let!(:variant) { product.variants.first }
describe :create do
let(:endpoint) do
enterprise_supplied_products_path(enterprise_id: enterprise.id)
end
let(:supplied_product) do
SuppliedProductBuilder.supplied_product(new_variant)
end
let(:new_variant) do
# We need an id to generate a URL as semantic id when exporting.
build(:variant, id: 0, name: "Apple", unit_value: 3)
end
it "flags a bad request" do
post endpoint, headers: auth_header(user.uid)
expect(response).to have_http_status :bad_request
end
it "creates a variant" do
request_body = DfcLoader.connector.export(supplied_product)
expect do
post endpoint,
params: request_body,
headers: auth_header(user.uid)
end
.to change { enterprise.supplied_products.count }.by(1)
variant = Spree::Variant.last
expect(variant.name).to eq "Apple"
expect(variant.unit_value).to eq 3
end
end
describe :show do
it "returns variants" do
get enterprise_supplied_product_path(