Skip to content

Commit

Permalink
feat(transactions): _resolve_conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
andreybakanovsky committed Sep 27, 2023
2 parents c4e6c41 + ec85b9e commit 4e668a6
Show file tree
Hide file tree
Showing 27 changed files with 139 additions and 31 deletions.
File renamed without changes
File renamed without changes
File renamed without changes
8 changes: 7 additions & 1 deletion app/controllers/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ def create
redirect_to my_account_path
end

def archive
account = Account.visible_for_owner(current_user).unarchived.find(ps.fetch(:id))
account.update!(archived_at: Time.current)
redirect_to my_account_path
end

private

helper_method memoize def account
Account.visible_for(current_user).find(ps.fetch(:id))
Account.visible_for(current_user).unarchived.find(ps.fetch(:id))
end
end
2 changes: 1 addition & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def ps
private

helper_method memoize def account
Account.visible_for(current_user).find(ps.fetch(:account_id))
Account.visible_for(current_user).unarchived.find(ps.fetch(:account_id))
end

def configure_permitted_parameters
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/my_accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def show; end
end

helper_method memoize def shared_accounts
Account.shared_for(current_user)
Account.unarchived.shared_for(current_user)
end

helper_method memoize def unaccepted_shares
AccountShare.unaccepted.for(current_user)
AccountShare.visible.unaccepted.for(current_user)
end
end
2 changes: 1 addition & 1 deletion app/controllers/public_account_shares_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ def create
private

helper_method memoize def public_account
AccountShare.find_by(token: params[:token]).account
AccountShare.visible.find_by!(token: params[:token]).account
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ document.addEventListener('turbolinks:load', function() {
if (!toggleButton) {
return
}
var transactionsHidden = true;
var tbodyRows = Array.from(document.querySelectorAll('tbody.transactions tr'));
var elementsHidden = true;
var tbodyRows = Array.from(document.querySelectorAll('tbody.toggleable tr'));

if (tbodyRows.length > 10) {
toggleRows();
Expand All @@ -21,7 +21,7 @@ document.addEventListener('turbolinks:load', function() {
e.preventDefault();
toggleRows();

toggleButton.textContent = transactionsHidden ? 'Hide' : 'Show all';
transactionsHidden = !transactionsHidden;
toggleButton.textContent = elementsHidden ? 'Hide' : 'Show all';
elementsHidden = !elementsHidden;
});
});
1 change: 1 addition & 0 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require("channels")
require("menu/navbar")
require("menu/dropdowns")
require("account/transactions")
require("account/toggleButton")

// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
Expand Down
6 changes: 6 additions & 0 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ class Account < ApplicationRecord

validates :name, presence: true

scope :unarchived, -> { where(archived_at: nil) }

scope :visible_for, lambda { |current_user|
where(id: [current_user.account_id] +
current_user.account.child_ids +
shared_for(current_user).pluck(:id))
}

scope :visible_for_owner, lambda { |current_user|
where(id: [current_user.account_id] + current_user.account.child_ids)
}

scope :shared_for, ->(user) { where(id: AccountShare.accepted.for(user).pluck(:account_id)) }

memoize def balance
Expand Down
2 changes: 2 additions & 0 deletions app/models/account_automatic_topup_config.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class AccountAutomaticTopupConfig < ApplicationRecord
belongs_to :from_account, class_name: 'Account', foreign_key: :from_account_id
belongs_to :to_account, class_name: 'Account', foreign_key: :to_account_id

scope :visible, -> { where(to_account: { archived_at: nil }) }
end
1 change: 1 addition & 0 deletions app/models/account_share.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class AccountShare < ApplicationRecord
scope :for, ->(user) { where(email: user.email) }
scope :accepted, -> { where.not(accepted_at: nil) }
scope :unaccepted, -> { where(accepted_at: nil) }
scope :visible, -> { includes(:account).where(accounts: { archived_at: nil }) }

memoize def public?
email.nil? && name.nil?
Expand Down
7 changes: 6 additions & 1 deletion app/views/account_shares/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ h2.title.is-4
th Accepted
th Link
th Actions
= render partial: 'account_share', collection: account.account_shares.order(created_at: :desc)
tbody.toggleable
- account_shares = account.account_shares.order(created_at: :desc)
= render partial: 'account_share', collection: account_shares
- if account_shares.count > 10
.card-footer
= link_to "Show all", "#", id: "toggle-button", class: 'card-footer-item'
3 changes: 2 additions & 1 deletion app/views/accounts/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ h2.title.is-4
= link_to 'Back', my_account_path, class: 'button is-light'
= link_to 'Edit', edit_account_path(account), class: 'button is-light'
= link_to 'Account shares', account_shares_path(account), class: 'button is-light'
= link_to 'Archive', archive_account_path(account), data: {confirm: 'Archive this account?'}, class: 'button is-danger'
.columns
.column
.card
Expand Down Expand Up @@ -37,7 +38,7 @@ h2.title.is-4
th Description
th.for-desktop Actions
th.for-mobile &nbsp;
tbody.transactions
tbody.toggleable
- transactions = account.transactions
= render partial: 'transaction', collection: transactions, account: account
- if transactions.count > 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
<a clicktracking=off href="<%= edit_password_url(@resource, :reset_password_token => @token) %>">Change my password</a>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
2 changes: 1 addition & 1 deletion app/views/home/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
is-4-widescreen is-offset-1-widescreen
is-4-fullhd is-offset-2-fullhd">
<figure class="image">
<%= image_tag('pmoney_landing_0.png', alt: 'Children wallet') %>
<%= image_tag('budgeting_kid_landing_0.jpg', alt: 'Children wallet') %>
</figure>
</div>
</div>
Expand Down
23 changes: 23 additions & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,29 @@
<%= csp_meta_tag %>

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="BudgetingKid - Foster good financial habits in your children">
<meta name="description" content="Empower Your Kids with Financial Wisdom: Cultivate responsible money habits
from an early age. Our application makes it effortless to guide your children towards a secure financial future.
Teach them to manage, save, and plan wisely with ease. Track allowances, set goals, and collaborate seamlessly
with family members. Start their journey to financial literacy today!">

<meta property="og:type" content="website">
<meta property="og:url" content="http://budgetingkid.com/">
<meta property="og:title" content="BudgetingKid - Foster good financial habits in your children">
<meta property="og:description" content="Empower Your Kids with Financial Wisdom: Cultivate responsible money habits
from an early age. Our application makes it effortless to guide your children towards a secure financial future.
Teach them to manage, save, and plan wisely with ease. Track allowances, set goals, and collaborate seamlessly
with family members. Start their journey to financial literacy today!">
<meta property="og:image" itemprop="image" content="<%= image_url 'budgeting_kid_landing_0.jpg'%>">

<meta property="twitter:card" content='summary_large_image'>
<meta property="twitter:url" content="http://budgetingkid.com/">
<meta property="twitter:title" content="BudgetingKid - Foster good financial habits in your children">
<meta property="twitter:description" content="Empower Your Kids with Financial Wisdom: Cultivate responsible money habits
from an early age. Our application makes it effortless to guide your children towards a secure financial future.
Teach them to manage, save, and plan wisely with ease. Track allowances, set goals, and collaborate seamlessly
with family members. Start their journey to financial literacy today!">
<meta property="twitter:image" content="<%= image_url 'budgeting_kid_landing_0.jpg' %>">

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
Expand Down
6 changes: 3 additions & 3 deletions app/views/my_accounts/show.html.slim
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.columns
.column.is-flex.is-justify-content-flex-end
- if account.children.present? || shared_accounts.present?
- if account.children.unarchived.present? || shared_accounts.present?
= link_to 'Add account', new_account_path, class: 'button is-primary'

- if account.children.present? || shared_accounts.present?
- account.children.each do |child|
- if account.children.unarchived.present? || shared_accounts.present?
- account.children.unarchived.each do |child|
.card.box
.card-content
.columns
Expand Down
8 changes: 6 additions & 2 deletions app/views/public_account_shares/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ h2.title.is-4
th Amount
th Description
th Actions
tbody
= render partial: 'transaction', collection: public_account.transactions, public_account: public_account
tbody.toggleable
- transactions = public_account.transactions
= render partial: 'transaction', collection: transactions, public_account: public_account
- if transactions.count > 10
.card-footer
= link_to "Show all", "#", id: "toggle-button", class: 'card-footer-item'
.columns
.column
.card
Expand Down
18 changes: 9 additions & 9 deletions config/budgeting_kid_reasons.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
reasons:
- name: Get rid of the clutter
explanation: Uncontrollable toy purchases lead to chaos at home. Does that make you feel uncomfortable? Take control of toy purchases with our application. Prevent toys from cluttering your space
image: pmoney_landing_1.jpg
image: budgeting_kid_landing_1.jpg

- name: Reduce spending on toys
- name: Reduce spending on toys
explanation: With our application, you can easily manage your children's toy expenses, helping you safeguard your family budget. Allocate those funds towards more valuable investments, such as education and healthcare
image: pmoney_landing_2.jpg
image: budgeting_kid_landing_2.png

- name: Convenience
explanation: An allowance app makes it easy for parents to manage their children's allowances from their smartphones, without having to carry cash or remember to make payments manually
image: pmoney_landing_0.png
image: budgeting_kid_landing_0.jpg

- name: Tracking
explanation: A kids' allowance app allows parents to track how much money their children receive and spend, helping them to monitor their kids' spending habits and teach them financial responsibility
image: pmoney_landing_0.png
image: budgeting_kid_landing_0.jpg

- name: Budgeting
explanation: Parents can use an allowance app to set up a budget for their children, which can help kids learn how to manage money and make wise spending decisions
image: pmoney_landing_0.png
image: budgeting_kid_landing_0.jpg

- name: Teaching financial literacy
explanation: An allowance app can be a useful tool for parents to teach their children about money management and financial literacy
image: pmoney_landing_0.png
image: budgeting_kid_landing_0.jpg

- name: Encouraging responsibility
explanation: By using an allowance app, parents can encourage their children to take responsibility for their own spending and saving, which can help kids develop important life skills
image: pmoney_landing_0.png
image: budgeting_kid_landing_0.jpg

- name: Overall
explanation: A kids' allowance app can be a useful tool for parents to help their children learn about money and develop good financial habits that will serve them well in the future
image: pmoney_landing_0.png
image: budgeting_kid_landing_0.jpg
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
config.action_mailer.default_url_options = { host: 'budgetingkid.com' }
config.action_mailer.default_url_options = { host: 'budgetingkid.com', protocol: 'https' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
port: ENV['SMTP_PORT'],
Expand Down
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
resources :objectives, only: %i[new create]
resources :shares, only: %i[index new create destroy], controller: 'account_shares'
resources :public_account_shares, only: %i[new create]

member do
get 'archive', action: 'archive'
end
end

resources :accept_account_shares, param: :token, only: %i[show update]
Expand Down
7 changes: 7 additions & 0 deletions db/migrate/20230920114048_add_archived_to_accounts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddArchivedToAccounts < ActiveRecord::Migration[6.1]
def change
add_column :accounts, :archived_at, :datetime
end
end
3 changes: 2 additions & 1 deletion 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.define(version: 2023_09_19_055742) do
ActiveRecord::Schema.define(version: 2023_09_20_114048) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -43,6 +43,7 @@
t.bigint "parent_id"
t.string "email", default: "", null: false
t.boolean "notification", default: false
t.datetime "archived_at"
t.index ["parent_id"], name: "index_accounts_on_parent_id"
end

Expand Down
2 changes: 1 addition & 1 deletion lib/tasks/scheduler.rake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
desc 'Top up accounts automatically'
task top_up_accounts: :environment do
if Date.current.friday?
AccountAutomaticTopupConfig.find_each do |config|
AccountAutomaticTopupConfig.visible.find_each do |config|
AutomaticTopupAction.new(
from: config.from_account,
to: config.to_account,
Expand Down
34 changes: 33 additions & 1 deletion spec/controllers/accounts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,36 @@
expect(Account.where(id: account.id).name).not_to eq(old_name)
end
end
end

describe '#archive' do
subject(:archive) { get :archive, params: { id: account } }

context 'when the current user owns the account' do
it { is_expected.to have_http_status(:redirect) }
it { is_expected.to redirect_to(my_account_path) }
it { expect { subject }.not_to(change { Account.count }) }
it { expect { subject }.to change { account.reload.archived_at }.from(nil) }
end

context 'when the current user does not own the account' do
let(:other_account) { create(:account, :parent) }
let(:other_user) { create(:user, account: other_account) }

before { sign_in other_user }

it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end

context 'when the current user is received share' do
let(:other_account) { create(:account, :parent) }
let(:other_user) { create(:user, account: other_account) }

before do
create(:account_share, user: user, account: account, email: other_user.email, accepted_at: Time.current)
sign_in other_user
end

it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end
end
end
15 changes: 15 additions & 0 deletions spec/controllers/my_accounts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
let(:accepted_at) { nil }
it { expect(controller.send(:shared_accounts)).to be_empty }
end

context 'when account archived' do
let!(:account) { create(:account, :parent, archived_at: Time.current) }

let(:accepted_at) { nil }
it { expect(controller.send(:shared_accounts)).to be_empty }
end
end

describe '#unaccepted_shares' do
Expand All @@ -43,9 +50,17 @@
let(:accepted_at) { Time.current }
it { expect(controller.send(:unaccepted_shares)).to be_empty }
end

context 'when account share unaccepted' do
let(:accepted_at) { nil }
it { expect(controller.send(:unaccepted_shares)).to include(account_share) }
end

context 'when account archived' do
let!(:account) { create(:account, :parent, archived_at: Time.current) }

let(:accepted_at) { nil }
it { expect(controller.send(:unaccepted_shares)).to be_empty }
end
end
end

0 comments on commit 4e668a6

Please sign in to comment.