mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-21 05:09:15 +00:00
Create source variants
This commit is contained in:
@@ -107,6 +107,39 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
# Clone a variant, retaining a link to the "source"
|
||||
def create_sourced_variant
|
||||
source_variant = Spree::Variant.find(params[:variant_id])
|
||||
product_index = params[:product_index]
|
||||
authorize! :create_sourced_variant, source_variant
|
||||
status = :ok
|
||||
|
||||
begin
|
||||
variant = source_variant.dup #may need a VariantDuplicator like producs?
|
||||
variant.price = source_variant.price
|
||||
variant.save!
|
||||
variant.on_demand = source_variant.on_demand
|
||||
variant.on_hand = source_variant.on_hand
|
||||
variant.save!
|
||||
#todo: create link to source
|
||||
|
||||
flash.now[:success] = t('.success')
|
||||
variant_index = "-#{variant.id}"
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
flash.now[:error] = variant.errors.full_messages.to_sentence
|
||||
status = :unprocessable_entity
|
||||
variant_index = "-1" # Create a unique-enough index
|
||||
end
|
||||
|
||||
respond_with do |format|
|
||||
format.turbo_stream {
|
||||
locals = { source_variant:, variant:, product_index:, variant_index:,
|
||||
producer_options:, category_options: categories, tax_category_options: }
|
||||
render :create_sourced_variant, status:, locals:
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def index_url(params)
|
||||
"/admin/products?#{params.to_query}" # todo: fix routing so this can be automaticly generated
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- next if variant.supplier.present? && !allowed_producers.include?(variant.supplier)
|
||||
= form.fields_for("products][#{product_index}][variants_attributes", variant, index: variant_index) do |variant_form|
|
||||
%tr.condensed{ id: dom_id(variant), 'data-controller': "variant", 'class': "nested-form-wrapper", 'data-new-record': variant.new_record? ? "true" : false }
|
||||
= render partial: 'variant_row', locals: { variant:, f: variant_form, category_options:, tax_category_options:, producer_options: }
|
||||
= render partial: 'variant_row', locals: { variant:, f: variant_form, product_index:, category_options:, tax_category_options:, producer_options: }
|
||||
|
||||
= form.fields_for("products][#{product_index}][variants_attributes][NEW_RECORD", prepare_new_variant(product, producer_options)) do |new_variant_form|
|
||||
%template{ 'data-nested-form-target': "template" }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-# locals: (variant:, f:, category_options:, tax_category_options:, producer_options:)
|
||||
-# locals: (variant:, f:, product_index: nil, category_options:, tax_category_options:, producer_options:)
|
||||
- method_on_demand, method_on_hand = variant.new_record? ? [:on_demand_desired, :on_hand_desired ]: [:on_demand, :on_hand]
|
||||
%td.col-image
|
||||
-# empty
|
||||
@@ -89,7 +89,7 @@
|
||||
- if variant.persisted?
|
||||
= link_to t('admin.products_page.actions.edit'), edit_admin_product_variant_path(variant.product, variant)
|
||||
/ TODO: only show if have permission. need to load permissions efficiently please. maybe the PErmissions object can cache result for each enterprise. maybe we preload it with the product query.
|
||||
= link_to t('admin.products_page.actions.create_sourced_variant'), "TODO" # see next commit
|
||||
= link_to t('admin.products_page.actions.create_sourced_variant'), admin_create_sourced_variant_path(variant_id: variant.id, product_index:), 'data-turbo-method': :post
|
||||
- if variant.product.variants.size > 1
|
||||
%a{ "data-controller": "modal-link", "data-action": "click->modal-link#setModalDataSetOnConfirm click->modal-link#open",
|
||||
"data-modal-link-target-value": "variant-delete-modal", "class": "delete",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
-# locals: (variant:, source_variant:, product_index:, variant_index:, producer_options:, category_options:, tax_category_options:)
|
||||
-# Pre-render the form, because you can't do it inside turbo stream block
|
||||
- variant_row = nil
|
||||
- fields_for("products][#{product_index}][variants_attributes", variant, index: variant_index) do |f|
|
||||
- variant_row = render(partial: 'variant_row', formats: :html,
|
||||
locals: { f:,
|
||||
variant:,
|
||||
producer_options:,
|
||||
category_options:,
|
||||
tax_category_options:})
|
||||
= turbo_stream.after dom_id(source_variant) do
|
||||
%tr.condensed{ id: dom_id(variant), 'data-controller': "variant", 'class': "nested-form-wrapper slide-in" }
|
||||
= variant_row
|
||||
|
||||
= turbo_stream.append "flashes" do
|
||||
= render(partial: 'admin/shared/flashes', locals: { flashes: flash })
|
||||
@@ -1099,6 +1099,8 @@ en:
|
||||
clone:
|
||||
success: Successfully cloned the product
|
||||
error: Unable to clone the product
|
||||
create_sourced_variant:
|
||||
success: "Successfully created sourced variant"
|
||||
tag_rules:
|
||||
rules_per_tag:
|
||||
one: "%{tag} has 1 rule"
|
||||
|
||||
@@ -82,6 +82,7 @@ Openfoodnetwork::Application.routes.draw do
|
||||
delete 'products_v3/:id', to: 'products_v3#destroy', as: 'product_destroy'
|
||||
delete 'products_v3/destroy_variant/:id', to: 'products_v3#destroy_variant', as: 'destroy_variant'
|
||||
post 'clone/:id', to: 'products_v3#clone', as: 'clone_product'
|
||||
post 'products/create_sourced_variant', to: 'products_v3#create_sourced_variant', as: 'create_sourced_variant'
|
||||
resources :product_preview, only: [:show]
|
||||
|
||||
resources :variant_overrides do
|
||||
|
||||
@@ -59,4 +59,45 @@ RSpec.describe "Admin::ProductsV3" do
|
||||
expect(response).to redirect_to('/unauthorized')
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /admin/products/create_sourced_variant" do
|
||||
let(:enterprise) { create(:supplier_enterprise) }
|
||||
let(:user) { create(:user, enterprises: [enterprise]) }
|
||||
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:variant) { create(:variant, display_name: "Original variant", supplier: supplier) }
|
||||
|
||||
before do
|
||||
sign_in user
|
||||
end
|
||||
|
||||
it "checks for permission" do
|
||||
params = { variant_id: variant.id, product_index: 1 }
|
||||
|
||||
expect {
|
||||
post(admin_create_sourced_variant_path, as: :turbo_stream, params:)
|
||||
expect(response).to redirect_to('/unauthorized')
|
||||
}.not_to change { variant.product.variants.count }
|
||||
end
|
||||
|
||||
context "With create_sourced_variants permissions on supplier" do
|
||||
let!(:enterprise_relationship) {
|
||||
create(:enterprise_relationship,
|
||||
parent: supplier,
|
||||
child: enterprise,
|
||||
permissions_list: [:create_sourced_variants])
|
||||
}
|
||||
|
||||
it "creates a clone of the variant, retaining link as source" do
|
||||
params = { variant_id: variant.id, product_index: 1 }
|
||||
|
||||
expect {
|
||||
post(admin_create_sourced_variant_path, as: :turbo_stream, params:)
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(response.body).to match "Original variant" # cloned variant name
|
||||
}.to change { variant.product.variants.count }.by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -291,19 +291,30 @@ RSpec.describe 'As an enterprise user, I can perform actions on the products scr
|
||||
end
|
||||
|
||||
context "with create_sourced_variants permission for my, and other's variants" do
|
||||
it "shows an option to create sourced variant" do
|
||||
it "creates a sourced variant" do
|
||||
create(:enterprise_relationship, parent: producer, child: producer,
|
||||
permissions_list: [:create_sourced_variants])
|
||||
enterprise_relationship.permissions.create! name: :create_sourced_variants
|
||||
|
||||
# Check my own variant
|
||||
within row_containing_name("My box") do
|
||||
page.find(".vertical-ellipsis-menu").click
|
||||
expect(page).to have_link "Create sourced variant" # , href: admin_clone_product_path(product_a)
|
||||
|
||||
expect(page).to have_link "Create sourced variant"
|
||||
end
|
||||
|
||||
# Create variant sourced from my friend
|
||||
within row_containing_name("My friends box") do
|
||||
page.find(".vertical-ellipsis-menu").click
|
||||
expect(page).to have_link "Create sourced variant" # , href: admin_clone_product_path(product_a)
|
||||
|
||||
click_link "Create sourced variant"
|
||||
end
|
||||
|
||||
expect(page).to have_content "Successfully created sourced variant"
|
||||
|
||||
within "table.products" do
|
||||
# There are now two copies
|
||||
expect(all_input_values).to match /My friends box.*My friends box/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user