From 20b1a40fca155271992e0a68bdc4346237b3e1ee Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 2 May 2024 12:01:50 +1000 Subject: [PATCH 1/2] AddDeletedByToSpreeProducts --- ...0240502011542_add_deleted_by_to_spree_products.rb | 6 ++++++ db/schema.rb | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20240502011542_add_deleted_by_to_spree_products.rb diff --git a/db/migrate/20240502011542_add_deleted_by_to_spree_products.rb b/db/migrate/20240502011542_add_deleted_by_to_spree_products.rb new file mode 100644 index 00000000000..fa98cd806da --- /dev/null +++ b/db/migrate/20240502011542_add_deleted_by_to_spree_products.rb @@ -0,0 +1,6 @@ +class AddDeletedByToSpreeProducts < ActiveRecord::Migration[7.0] + def change + add_column :spree_products, :deleted_by_id, :integer, null: true + add_foreign_key :spree_products, :spree_users, column: :deleted_by_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 42e4b6ac401..6c3fb8cc026 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_04_30_075133) do +ActiveRecord::Schema[7.0].define(version: 2024_05_02_011542) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" @@ -101,7 +101,7 @@ t.datetime "terms_and_conditions_accepted_at", precision: nil t.string "first_name", default: "", null: false t.string "last_name", default: "", null: false - t.boolean "created_manually", default: false + t.boolean "created_manually", default: false, null: false t.index ["bill_address_id"], name: "index_customers_on_bill_address_id" t.index ["created_manually"], name: "index_customers_on_created_manually" t.index ["email"], name: "index_customers_on_email" @@ -220,9 +220,9 @@ t.string "email_address", limit: 255 t.boolean "require_login", default: false, null: false t.boolean "allow_guest_orders", default: true, null: false + t.boolean "allow_order_changes", default: false, null: false t.text "invoice_text" t.boolean "display_invoice_logo", default: false - t.boolean "allow_order_changes", default: false, null: false t.boolean "enable_subscriptions", default: false, null: false t.integer "business_address_id" t.boolean "show_customer_names_to_suppliers", default: false, null: false @@ -301,7 +301,7 @@ t.bigint "order_id" t.integer "number" t.jsonb "data" - t.date "date", default: -> { "CURRENT_TIMESTAMP" } + t.date "date", default: -> { "now()" } t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "cancelled", default: false, null: false @@ -701,6 +701,7 @@ t.integer "primary_taxon_id" t.boolean "inherits_properties", default: true, null: false t.string "sku", limit: 255, default: "", null: false + t.integer "deleted_by_id" t.index ["deleted_at"], name: "index_products_on_deleted_at" t.index ["name"], name: "index_products_on_name" t.index ["primary_taxon_id"], name: "index_spree_products_on_primary_taxon_id" @@ -1109,7 +1110,7 @@ create_table "vouchers", force: :cascade do |t| t.string "code", limit: 255, null: false - t.datetime "expiry_date" + t.datetime "expiry_date", precision: nil t.datetime "created_at", null: false t.datetime "updated_at", null: false t.bigint "enterprise_id" @@ -1203,6 +1204,7 @@ add_foreign_key "spree_products", "spree_shipping_categories", column: "shipping_category_id", name: "spree_products_shipping_category_id_fk" add_foreign_key "spree_products", "spree_tax_categories", column: "tax_category_id", name: "spree_products_tax_category_id_fk" add_foreign_key "spree_products", "spree_taxons", column: "primary_taxon_id", name: "spree_products_primary_taxon_id_fk" + add_foreign_key "spree_products", "spree_users", column: "deleted_by_id" add_foreign_key "spree_return_authorizations", "spree_orders", column: "order_id", name: "spree_return_authorizations_order_id_fk" add_foreign_key "spree_roles_users", "spree_roles", column: "role_id", name: "spree_roles_users_role_id_fk" add_foreign_key "spree_roles_users", "spree_users", column: "user_id", name: "spree_roles_users_user_id_fk" From a38f22fbee56f0e287c090deb0625281086f3f6b Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 2 May 2024 12:05:40 +1000 Subject: [PATCH 2/2] Save deleted_by user when deleting products --- app/controllers/api/v0/products_controller.rb | 2 +- app/models/spree/product.rb | 6 ++++++ app/reflexes/products_reflex.rb | 2 +- spec/controllers/api/v0/products_controller_spec.rb | 1 + spec/models/spree/product_spec.rb | 10 ++++++++++ spec/reflexes/products_reflex_spec.rb | 1 + 6 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v0/products_controller.rb b/app/controllers/api/v0/products_controller.rb index eead37ca494..5d813465912 100644 --- a/app/controllers/api/v0/products_controller.rb +++ b/app/controllers/api/v0/products_controller.rb @@ -42,7 +42,7 @@ def destroy authorize! :delete, Spree::Product @product = product_finder.find_product authorize! :delete, @product - @product.destroy + @product.destroy(deleted_by: current_api_user) render json: @product, serializer: Api::Admin::ProductSerializer, status: :no_content end diff --git a/app/models/spree/product.rb b/app/models/spree/product.rb index 4fd670f90e5..b5bfdd36080 100755 --- a/app/models/spree/product.rb +++ b/app/models/spree/product.rb @@ -33,6 +33,7 @@ class Product < ApplicationRecord searchable_scopes :active, :with_properties belongs_to :supplier, class_name: 'Enterprise', optional: false, touch: true + belongs_to :deleted_by, class_name: "Spree::User", optional: true has_one :image, class_name: "Spree::Image", as: :viewable, dependent: :destroy @@ -260,6 +261,11 @@ def import_date variants.map(&:import_date).compact.max end + def destroy(deleted_by: nil) + update_attribute(:deleted_by, deleted_by) if deleted_by.present? + super() + end + def destruction transaction do touch_distributors diff --git a/app/reflexes/products_reflex.rb b/app/reflexes/products_reflex.rb index 9cad290331d..3f7f3969601 100644 --- a/app/reflexes/products_reflex.rb +++ b/app/reflexes/products_reflex.rb @@ -26,7 +26,7 @@ def delete_product product = product_finder(id).find_product authorize! :delete, product - if product.destroy + if product.destroy(deleted_by: current_user) flash[:success] = I18n.t('admin.products_v3.delete_product.success') else flash[:error] = I18n.t('admin.products_v3.delete_product.error') diff --git a/spec/controllers/api/v0/products_controller_spec.rb b/spec/controllers/api/v0/products_controller_spec.rb index 4abba9f3bd7..5ec3363c16e 100644 --- a/spec/controllers/api/v0/products_controller_spec.rb +++ b/spec/controllers/api/v0/products_controller_spec.rb @@ -81,6 +81,7 @@ expect(response.status).to eq(204) expect { product.reload }.not_to raise_error expect(product.deleted_at).not_to be_nil + expect(product.deleted_by).to eq current_api_user end it "is denied access to deleting another enterprises' product" do diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 7efd2da0240..34bdbaee464 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -28,6 +28,12 @@ module Spree expect(product.deleted_at).not_to be_nil expect(product.variants.all? { |v| !v.deleted_at.nil? }).to be_truthy end + + it "should set deleted_by user if provided" do + user = create(:user) + product.destroy(deleted_by: user) + expect(product.reload.deleted_by).to eq user + end end end @@ -340,6 +346,10 @@ module Spree it "removes variants from order cycles" do expect { product.destroy }.to change { ExchangeVariant.count } end + + #todo: it "aborts if exchange variants failed to delete" + # expect(product.deleted_at).to be_nil + # expect(product.deleted_by).to be_nil end it "updates units when saved change to variant unit" do diff --git a/spec/reflexes/products_reflex_spec.rb b/spec/reflexes/products_reflex_spec.rb index 97bf6171616..5e4bab3b1b4 100644 --- a/spec/reflexes/products_reflex_spec.rb +++ b/spec/reflexes/products_reflex_spec.rb @@ -29,6 +29,7 @@ subject.run(action_name) product.reload expect(product.deleted_at).not_to be_nil + expect(product.deleted_by).to eq current_user expect(flash[:success]).to eq('Successfully deleted the product') end