Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ecommerce/fulfillment/lib/fulfillment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
require_relative "fulfillment/events/order_registered"
require_relative "fulfillment/events/order_confirmed"
require_relative "fulfillment/events/order_cancelled"
require_relative "fulfillment/events/order_archived"
require_relative "fulfillment/commands/register_order"
require_relative "fulfillment/commands/confirm_order"
require_relative "fulfillment/commands/cancel_order"
require_relative "fulfillment/commands/archive_order"
require_relative "fulfillment/on_register_order"
require_relative "fulfillment/on_cancel_order"
require_relative "fulfillment/on_confirm_order"
require_relative "fulfillment/on_archive_order"
require_relative "fulfillment/order"
require_relative "fulfillment/number_generator"
require_relative "fulfillment/fake_number_generator"
Expand All @@ -22,6 +25,7 @@ def call(event_store, command_bus)
command_bus.register(RegisterOrder, OnRegisterOrder.new(event_store, @number_generator.call))
command_bus.register(ConfirmOrder, OnConfirmOrder.new(event_store))
command_bus.register(CancelOrder, OnCancelOrder.new(event_store))
command_bus.register(ArchiveOrder, OnArchiveOrder.new(event_store))
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Fulfillment
class ArchiveOrder < Infra::Command
attribute :order_id, Infra::Types::UUID

alias aggregate_id order_id
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Fulfillment
class OrderArchived < Infra::Event
attribute :order_id, Infra::Types::UUID
end
end
15 changes: 15 additions & 0 deletions ecommerce/fulfillment/lib/fulfillment/on_archive_order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Fulfillment
class OnArchiveOrder
def initialize(event_store)
@repository = Infra::AggregateRootRepository.new(event_store)
end

def call(command)
@repository.with_aggregate(Order, command.aggregate_id) do |order|
order.archive
end
end
end
end
8 changes: 8 additions & 0 deletions ecommerce/fulfillment/lib/fulfillment/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def cancel
apply OrderCancelled.new(data: { order_id: @id })
end

def archive
apply OrderArchived.new(data: { order_id: @id })
end

on OrderRegistered do |event|
@state = :new
end
Expand All @@ -36,5 +40,9 @@ def cancel
on OrderCancelled do |event|
@state = :cancelled
end

on OrderArchived do |event|
@state = :archived
end
end
end
46 changes: 46 additions & 0 deletions ecommerce/fulfillment/test/archive_order_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require_relative "test_helper"

module Fulfillment
class ArchiveOrderTest < Test
cover "Fulfillment::OnArchiveOrder*"

def test_order_can_be_archived
aggregate_id = SecureRandom.uuid
stream = "Fulfillment::Order$#{aggregate_id}"

arrange(
RegisterOrder.new(order_id: aggregate_id)
)

assert_events(
stream,
OrderArchived.new(data: { order_id: aggregate_id })
) { act(ArchiveOrder.new(order_id: aggregate_id)) }
end

def test_not_registered_order_can_be_archived
aggregate_id = SecureRandom.uuid
stream = "Fulfillment::Order$#{aggregate_id}"

assert_events(
stream,
OrderArchived.new(data: { order_id: aggregate_id })
) { act(ArchiveOrder.new(order_id: aggregate_id)) }
end

def test_confirmed_order_can_be_archived
aggregate_id = SecureRandom.uuid
stream = "Fulfillment::Order$#{aggregate_id}"

arrange(
RegisterOrder.new(order_id: aggregate_id),
ConfirmOrder.new(order_id: aggregate_id)
)

assert_events(
stream,
OrderArchived.new(data: { order_id: aggregate_id })
) { act(ArchiveOrder.new(order_id: aggregate_id)) }
end
end
end
2 changes: 2 additions & 0 deletions ecommerce/product_catalog/lib/product_catalog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
require_relative "product_catalog/events"
require_relative "product_catalog/registration"
require_relative "product_catalog/naming"
require_relative "product_catalog/archivization"

module ProductCatalog

class Configuration
def call(event_store, command_bus)
command_bus.register(RegisterProduct, Registration.new(event_store))
command_bus.register(NameProduct, Naming.new(event_store))
command_bus.register(ArchiveProduct, Archivization.new(event_store))
end
end
end
16 changes: 16 additions & 0 deletions ecommerce/product_catalog/lib/product_catalog/archivization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module ProductCatalog
class Archivization
def initialize(event_store)
@event_store = event_store
end

def call(command)
@event_store.publish(
ProductArchived.new(
data: { product_id: command.product_id }
),
stream_name: "ProductCatalog$#{command.product_id}"
)
end
end
end
4 changes: 4 additions & 0 deletions ecommerce/product_catalog/lib/product_catalog/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ class NameProduct < Infra::Command
attribute :product_id, Infra::Types::UUID
attribute :name, Infra::Types::String
end

class ArchiveProduct < Infra::Command
attribute :product_id, Infra::Types::UUID
end
end
4 changes: 4 additions & 0 deletions ecommerce/product_catalog/lib/product_catalog/events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ class ProductNamed < Infra::Event
attribute :product_id, Infra::Types::String
end

class ProductArchived < Infra::Event
attribute :product_id, Infra::Types::UUID
end

end
26 changes: 26 additions & 0 deletions ecommerce/product_catalog/test/archivization_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require_relative 'test_helper'

module ProductCatalog
class ArchivizationTest < Test
cover "ProductCatalog*"

def test_product_should_get_archived
uid = SecureRandom.uuid
assert archive_product(uid)
end

def test_should_publish_event
uid = SecureRandom.uuid
product_archived = ProductCatalog::ProductArchived.new(data: { product_id: uid })
assert_events("ProductCatalog$#{uid}", product_archived) do
archive_product(uid)
end
end

private

def archive_product(uid)
run_command(ArchiveProduct.new(product_id: uid))
end
end
end
9 changes: 7 additions & 2 deletions rails_application/app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class OrdersController < ApplicationController
def index
@orders = Orders::Order.order("id DESC").page(params[:page]).per(10)
@orders = Orders::Order.where(archived: false).order("id DESC").page(params[:page]).per(10)
end

def show
Expand All @@ -21,7 +21,7 @@ def edit
@order_id = params[:id]
@order = Orders::Order.find_by_uid(params[:id])
@order_lines = Orders::OrderLine.where(order_uid: params[:id])
@products = Products::Product.all
@products = Products::Product.where(archived: false)
@customers = Customers::Customer.all
@time_promotions = TimePromotions::TimePromotion.current

Expand Down Expand Up @@ -116,6 +116,11 @@ def cancel
redirect_to root_path, notice: "Order cancelled"
end

def archive
command_bus.(Fulfillment::ArchiveOrder.new(order_id: params[:id]))
redirect_to orders_path, notice: "Order was archived"
end

private

def authorize_payment(order_id)
Expand Down
7 changes: 6 additions & 1 deletion rails_application/app/controllers/products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ProductForm
end

def index
@products = Products::Product.all
@products = Products::Product.where(archived: false)
end

def show
Expand Down Expand Up @@ -76,6 +76,11 @@ def update
redirect_to products_path, notice: "Product was successfully updated"
end

def archive
command_bus.(ProductCatalog::ArchiveProduct.new(product_id: params[:id]))
redirect_to products_path, notice: "Product was archived"
end

private

def create_product(product_id, name)
Expand Down
8 changes: 8 additions & 0 deletions rails_application/app/read_models/orders/archive_order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Orders
class ArchiveOrder
def call(event)
order = Order.find_by(uid: event.data[:order_id])
order&.update!(archived: true)
end
end
end
1 change: 1 addition & 0 deletions rails_application/app/read_models/orders/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def call(event_store)
event_store.subscribe(CancelOrder.new, to: [Fulfillment::OrderCancelled])
event_store.subscribe(UpdateTimePromotionDiscountValue.new, to: [Pricing::PercentageDiscountSet])
event_store.subscribe(RemoveTimePromotionDiscount.new, to: [Pricing::PercentageDiscountRemoved])
event_store.subscribe(ArchiveOrder.new, to: [Fulfillment::OrderArchived])

subscribe(
->(event) { broadcast_order_state_change(event.data.fetch(:order_id), 'Submitted') },
Expand Down
8 changes: 8 additions & 0 deletions rails_application/app/read_models/products/archive_product.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Products
class ArchiveProduct
def call(event)
product = Product.find_by(id: event.data[:product_id])
product&.update!(archived: true)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def call
@read_model.subscribe_copy(Inventory::StockLevelChanged, :stock_level)
@read_model.subscribe_copy(Taxes::VatRateSet, [:vat_rate, :code])
@read_model.subscribe_copy(Inventory::AvailabilityChanged, :available)
@event_store.subscribe(ArchiveProduct.new, to: [ProductCatalog::ProductArchived])
@event_store.subscribe(RefreshFuturePricesCalendar, to: [Pricing::PriceSet])
end
end
Expand Down
5 changes: 5 additions & 0 deletions rails_application/app/views/orders/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
<% if (@order.state == "Submitted") %>
<%= button_to("Cancel Order", cancel_order_path(@order.uid), class: "inline-flex items-center px-4 py-2 border rounded-md shadow-sm text-sm font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-50 border-gray-300 text-gray-700 bg-white hover:bg-gray-50") %>
<% end %>

<%= button_to 'Archive', archive_order_path(@order.uid),
method: :post,
data: { confirm: 'Are you sure?' },
class: 'ml-3 inline-flex items-center px-4 py-2 border rounded-md shadow-sm text-sm font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 border-gray-300 text-gray-700 bg-white hover:bg-gray-50' %>
<% end %>

<dl class="mb-8">
Expand Down
5 changes: 5 additions & 0 deletions rails_application/app/views/products/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
<%= primary_action_button do %>
<%= link_to 'Edit Product', edit_product_path(@product.id) %>
<% end %>

<%= button_to 'Archive', archive_product_path(@product.id),
method: :post,
data: { confirm: 'Are you sure?' },
class: 'sm:ml-3 inline-flex items-center px-4 py-2 border rounded-md shadow-sm text-sm font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 border-gray-300 text-gray-700 bg-white hover:bg-gray-50' %>
<% end %>

<dl class="mb-8">
Expand Down
2 changes: 2 additions & 0 deletions rails_application/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
post :remove_item
post :pay
post :cancel
post :archive
get :edit_discount
post :update_discount
post :remove_discount
Expand All @@ -34,6 +35,7 @@
resources :products, only: [:new, :show, :create, :index, :edit, :update] do
resources :supplies, only: [:new, :create]
member do
post :archive
post :add_future_price, to: "product/future_price#add_future_price", as: "add_future_price"
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddArchivedToProducts < ActiveRecord::Migration[7.2]
def change
add_column :products, :archived, :boolean, default: false, null: false
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddArchivedToOrders < ActiveRecord::Migration[7.2]
def change
add_column :orders, :archived, :boolean, default: false, null: false
end
end
4 changes: 3 additions & 1 deletion rails_application/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2025_09_08_135920) do
ActiveRecord::Schema[7.2].define(version: 2025_09_15_083902) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
Expand Down Expand Up @@ -173,6 +173,7 @@
t.decimal "time_promotion_discount_value", precision: 8, scale: 2
t.datetime "total_value_updated_at"
t.datetime "discount_updated_at"
t.boolean "archived", default: false, null: false
t.index ["uid"], name: "index_orders_on_uid", unique: true
end

Expand All @@ -194,6 +195,7 @@
t.string "vat_rate_code"
t.text "current_prices_calendar"
t.integer "available"
t.boolean "archived", default: false, null: false
end

create_table "public_offer_products", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
Expand Down