mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
link wallet & its transactions to invoicingprofile
This commit is contained in:
parent
4d1e936d76
commit
7ed97ef35a
@ -20,7 +20,7 @@
|
||||
- [TODO DEPLOY] `rake fablab:setup:chain_invoices_items_records`
|
||||
- [TODO DEPLOY] `rake fablab:setup:chain_invoices_records`
|
||||
- [TODO DEPLOY] `rake fablab:setup:chain_history_values_records`
|
||||
- [TODO DEPLOY] -> (only dev) yarn install
|
||||
- [TODO DEPLOY] -> (only dev) yarn install
|
||||
|
||||
## v3.1.1 2019 April 8
|
||||
|
||||
|
@ -5,7 +5,8 @@ class API::WalletController < API::ApiController
|
||||
before_action :authenticate_user!
|
||||
|
||||
def by_user
|
||||
@wallet = Wallet.find_by(user_id: params[:user_id])
|
||||
invoicing_profile = InvoicingProfile.find_by(user_id: params[:user_id])
|
||||
@wallet = Wallet.find_by(invoicing_profile_id: invoicing_profile.id)
|
||||
authorize @wallet
|
||||
render :show
|
||||
end
|
||||
@ -13,7 +14,7 @@ class API::WalletController < API::ApiController
|
||||
def transactions
|
||||
@wallet = Wallet.find(params[:id])
|
||||
authorize @wallet
|
||||
@wallet_transactions = @wallet.wallet_transactions.includes(:invoice, user: [:profile]).order(created_at: :desc)
|
||||
@wallet_transactions = @wallet.wallet_transactions.includes(:invoice, :invoicing_profile).order(created_at: :desc)
|
||||
end
|
||||
|
||||
def credit
|
||||
|
@ -6,9 +6,20 @@ class InvoicingProfile < ActiveRecord::Base
|
||||
accepts_nested_attributes_for :organization, allow_destroy: false
|
||||
has_many :invoices, dependent: :destroy
|
||||
|
||||
has_one :wallet, dependent: :destroy
|
||||
has_many :wallet_transactions, dependent: :destroy
|
||||
|
||||
after_create :create_a_wallet
|
||||
|
||||
|
||||
def full_name
|
||||
# if first_name or last_name is nil, the empty string will be used as a temporary replacement
|
||||
(first_name || '').humanize.titleize + ' ' + (last_name || '').humanize.titleize
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_a_wallet
|
||||
create_wallet
|
||||
end
|
||||
end
|
||||
|
@ -52,9 +52,6 @@ class User < ActiveRecord::Base
|
||||
has_many :tags, through: :user_tags
|
||||
accepts_nested_attributes_for :tags, allow_destroy: true
|
||||
|
||||
has_one :wallet, dependent: :destroy
|
||||
has_many :wallet_transactions, dependent: :destroy
|
||||
|
||||
has_many :exports, dependent: :destroy
|
||||
|
||||
has_many :history_values, dependent: :nullify
|
||||
@ -65,7 +62,6 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
before_create :assign_default_role
|
||||
after_create :create_a_wallet
|
||||
after_commit :create_stripe_customer, on: [:create]
|
||||
after_commit :notify_admin_when_user_is_created, on: :create
|
||||
after_update :notify_group_changed, if: :group_id_changed?
|
||||
@ -138,6 +134,14 @@ class User < ActiveRecord::Base
|
||||
invoicing_profile.invoices
|
||||
end
|
||||
|
||||
def wallet
|
||||
invoicing_profile.wallet
|
||||
end
|
||||
|
||||
def wallet_transactions
|
||||
invoicing_profile.wallet_transactions
|
||||
end
|
||||
|
||||
def generate_subscription_invoice(operator_id)
|
||||
return unless subscription
|
||||
|
||||
@ -328,10 +332,6 @@ class User < ActiveRecord::Base
|
||||
StripeWorker.perform_async(:create_stripe_customer, id)
|
||||
end
|
||||
|
||||
def create_a_wallet
|
||||
create_wallet
|
||||
end
|
||||
|
||||
def send_devise_notification(notification, *args)
|
||||
devise_mailer.send(notification, self, *args).deliver_later
|
||||
end
|
||||
|
@ -1,13 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# user's virtual wallet which can be credited by an admin
|
||||
# all subsequent user's transactions will charge the wallet, as the default payment mean, if the wallet amount > 0
|
||||
# if the wallet amount is not sufficient, a secondary payment mean will be requested (card or cash, depending on the login context)
|
||||
class Wallet < ActiveRecord::Base
|
||||
include AmountConcern
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :invoicing_profile
|
||||
has_many :wallet_transactions, dependent: :destroy
|
||||
|
||||
validates :user, presence: true
|
||||
validates :invoicing_profile, presence: true
|
||||
|
||||
def credit(amount)
|
||||
if amount.is_a?(Numeric) and amount >= 0
|
||||
if amount.is_a?(Numeric) && amount >= 0
|
||||
self.amount += amount
|
||||
return save
|
||||
end
|
||||
@ -15,10 +20,14 @@ class Wallet < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def debit(amount)
|
||||
if amount.is_a?(Numeric) and amount >= 0
|
||||
if amount.is_a?(Numeric) && amount >= 0
|
||||
self.amount -= amount
|
||||
return save
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def user
|
||||
invoicing_profile.user
|
||||
end
|
||||
end
|
||||
|
@ -1,12 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# track of all transactions payed using the given wallet
|
||||
class WalletTransaction < ActiveRecord::Base
|
||||
include AmountConcern
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :invoicing_profile
|
||||
belongs_to :wallet
|
||||
belongs_to :reservation
|
||||
belongs_to :transactable, polymorphic: true
|
||||
has_one :invoice
|
||||
|
||||
validates_inclusion_of :transaction_type, in: %w( credit debit )
|
||||
validates :user, :wallet, presence: true
|
||||
validates_inclusion_of :transaction_type, in: %w[credit debit]
|
||||
validates :invoicing_profile, :wallet, presence: true
|
||||
|
||||
def user
|
||||
invoicing_profile.user
|
||||
end
|
||||
end
|
||||
|
@ -8,7 +8,7 @@ class WalletService
|
||||
def credit(amount)
|
||||
ActiveRecord::Base.transaction do
|
||||
if @wallet.credit(amount)
|
||||
transaction = WalletTransaction.new(user: @user, wallet: @wallet, transaction_type: 'credit', amount: amount)
|
||||
transaction = WalletTransaction.new(invoicing_profile: @user.invoicing_profile, wallet: @wallet, transaction_type: 'credit', amount: amount)
|
||||
if transaction.save
|
||||
NotificationCenter.call type: 'notify_user_wallet_is_credited',
|
||||
receiver: @wallet.user,
|
||||
@ -28,10 +28,15 @@ class WalletService
|
||||
def debit(amount, transactable)
|
||||
ActiveRecord::Base.transaction do
|
||||
if @wallet.debit(amount)
|
||||
transaction = WalletTransaction.new(user: @user, wallet: @wallet, transaction_type: 'debit', amount: amount, transactable: transactable)
|
||||
if transaction.save
|
||||
return transaction
|
||||
end
|
||||
transaction = WalletTransaction.new(
|
||||
invoicing_profile: @user&.invoicing_profile,
|
||||
wallet: @wallet,
|
||||
transaction_type: 'debit',
|
||||
amount: amount,
|
||||
transactable: transactable
|
||||
)
|
||||
|
||||
return transaction if transaction.save
|
||||
end
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
|
@ -1 +1,2 @@
|
||||
json.extract! @wallet, :id, :user_id, :amount
|
||||
json.extract! @wallet, :id, :invoicing_profile_id, :amount
|
||||
json.user_id @wallet.invoicing_profile.user_id
|
||||
|
@ -1,11 +1,13 @@
|
||||
json.array!(@wallet_transactions) do |t|
|
||||
json.extract! t, :id, :transaction_type, :created_at, :amount, :transactable_type
|
||||
json.user do
|
||||
json.id t.user.id
|
||||
json.full_name t.user.profile.full_name
|
||||
json.id t.invoicing_profile.user_id
|
||||
json.full_name t.invoicing_profile.full_name
|
||||
end
|
||||
if t.invoice
|
||||
json.invoice do
|
||||
json.id t.invoice.id
|
||||
json.reference t.invoice.reference
|
||||
end
|
||||
end
|
||||
json.invoice do
|
||||
json.id t.invoice.id
|
||||
json.reference t.invoice.reference
|
||||
end if t.invoice
|
||||
end
|
||||
|
@ -0,0 +1,6 @@
|
||||
class AddInvoicingProfileToWallet < ActiveRecord::Migration
|
||||
def change
|
||||
add_reference :wallets, :invoicing_profile, index: true, foreign_key: true
|
||||
add_reference :wallet_transactions, :invoicing_profile, index: true, foreign_key: true
|
||||
end
|
||||
end
|
@ -0,0 +1,31 @@
|
||||
class MigrateWalletToInvoicingProfile < ActiveRecord::Migration
|
||||
def up
|
||||
Wallet.all.each do |w|
|
||||
user = User.find(w.user_id)
|
||||
w.update_attributes(
|
||||
invoicing_profile_id: user.invoicing_profile.id
|
||||
)
|
||||
end
|
||||
WalletTransaction.all.each do |wt|
|
||||
user = User.find(wt.user_id)
|
||||
wt.update_attributes(
|
||||
invoicing_profile_id: user.invoicing_profile.id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
Wallet.all.each do |w|
|
||||
invoicing_profile = User.find(w.invoicing_profile_id)
|
||||
w.update_attributes(
|
||||
user_id: invoicing_profile.user_id
|
||||
)
|
||||
end
|
||||
WalletTransaction.all.each do |wt|
|
||||
invoicing_profile = User.find(wt.invoicing_profile_id)
|
||||
wt.update_attributes(
|
||||
user_id: invoicing_profile.user_id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
6
db/migrate/20190603130038_remove_user_id_from_wallet.rb
Normal file
6
db/migrate/20190603130038_remove_user_id_from_wallet.rb
Normal file
@ -0,0 +1,6 @@
|
||||
class RemoveUserIdFromWallet < ActiveRecord::Migration
|
||||
def change
|
||||
remove_reference :wallets, :user, index: true, foreign_key: true
|
||||
remove_reference :wallet_transactions, :user, index: true, foreign_key: true
|
||||
end
|
||||
end
|
24
db/schema.rb
24
db/schema.rb
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20190529120814) do
|
||||
ActiveRecord::Schema.define(version: 20190603130038) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@ -860,28 +860,28 @@ ActiveRecord::Schema.define(version: 20190529120814) do
|
||||
add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id", using: :btree
|
||||
|
||||
create_table "wallet_transactions", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "wallet_id"
|
||||
t.integer "transactable_id"
|
||||
t.string "transactable_type"
|
||||
t.string "transaction_type"
|
||||
t.integer "amount"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "invoicing_profile_id"
|
||||
end
|
||||
|
||||
add_index "wallet_transactions", ["invoicing_profile_id"], name: "index_wallet_transactions_on_invoicing_profile_id", using: :btree
|
||||
add_index "wallet_transactions", ["transactable_type", "transactable_id"], name: "index_wallet_transactions_on_transactable", using: :btree
|
||||
add_index "wallet_transactions", ["user_id"], name: "index_wallet_transactions_on_user_id", using: :btree
|
||||
add_index "wallet_transactions", ["wallet_id"], name: "index_wallet_transactions_on_wallet_id", using: :btree
|
||||
|
||||
create_table "wallets", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "amount", default: 0
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "amount", default: 0
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "invoicing_profile_id"
|
||||
end
|
||||
|
||||
add_index "wallets", ["user_id"], name: "index_wallets_on_user_id", using: :btree
|
||||
add_index "wallets", ["invoicing_profile_id"], name: "index_wallets_on_invoicing_profile_id", using: :btree
|
||||
|
||||
add_foreign_key "accounting_periods", "users", column: "closed_by"
|
||||
add_foreign_key "availability_tags", "availabilities"
|
||||
@ -915,7 +915,7 @@ ActiveRecord::Schema.define(version: 20190529120814) do
|
||||
add_foreign_key "tickets", "reservations"
|
||||
add_foreign_key "user_tags", "tags"
|
||||
add_foreign_key "user_tags", "users"
|
||||
add_foreign_key "wallet_transactions", "users"
|
||||
add_foreign_key "wallet_transactions", "invoicing_profiles"
|
||||
add_foreign_key "wallet_transactions", "wallets"
|
||||
add_foreign_key "wallets", "users"
|
||||
add_foreign_key "wallets", "invoicing_profiles"
|
||||
end
|
||||
|
2
test/fixtures/wallet_transactions.yml
vendored
2
test/fixtures/wallet_transactions.yml
vendored
@ -1,7 +1,7 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
transaction1:
|
||||
user_id: 5
|
||||
invoicing_profile_id: 5
|
||||
wallet: wallet_5
|
||||
transaction_type: credit
|
||||
amount: 1000
|
||||
|
14
test/fixtures/wallets.yml
vendored
14
test/fixtures/wallets.yml
vendored
@ -1,27 +1,27 @@
|
||||
wallet_2:
|
||||
user_id: 2
|
||||
invoicing_profile_id: 2
|
||||
amount: 0
|
||||
|
||||
wallet_4:
|
||||
user_id: 4
|
||||
invoicing_profile_id: 4
|
||||
amount: 0
|
||||
|
||||
wallet_6:
|
||||
user_id: 6
|
||||
invoicing_profile_id: 6
|
||||
amount: 0
|
||||
|
||||
wallet_5:
|
||||
user_id: 5
|
||||
invoicing_profile_id: 5
|
||||
amount: 1000
|
||||
|
||||
wallet_3:
|
||||
user_id: 3
|
||||
invoicing_profile_id: 3
|
||||
amount: 0
|
||||
|
||||
wallet_1:
|
||||
user_id: 1
|
||||
invoicing_profile_id: 1
|
||||
amount: 0
|
||||
|
||||
wallet_7:
|
||||
user_id: 7
|
||||
invoicing_profile_id: 7
|
||||
amount: 0
|
||||
|
@ -25,6 +25,11 @@ class MembersTest < ActionDispatch::IntegrationTest
|
||||
first_name: 'Robert',
|
||||
birthday: '2018-02-08',
|
||||
phone: '0485232145'
|
||||
},
|
||||
invoicing_profile_attributes: {
|
||||
address_attributes: {
|
||||
address: '21 grand rue, 73110 Bourget-en-Huile'
|
||||
}
|
||||
}
|
||||
} }.to_json, default_headers
|
||||
end
|
||||
|
@ -19,7 +19,7 @@ class WalletsTest < ActionDispatch::IntegrationTest
|
||||
assert_equal 200, response.status
|
||||
assert_equal Mime::JSON, response.content_type
|
||||
wallet = json_response(response.body)
|
||||
assert_equal @vlonchamp.wallet.user_id, wallet[:user_id]
|
||||
assert_equal @vlonchamp.wallet.invoicing_profile_id, wallet[:invoicing_profile_id]
|
||||
assert_equal @vlonchamp.wallet.amount, wallet[:amount]
|
||||
end
|
||||
|
||||
@ -31,7 +31,7 @@ class WalletsTest < ActionDispatch::IntegrationTest
|
||||
assert_equal 200, response.status
|
||||
assert_equal Mime::JSON, response.content_type
|
||||
wallet = json_response(response.body)
|
||||
assert_equal @user1.wallet.user_id, wallet[:user_id]
|
||||
assert_equal @user1.wallet.invoicing_profile_id, wallet[:invoicing_profile_id]
|
||||
assert_equal @user1.wallet.amount, wallet[:amount]
|
||||
end
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
require 'test_helper'
|
||||
|
||||
class WalletTest < ActiveSupport::TestCase
|
||||
test "default amount must be zero" do
|
||||
test 'default amount must be zero' do
|
||||
w = Wallet.new
|
||||
assert w.amount == 0
|
||||
assert w.amount.zero?
|
||||
end
|
||||
|
||||
test 'should user present' do
|
||||
test 'should invoicing_profile present' do
|
||||
w = Wallet.create
|
||||
assert w.errors[:user].present?
|
||||
assert w.errors[:invoicing_profile].present?
|
||||
end
|
||||
|
||||
test 'can credit amount' do
|
||||
|
@ -4,7 +4,7 @@ class WalletTransactionTest < ActiveSupport::TestCase
|
||||
test 'transaction type must be credit or debit' do
|
||||
@jdupond = User.find_by(username: 'jdupond')
|
||||
@jdupond_wallet = @jdupond.wallet
|
||||
transaction = WalletTransaction.new amount: 5, user: @jdupond, wallet: @jdupond_wallet
|
||||
transaction = WalletTransaction.new amount: 5, invoicing_profile: @jdupond.invoicing_profile, wallet: @jdupond_wallet
|
||||
transaction.transaction_type = 'credit'
|
||||
assert transaction.valid?
|
||||
transaction.transaction_type = 'debit'
|
||||
|
Loading…
x
Reference in New Issue
Block a user