Merge pull request #14 from exstake/feature/crypto-exchange-order-entities
add BuyCryptoOrder and SellCryptoOrder entities
This commit is contained in:
36
app/models/buy_crypto_order.rb
Normal file
36
app/models/buy_crypto_order.rb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: buy_crypto_orders
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# paid_amount_cents :integer default(0), not null
|
||||||
|
# received_amount :decimal(20, 10)
|
||||||
|
# status :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# currency_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_buy_crypto_orders_on_currency_id (currency_id)
|
||||||
|
# index_buy_crypto_orders_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (currency_id => currencies.id)
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
class BuyCryptoOrder < ApplicationRecord
|
||||||
|
include Processable
|
||||||
|
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :currency
|
||||||
|
|
||||||
|
monetize :paid_amount_cents
|
||||||
|
|
||||||
|
validates :paid_amount_cents, presence: true, numericality: { greater_than: 0 }
|
||||||
|
validates :received_amount, presence: true, if: :completed?
|
||||||
|
end
|
||||||
21
app/models/concerns/processable.rb
Normal file
21
app/models/concerns/processable.rb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
module Processable
|
||||||
|
extend Enumerize
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
enumerize :status, in: [:processing, :completed, :canceled], default: :processing
|
||||||
|
end
|
||||||
|
|
||||||
|
def processing?
|
||||||
|
status == :processing
|
||||||
|
end
|
||||||
|
|
||||||
|
def completed?
|
||||||
|
status == :completed
|
||||||
|
end
|
||||||
|
|
||||||
|
def canceled?
|
||||||
|
status == :canceled
|
||||||
|
end
|
||||||
|
end
|
||||||
36
app/models/sell_crypto_order.rb
Normal file
36
app/models/sell_crypto_order.rb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: sell_crypto_orders
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# paid_amount :decimal(20, 10) default(0.0), not null
|
||||||
|
# received_amount_cents :integer
|
||||||
|
# status :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# currency_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_sell_crypto_orders_on_currency_id (currency_id)
|
||||||
|
# index_sell_crypto_orders_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (currency_id => currencies.id)
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
class SellCryptoOrder < ApplicationRecord
|
||||||
|
include Processable
|
||||||
|
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :currency
|
||||||
|
|
||||||
|
monetize :received_amount_cents
|
||||||
|
|
||||||
|
validates :paid_amount, presence: true, numericality: { greater_than: 0 }
|
||||||
|
validates :received_amount_cents, presence: true, if: :completed?
|
||||||
|
end
|
||||||
15
db/migrate/20210814194443_create_buy_crypto_orders.rb
Normal file
15
db/migrate/20210814194443_create_buy_crypto_orders.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
class CreateBuyCryptoOrders < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
create_table(:buy_crypto_orders) do |t|
|
||||||
|
t.references(:user, null: false, foreign_key: true)
|
||||||
|
t.references(:currency, null: false, foreign_key: true)
|
||||||
|
|
||||||
|
t.string(:status, null: false)
|
||||||
|
t.integer(:paid_amount_cents, null: false, default: 0)
|
||||||
|
t.decimal(:received_amount, precision: 20, scale: 10, null: true)
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
15
db/migrate/20210814194513_create_sell_crypto_orders.rb
Normal file
15
db/migrate/20210814194513_create_sell_crypto_orders.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
class CreateSellCryptoOrders < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
create_table(:sell_crypto_orders) do |t|
|
||||||
|
t.references(:user, null: false, foreign_key: true)
|
||||||
|
t.references(:currency, null: false, foreign_key: true)
|
||||||
|
|
||||||
|
t.string(:status, null: false)
|
||||||
|
t.decimal(:paid_amount, precision: 20, scale: 10, null: false, default: 0)
|
||||||
|
t.integer(:received_amount_cents, null: true)
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
30
db/schema.rb
generated
30
db/schema.rb
generated
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2021_08_12_011039) do
|
ActiveRecord::Schema.define(version: 2021_08_14_194513) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@@ -65,6 +65,18 @@ ActiveRecord::Schema.define(version: 2021_08_12_011039) do
|
|||||||
t.index ["user_id"], name: "index_balances_on_user_id"
|
t.index ["user_id"], name: "index_balances_on_user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "buy_crypto_orders", force: :cascade do |t|
|
||||||
|
t.bigint "user_id", null: false
|
||||||
|
t.bigint "currency_id", null: false
|
||||||
|
t.string "status", null: false
|
||||||
|
t.integer "paid_amount_cents", default: 0, null: false
|
||||||
|
t.decimal "received_amount", precision: 20, scale: 10
|
||||||
|
t.datetime "created_at", precision: 6, null: false
|
||||||
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.index ["currency_id"], name: "index_buy_crypto_orders_on_currency_id"
|
||||||
|
t.index ["user_id"], name: "index_buy_crypto_orders_on_user_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "currencies", force: :cascade do |t|
|
create_table "currencies", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.datetime "created_at", precision: 6, null: false
|
t.datetime "created_at", precision: 6, null: false
|
||||||
@@ -80,6 +92,18 @@ ActiveRecord::Schema.define(version: 2021_08_12_011039) do
|
|||||||
t.index ["user_id"], name: "index_fiat_balances_on_user_id"
|
t.index ["user_id"], name: "index_fiat_balances_on_user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "sell_crypto_orders", force: :cascade do |t|
|
||||||
|
t.bigint "user_id", null: false
|
||||||
|
t.bigint "currency_id", null: false
|
||||||
|
t.string "status", null: false
|
||||||
|
t.decimal "paid_amount", precision: 20, scale: 10, default: "0.0", null: false
|
||||||
|
t.integer "received_amount_cents"
|
||||||
|
t.datetime "created_at", precision: 6, null: false
|
||||||
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.index ["currency_id"], name: "index_sell_crypto_orders_on_currency_id"
|
||||||
|
t.index ["user_id"], name: "index_sell_crypto_orders_on_user_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "user_documents", force: :cascade do |t|
|
create_table "user_documents", force: :cascade do |t|
|
||||||
t.string "status", null: false
|
t.string "status", null: false
|
||||||
t.bigint "user_id", null: false
|
t.bigint "user_id", null: false
|
||||||
@@ -106,6 +130,10 @@ ActiveRecord::Schema.define(version: 2021_08_12_011039) do
|
|||||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "balances", "currencies"
|
add_foreign_key "balances", "currencies"
|
||||||
add_foreign_key "balances", "users"
|
add_foreign_key "balances", "users"
|
||||||
|
add_foreign_key "buy_crypto_orders", "currencies"
|
||||||
|
add_foreign_key "buy_crypto_orders", "users"
|
||||||
add_foreign_key "fiat_balances", "users"
|
add_foreign_key "fiat_balances", "users"
|
||||||
|
add_foreign_key "sell_crypto_orders", "currencies"
|
||||||
|
add_foreign_key "sell_crypto_orders", "users"
|
||||||
add_foreign_key "user_documents", "users"
|
add_foreign_key "user_documents", "users"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ currency = Currency.create!(name: "CAKE")
|
|||||||
Balance.create!(
|
Balance.create!(
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
currency_id: currency.id,
|
currency_id: currency.id,
|
||||||
amount: (rand * (10000 - 0) + 0)
|
amount: rand * 10000
|
||||||
)
|
)
|
||||||
|
|
||||||
FiatBalance.create!(user_id: user.id, amount_cents: 15000)
|
FiatBalance.create!(user_id: user.id, amount_cents: 15000)
|
||||||
|
|||||||
151
erd.svg
151
erd.svg
@@ -4,12 +4,12 @@
|
|||||||
<!-- Generated by graphviz version 2.48.0 (0)
|
<!-- Generated by graphviz version 2.48.0 (0)
|
||||||
-->
|
-->
|
||||||
<!-- Title: XStake Pages: 1 -->
|
<!-- Title: XStake Pages: 1 -->
|
||||||
<svg width="400pt" height="415pt"
|
<svg width="426pt" height="606pt"
|
||||||
viewBox="0.00 0.00 399.60 414.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
viewBox="0.00 0.00 425.60 605.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 385.8)">
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 576.8)">
|
||||||
<title>XStake</title>
|
<title>XStake</title>
|
||||||
<polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-385.8 370.8,-385.8 370.8,28.8 -28.8,28.8"/>
|
<polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-576.8 396.8,-576.8 396.8,28.8 -28.8,28.8"/>
|
||||||
<text text-anchor="middle" x="171" y="-342.6" font-family="Arial Bold" font-size="13.00">XStake domain model</text>
|
<text text-anchor="middle" x="184" y="-533.6" font-family="Arial Bold" font-size="13.00">XStake domain model</text>
|
||||||
<!-- m_AdminUser -->
|
<!-- m_AdminUser -->
|
||||||
<g id="node1" class="node">
|
<g id="node1" class="node">
|
||||||
<title>m_AdminUser</title>
|
<title>m_AdminUser</title>
|
||||||
@@ -30,46 +30,92 @@
|
|||||||
<!-- m_Balance -->
|
<!-- m_Balance -->
|
||||||
<g id="node2" class="node">
|
<g id="node2" class="node">
|
||||||
<title>m_Balance</title>
|
<title>m_Balance</title>
|
||||||
<path fill="none" stroke="black" d="M210,-250.5C210,-250.5 330,-250.5 330,-250.5 336,-250.5 342,-256.5 342,-262.5 342,-262.5 342,-307.5 342,-307.5 342,-313.5 336,-319.5 330,-319.5 330,-319.5 210,-319.5 210,-319.5 204,-319.5 198,-313.5 198,-307.5 198,-307.5 198,-262.5 198,-262.5 198,-256.5 204,-250.5 210,-250.5"/>
|
<path fill="none" stroke="black" d="M223,-441.5C223,-441.5 343,-441.5 343,-441.5 349,-441.5 355,-447.5 355,-453.5 355,-453.5 355,-498.5 355,-498.5 355,-504.5 349,-510.5 343,-510.5 343,-510.5 223,-510.5 223,-510.5 217,-510.5 211,-504.5 211,-498.5 211,-498.5 211,-453.5 211,-453.5 211,-447.5 217,-441.5 223,-441.5"/>
|
||||||
<text text-anchor="start" x="246.5" y="-306.7" font-family="Arial Bold" font-size="11.00">Balance</text>
|
<text text-anchor="start" x="259.5" y="-497.7" font-family="Arial Bold" font-size="11.00">Balance</text>
|
||||||
<polyline fill="none" stroke="black" points="198,-299.5 342,-299.5 "/>
|
<polyline fill="none" stroke="black" points="211,-490.5 355,-490.5 "/>
|
||||||
<text text-anchor="start" x="205" y="-286" font-family="Arial" font-size="10.00">amount </text>
|
<text text-anchor="start" x="218" y="-477" font-family="Arial" font-size="10.00">amount </text>
|
||||||
<text text-anchor="start" x="241" y="-286" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10) ∗</text>
|
<text text-anchor="start" x="254" y="-477" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10) ∗</text>
|
||||||
<text text-anchor="start" x="205" y="-273" font-family="Arial" font-size="10.00">currency_id </text>
|
<text text-anchor="start" x="218" y="-464" font-family="Arial" font-size="10.00">currency_id </text>
|
||||||
<text text-anchor="start" x="259" y="-273" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
<text text-anchor="start" x="272" y="-464" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
<text text-anchor="start" x="205" y="-260" font-family="Arial" font-size="10.00">user_id </text>
|
<text text-anchor="start" x="218" y="-451" font-family="Arial" font-size="10.00">user_id </text>
|
||||||
<text text-anchor="start" x="240" y="-260" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
<text text-anchor="start" x="253" y="-451" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
|
</g>
|
||||||
|
<!-- m_BuyCryptoOrder -->
|
||||||
|
<g id="node3" class="node">
|
||||||
|
<title>m_BuyCryptoOrder</title>
|
||||||
|
<path fill="none" stroke="black" d="M210,-316.5C210,-316.5 356,-316.5 356,-316.5 362,-316.5 368,-322.5 368,-328.5 368,-328.5 368,-399.5 368,-399.5 368,-405.5 362,-411.5 356,-411.5 356,-411.5 210,-411.5 210,-411.5 204,-411.5 198,-405.5 198,-399.5 198,-399.5 198,-328.5 198,-328.5 198,-322.5 204,-316.5 210,-316.5"/>
|
||||||
|
<text text-anchor="start" x="237" y="-398.7" font-family="Arial Bold" font-size="11.00">BuyCryptoOrder</text>
|
||||||
|
<polyline fill="none" stroke="black" points="198,-391.5 368,-391.5 "/>
|
||||||
|
<text text-anchor="start" x="205" y="-378" font-family="Arial" font-size="10.00">currency_id </text>
|
||||||
|
<text text-anchor="start" x="259" y="-378" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
|
<text text-anchor="start" x="205" y="-365" font-family="Arial" font-size="10.00">paid_amount_cents </text>
|
||||||
|
<text text-anchor="start" x="293" y="-365" font-family="Arial Italic" font-size="10.00" fill="#999999">integer ∗</text>
|
||||||
|
<text text-anchor="start" x="205" y="-352" font-family="Arial" font-size="10.00">received_amount </text>
|
||||||
|
<text text-anchor="start" x="283" y="-352" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10) ∗</text>
|
||||||
|
<text text-anchor="start" x="205" y="-339" font-family="Arial" font-size="10.00">status </text>
|
||||||
|
<text text-anchor="start" x="236" y="-339" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
||||||
|
<text text-anchor="start" x="205" y="-326" font-family="Arial" font-size="10.00">user_id </text>
|
||||||
|
<text text-anchor="start" x="240" y="-326" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_Currency -->
|
<!-- m_Currency -->
|
||||||
<g id="node3" class="node">
|
<g id="node4" class="node">
|
||||||
<title>m_Currency</title>
|
<title>m_Currency</title>
|
||||||
<path fill="none" stroke="black" d="M21,-276.5C21,-276.5 141,-276.5 141,-276.5 147,-276.5 153,-282.5 153,-288.5 153,-288.5 153,-307.5 153,-307.5 153,-313.5 147,-319.5 141,-319.5 141,-319.5 21,-319.5 21,-319.5 15,-319.5 9,-313.5 9,-307.5 9,-307.5 9,-288.5 9,-288.5 9,-282.5 15,-276.5 21,-276.5"/>
|
<path fill="none" stroke="black" d="M21,-342.5C21,-342.5 141,-342.5 141,-342.5 147,-342.5 153,-348.5 153,-354.5 153,-354.5 153,-373.5 153,-373.5 153,-379.5 147,-385.5 141,-385.5 141,-385.5 21,-385.5 21,-385.5 15,-385.5 9,-379.5 9,-373.5 9,-373.5 9,-354.5 9,-354.5 9,-348.5 15,-342.5 21,-342.5"/>
|
||||||
<text text-anchor="start" x="54.5" y="-306.7" font-family="Arial Bold" font-size="11.00">Currency</text>
|
<text text-anchor="start" x="54.5" y="-372.7" font-family="Arial Bold" font-size="11.00">Currency</text>
|
||||||
<polyline fill="none" stroke="black" points="9,-299.5 153,-299.5 "/>
|
<polyline fill="none" stroke="black" points="9,-365.5 153,-365.5 "/>
|
||||||
<text text-anchor="start" x="16" y="-286" font-family="Arial" font-size="10.00">name </text>
|
<text text-anchor="start" x="16" y="-352" font-family="Arial" font-size="10.00">name </text>
|
||||||
<text text-anchor="start" x="44" y="-286" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
<text text-anchor="start" x="44" y="-352" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_Currency->m_Balance -->
|
<!-- m_Currency->m_Balance -->
|
||||||
<g id="edge4" class="edge">
|
<g id="edge8" class="edge">
|
||||||
<title>m_Currency->m_Balance</title>
|
<title>m_Currency->m_Balance</title>
|
||||||
<path fill="none" stroke="black" d="M153.23,-293.05C164.91,-292.24 177.08,-291.39 188.96,-290.56"/>
|
<path fill="none" stroke="black" d="M120.56,-385.59C146.51,-400.12 181.46,-419.7 212.21,-436.92"/>
|
||||||
<polygon fill="black" stroke="black" points="189.21,-293.7 197.97,-289.94 188.77,-287.42 189.21,-293.7"/>
|
<polygon fill="black" stroke="black" points="210.95,-439.82 220.34,-441.47 214.03,-434.33 210.95,-439.82"/>
|
||||||
|
</g>
|
||||||
|
<!-- m_Currency->m_BuyCryptoOrder -->
|
||||||
|
<g id="edge5" class="edge">
|
||||||
|
<title>m_Currency->m_BuyCryptoOrder</title>
|
||||||
|
<path fill="none" stroke="black" d="M153.08,-364C164.62,-364 176.72,-364 188.7,-364"/>
|
||||||
|
<polygon fill="black" stroke="black" points="188.82,-367.15 197.82,-364 188.82,-360.85 188.82,-367.15"/>
|
||||||
|
</g>
|
||||||
|
<!-- m_SellCryptoOrder -->
|
||||||
|
<g id="node6" class="node">
|
||||||
|
<title>m_SellCryptoOrder</title>
|
||||||
|
<path fill="none" stroke="black" d="M214.5,-191.5C214.5,-191.5 351.5,-191.5 351.5,-191.5 357.5,-191.5 363.5,-197.5 363.5,-203.5 363.5,-203.5 363.5,-274.5 363.5,-274.5 363.5,-280.5 357.5,-286.5 351.5,-286.5 351.5,-286.5 214.5,-286.5 214.5,-286.5 208.5,-286.5 202.5,-280.5 202.5,-274.5 202.5,-274.5 202.5,-203.5 202.5,-203.5 202.5,-197.5 208.5,-191.5 214.5,-191.5"/>
|
||||||
|
<text text-anchor="start" x="238" y="-273.7" font-family="Arial Bold" font-size="11.00">SellCryptoOrder</text>
|
||||||
|
<polyline fill="none" stroke="black" points="202.5,-266.5 363.5,-266.5 "/>
|
||||||
|
<text text-anchor="start" x="210" y="-253" font-family="Arial" font-size="10.00">currency_id </text>
|
||||||
|
<text text-anchor="start" x="264" y="-253" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
|
<text text-anchor="start" x="210" y="-240" font-family="Arial" font-size="10.00">paid_amount </text>
|
||||||
|
<text text-anchor="start" x="269" y="-240" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10) ∗</text>
|
||||||
|
<text text-anchor="start" x="210" y="-227" font-family="Arial" font-size="10.00">received_amount_cents </text>
|
||||||
|
<text text-anchor="start" x="317" y="-227" font-family="Arial Italic" font-size="10.00" fill="#999999">integer ∗</text>
|
||||||
|
<text text-anchor="start" x="210" y="-214" font-family="Arial" font-size="10.00">status </text>
|
||||||
|
<text text-anchor="start" x="241" y="-214" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
||||||
|
<text text-anchor="start" x="210" y="-201" font-family="Arial" font-size="10.00">user_id </text>
|
||||||
|
<text text-anchor="start" x="245" y="-201" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
|
</g>
|
||||||
|
<!-- m_Currency->m_SellCryptoOrder -->
|
||||||
|
<g id="edge7" class="edge">
|
||||||
|
<title>m_Currency->m_SellCryptoOrder</title>
|
||||||
|
<path fill="none" stroke="black" d="M116.84,-342.23C139.24,-328.22 169.37,-309.39 197.77,-291.65"/>
|
||||||
|
<polygon fill="black" stroke="black" points="199.76,-294.12 205.72,-286.68 196.42,-288.77 199.76,-294.12"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_FiatBalance -->
|
<!-- m_FiatBalance -->
|
||||||
<g id="node4" class="node">
|
<g id="node5" class="node">
|
||||||
<title>m_FiatBalance</title>
|
<title>m_FiatBalance</title>
|
||||||
<path fill="none" stroke="black" d="M210,-151.5C210,-151.5 330,-151.5 330,-151.5 336,-151.5 342,-157.5 342,-163.5 342,-163.5 342,-208.5 342,-208.5 342,-214.5 336,-220.5 330,-220.5 330,-220.5 210,-220.5 210,-220.5 204,-220.5 198,-214.5 198,-208.5 198,-208.5 198,-163.5 198,-163.5 198,-157.5 204,-151.5 210,-151.5"/>
|
<path fill="none" stroke="black" d="M223,-6.5C223,-6.5 343,-6.5 343,-6.5 349,-6.5 355,-12.5 355,-18.5 355,-18.5 355,-63.5 355,-63.5 355,-69.5 349,-75.5 343,-75.5 343,-75.5 223,-75.5 223,-75.5 217,-75.5 211,-69.5 211,-63.5 211,-63.5 211,-18.5 211,-18.5 211,-12.5 217,-6.5 223,-6.5"/>
|
||||||
<text text-anchor="start" x="237" y="-207.7" font-family="Arial Bold" font-size="11.00">FiatBalance</text>
|
<text text-anchor="start" x="250" y="-62.7" font-family="Arial Bold" font-size="11.00">FiatBalance</text>
|
||||||
<polyline fill="none" stroke="black" points="198,-200.5 342,-200.5 "/>
|
<polyline fill="none" stroke="black" points="211,-55.5 355,-55.5 "/>
|
||||||
<text text-anchor="start" x="205" y="-187" font-family="Arial" font-size="10.00">amount_cents </text>
|
<text text-anchor="start" x="218" y="-42" font-family="Arial" font-size="10.00">amount_cents </text>
|
||||||
<text text-anchor="start" x="270" y="-187" font-family="Arial Italic" font-size="10.00" fill="#999999">integer ∗</text>
|
<text text-anchor="start" x="283" y="-42" font-family="Arial Italic" font-size="10.00" fill="#999999">integer ∗</text>
|
||||||
<text text-anchor="start" x="205" y="-174" font-family="Arial" font-size="10.00">amount_currency </text>
|
<text text-anchor="start" x="218" y="-29" font-family="Arial" font-size="10.00">amount_currency </text>
|
||||||
<text text-anchor="start" x="284" y="-174" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
<text text-anchor="start" x="297" y="-29" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
||||||
<text text-anchor="start" x="205" y="-161" font-family="Arial" font-size="10.00">user_id </text>
|
<text text-anchor="start" x="218" y="-16" font-family="Arial" font-size="10.00">user_id </text>
|
||||||
<text text-anchor="start" x="240" y="-161" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
<text text-anchor="start" x="253" y="-16" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_User -->
|
<!-- m_User -->
|
||||||
<g id="node5" class="node">
|
<g id="node7" class="node">
|
||||||
<title>m_User</title>
|
<title>m_User</title>
|
||||||
<path fill="none" stroke="black" d="M12,-125.5C12,-125.5 150,-125.5 150,-125.5 156,-125.5 162,-131.5 162,-137.5 162,-137.5 162,-234.5 162,-234.5 162,-240.5 156,-246.5 150,-246.5 150,-246.5 12,-246.5 12,-246.5 6,-246.5 0,-240.5 0,-234.5 0,-234.5 0,-137.5 0,-137.5 0,-131.5 6,-125.5 12,-125.5"/>
|
<path fill="none" stroke="black" d="M12,-125.5C12,-125.5 150,-125.5 150,-125.5 156,-125.5 162,-131.5 162,-137.5 162,-137.5 162,-234.5 162,-234.5 162,-240.5 156,-246.5 150,-246.5 150,-246.5 12,-246.5 12,-246.5 6,-246.5 0,-240.5 0,-234.5 0,-234.5 0,-137.5 0,-137.5 0,-131.5 6,-125.5 12,-125.5"/>
|
||||||
<text text-anchor="start" x="66.5" y="-233.7" font-family="Arial Bold" font-size="11.00">User</text>
|
<text text-anchor="start" x="66.5" y="-233.7" font-family="Arial Bold" font-size="11.00">User</text>
|
||||||
@@ -92,30 +138,41 @@
|
|||||||
<!-- m_User->m_Balance -->
|
<!-- m_User->m_Balance -->
|
||||||
<g id="edge2" class="edge">
|
<g id="edge2" class="edge">
|
||||||
<title>m_User->m_Balance</title>
|
<title>m_User->m_Balance</title>
|
||||||
<path fill="none" stroke="black" d="M162.12,-228.42C173.29,-234.33 184.71,-240.38 195.75,-246.22"/>
|
<path fill="none" stroke="black" d="M119.1,-246.71C133.45,-271.44 149.41,-300.62 162,-328 181.56,-370.54 167.99,-391.06 198,-427 202.33,-432.18 207.36,-436.94 212.76,-441.29"/>
|
||||||
<polygon fill="black" stroke="black" points="194.27,-249 203.7,-250.43 197.22,-243.44 194.27,-249"/>
|
</g>
|
||||||
|
<!-- m_User->m_BuyCryptoOrder -->
|
||||||
|
<g id="edge4" class="edge">
|
||||||
|
<title>m_User->m_BuyCryptoOrder</title>
|
||||||
|
<path fill="none" stroke="black" d="M139.37,-246.78C157.57,-265.12 178.14,-284.91 198,-302 201.26,-304.81 204.64,-307.63 208.09,-310.44"/>
|
||||||
|
<polygon fill="black" stroke="black" points="206.25,-313 215.25,-316.17 210.19,-308.08 206.25,-313"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_User->m_FiatBalance -->
|
<!-- m_User->m_FiatBalance -->
|
||||||
<g id="edge3" class="edge">
|
<g id="edge3" class="edge">
|
||||||
<title>m_User->m_FiatBalance</title>
|
<title>m_User->m_FiatBalance</title>
|
||||||
<path fill="none" stroke="black" d="M162.12,-186C174.01,-186 186.21,-186 197.9,-186"/>
|
<path fill="none" stroke="black" d="M151.41,-125.47C166.42,-113.26 182.46,-100.85 198,-90 204.92,-85.17 212.34,-80.35 219.8,-75.73"/>
|
||||||
|
</g>
|
||||||
|
<!-- m_User->m_SellCryptoOrder -->
|
||||||
|
<g id="edge6" class="edge">
|
||||||
|
<title>m_User->m_SellCryptoOrder</title>
|
||||||
|
<path fill="none" stroke="black" d="M162.2,-207.25C172.55,-210 183.21,-212.82 193.69,-215.6"/>
|
||||||
|
<polygon fill="black" stroke="black" points="192.93,-218.66 202.44,-217.92 194.55,-212.57 192.93,-218.66"/>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_UserDocument -->
|
<!-- m_UserDocument -->
|
||||||
<g id="node6" class="node">
|
<g id="node8" class="node">
|
||||||
<title>m_UserDocument</title>
|
<title>m_UserDocument</title>
|
||||||
<path fill="none" stroke="black" d="M210,-66C210,-66 330,-66 330,-66 336,-66 342,-72 342,-78 342,-78 342,-110 342,-110 342,-116 336,-122 330,-122 330,-122 210,-122 210,-122 204,-122 198,-116 198,-110 198,-110 198,-78 198,-78 198,-72 204,-66 210,-66"/>
|
<path fill="none" stroke="black" d="M223,-105C223,-105 343,-105 343,-105 349,-105 355,-111 355,-117 355,-117 355,-149 355,-149 355,-155 349,-161 343,-161 343,-161 223,-161 223,-161 217,-161 211,-155 211,-149 211,-149 211,-117 211,-117 211,-111 217,-105 223,-105"/>
|
||||||
<text text-anchor="start" x="228.5" y="-109.2" font-family="Arial Bold" font-size="11.00">UserDocument</text>
|
<text text-anchor="start" x="241.5" y="-148.2" font-family="Arial Bold" font-size="11.00">UserDocument</text>
|
||||||
<polyline fill="none" stroke="black" points="198,-102 342,-102 "/>
|
<polyline fill="none" stroke="black" points="211,-141 355,-141 "/>
|
||||||
<text text-anchor="start" x="205" y="-89" font-family="Arial" font-size="10.00">status </text>
|
<text text-anchor="start" x="218" y="-128" font-family="Arial" font-size="10.00">status </text>
|
||||||
<text text-anchor="start" x="236" y="-89" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
<text text-anchor="start" x="249" y="-128" font-family="Arial Italic" font-size="10.00" fill="#999999">string ∗</text>
|
||||||
<text text-anchor="start" x="205" y="-76" font-family="Arial" font-size="10.00">user_id </text>
|
<text text-anchor="start" x="218" y="-115" font-family="Arial" font-size="10.00">user_id </text>
|
||||||
<text text-anchor="start" x="240" y="-76" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
<text text-anchor="start" x="253" y="-115" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) ∗ FK</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- m_User->m_UserDocument -->
|
<!-- m_User->m_UserDocument -->
|
||||||
<g id="edge1" class="edge">
|
<g id="edge1" class="edge">
|
||||||
<title>m_User->m_UserDocument</title>
|
<title>m_User->m_UserDocument</title>
|
||||||
<path fill="none" stroke="black" d="M162.12,-146.58C175.99,-139.76 190.27,-132.73 203.69,-126.13"/>
|
<path fill="none" stroke="black" d="M162.2,-164.75C175.26,-161.29 188.8,-157.7 201.87,-154.23"/>
|
||||||
<polygon fill="black" stroke="black" points="205.24,-128.88 211.92,-122.08 202.46,-123.23 205.24,-128.88"/>
|
<polygon fill="black" stroke="black" points="202.93,-157.21 210.83,-151.86 201.32,-151.12 202.93,-157.21"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 14 KiB |
34
spec/factories/buy_crypto_orders.rb
Normal file
34
spec/factories/buy_crypto_orders.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: buy_crypto_orders
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# paid_amount_cents :integer default(0), not null
|
||||||
|
# received_amount :decimal(20, 10)
|
||||||
|
# status :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# currency_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_buy_crypto_orders_on_currency_id (currency_id)
|
||||||
|
# index_buy_crypto_orders_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (currency_id => currencies.id)
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :buy_crypto_order do
|
||||||
|
association :user
|
||||||
|
association :currency
|
||||||
|
status { :processing }
|
||||||
|
paid_amount_cents { rand(10000) }
|
||||||
|
received_amount { rand * 10000 }
|
||||||
|
end
|
||||||
|
end
|
||||||
34
spec/factories/sell_crypto_orders.rb
Normal file
34
spec/factories/sell_crypto_orders.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: sell_crypto_orders
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# paid_amount :decimal(20, 10) default(0.0), not null
|
||||||
|
# received_amount_cents :integer
|
||||||
|
# status :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# currency_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_sell_crypto_orders_on_currency_id (currency_id)
|
||||||
|
# index_sell_crypto_orders_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (currency_id => currencies.id)
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :sell_crypto_order do
|
||||||
|
association :user
|
||||||
|
association :currency
|
||||||
|
status { :processing }
|
||||||
|
received_amount_cents { rand(10000) }
|
||||||
|
paid_amount { rand * 10000 }
|
||||||
|
end
|
||||||
|
end
|
||||||
56
spec/models/buy_crypto_order_spec.rb
Normal file
56
spec/models/buy_crypto_order_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: buy_crypto_orders
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# paid_amount_cents :integer default(0), not null
|
||||||
|
# received_amount :decimal(20, 10)
|
||||||
|
# status :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# currency_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_buy_crypto_orders_on_currency_id (currency_id)
|
||||||
|
# index_buy_crypto_orders_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (currency_id => currencies.id)
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe(BuyCryptoOrder, type: :model) do
|
||||||
|
describe "validations" do
|
||||||
|
context "when status is `processing`" do
|
||||||
|
subject { build(:buy_crypto_order, status: :processing) }
|
||||||
|
|
||||||
|
it { is_expected.to(validate_presence_of(:paid_amount_cents)) }
|
||||||
|
it { is_expected.not_to(validate_presence_of(:received_amount)) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when status is `completed`" do
|
||||||
|
subject { build(:buy_crypto_order, status: :completed) }
|
||||||
|
|
||||||
|
it { is_expected.to(validate_presence_of(:paid_amount_cents)) }
|
||||||
|
it { is_expected.to(validate_presence_of(:received_amount)) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when status is `canceled`" do
|
||||||
|
subject { build(:buy_crypto_order, status: :canceled) }
|
||||||
|
|
||||||
|
it { is_expected.to(validate_presence_of(:paid_amount_cents)) }
|
||||||
|
it { is_expected.not_to(validate_presence_of(:received_amount)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "associations" do
|
||||||
|
it { is_expected.to(belong_to(:user)) }
|
||||||
|
it { is_expected.to(belong_to(:currency)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
56
spec/models/sell_crypto_order_spec.rb
Normal file
56
spec/models/sell_crypto_order_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: sell_crypto_orders
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# paid_amount :decimal(20, 10) default(0.0), not null
|
||||||
|
# received_amount_cents :integer
|
||||||
|
# status :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# currency_id :bigint not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_sell_crypto_orders_on_currency_id (currency_id)
|
||||||
|
# index_sell_crypto_orders_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (currency_id => currencies.id)
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe(SellCryptoOrder, type: :model) do
|
||||||
|
describe "validations" do
|
||||||
|
context "when status is `processing`" do
|
||||||
|
subject { build(:sell_crypto_order, status: :processing) }
|
||||||
|
|
||||||
|
it { is_expected.to(validate_presence_of(:paid_amount)) }
|
||||||
|
it { is_expected.not_to(validate_presence_of(:received_amount_cents)) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when status is `completed`" do
|
||||||
|
subject { build(:sell_crypto_order, status: :completed) }
|
||||||
|
|
||||||
|
it { is_expected.to(validate_presence_of(:paid_amount)) }
|
||||||
|
it { is_expected.to(validate_presence_of(:received_amount_cents)) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when status is `canceled`" do
|
||||||
|
subject { build(:sell_crypto_order, status: :canceled) }
|
||||||
|
|
||||||
|
it { is_expected.to(validate_presence_of(:paid_amount)) }
|
||||||
|
it { is_expected.not_to(validate_presence_of(:received_amount_cents)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "associations" do
|
||||||
|
it { is_expected.to(belong_to(:user)) }
|
||||||
|
it { is_expected.to(belong_to(:currency)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user