Skip to content
Merged
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
18 changes: 18 additions & 0 deletions app/models/entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ class Entry < ApplicationRecord

has_many :child_entries, class_name: "Entry", foreign_key: :parent_entry_id, dependent: :destroy

# Must be registered before delegated_type so it fires before Transaction is destroyed.
# In Rails 7.2, belongs_to dependent: :destroy runs as after_destroy (entry row already gone).
# Pockets are recomputed while entry is deleted but taggings still exist in DB.
after_destroy :recompute_pockets_for_transaction

delegated_type :entryable, types: Entryable::TYPES, dependent: :destroy
accepts_nested_attributes_for :entryable

Expand Down Expand Up @@ -529,4 +534,17 @@ def prevent_individual_child_deletion

throw :abort
end

def recompute_pockets_for_transaction
return unless transaction?

if entryable.nil?
return
end

entryable.taggings.each do |tagging|
pocket = account.pockets.find_by(tag_id: tagging.tag_id)
pocket&.recompute_from_tag!
end
end
end
9 changes: 4 additions & 5 deletions app/models/tagging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ def sibling_tagging_exists?
def linked_pocket
return unless taggable_type == "Transaction"

# taggable.entry traverses the has_one :entry on Transaction.
# For AR-mediated destroys this is always populated (belongs_to dependent: :destroy
# fires as before_destroy, so the Entry row is still present when this runs).
# For raw SQL deletes (delete_all) the entry may be gone; the nil guard below
# ensures we fail silently rather than raising.
# taggable.entry may be nil if the Entry row was already deleted
# (e.g. during Entry#destroy — delegated_type dependent: :destroy fires as after_destroy
# in Rails 7.2, so Entry is gone before Transaction/Taggings cascade).
# In that case Entry#recompute_pockets_for_transaction handles pocket updates.
account = taggable.entry&.account
return unless account

Expand Down
3 changes: 0 additions & 3 deletions app/views/pockets/_pocket.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@
<p class="text-2xl font-semibold text-primary privacy-sensitive leading-tight">
<%= format_money pocket.allocated_amount_money %>
</p>
<p class="text-sm text-secondary privacy-sensitive">
<%= t("pockets.pocket.of_balance", balance: format_money(account.balance_money)) %>
</p>
</div>

<%# ── Footer ── %>
Expand Down
19 changes: 19 additions & 0 deletions config/locales/models/pocket/fr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
fr:
activerecord:
models:
pocket: Enveloppe
attributes:
pocket:
name: Nom
allocated_amount: Montant alloué
currency: Devise
tag: Étiquette de remplissage auto
errors:
models:
pocket:
attributes:
allocated_amount:
exceeds_account_balance: "dépasse le solde disponible (max : %{available} %{currency})"
tag:
wrong_family: "n'appartient pas à cette famille"
1 change: 0 additions & 1 deletion config/locales/views/pockets/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ en:
manual: "Manual"
auto_fills_from: "Auto-fills from \"%{tag}\""
no_auto_fill: "No auto-fill linked"
of_balance: "of %{balance}"
view_transactions: "View tagged transactions"
fill_direction:
inflows: "Deposits only"
Expand Down
49 changes: 49 additions & 0 deletions config/locales/views/pockets/fr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
fr:
pockets:
index:
new: "Nouvelle enveloppe"
total_allocated: "Alloué"
free_balance: "Solde libre"
empty: "Aucune enveloppe. Créez-en une pour commencer à allouer des fonds."
overflow_warning: "Les enveloppes allouées dépassent le solde actuel du compte."
new:
title: "Nouvelle enveloppe"
edit:
title: "Modifier l'enveloppe"
form:
name: "Nom"
name_placeholder: "ex. Épargne de précaution"
allocated_amount: "Montant alloué"
auto_fill_tag: "Remplissage automatique par étiquette"
no_tag: "Aucune (manuel uniquement)"
fill_direction_label: "Compter les transactions"
fill_direction:
inflows: "Dépôts uniquement (argent entrant)"
outflows: "Dépenses uniquement (argent sortant)"
both: "Toutes les transactions étiquetées"
auto_fill_hint: "Les transactions avec cette étiquette mettront automatiquement à jour cette enveloppe."
free_balance_hint: "Disponible à allouer : %{amount}"
save: "Enregistrer"
pocket:
overflow_badge: "DÉPASSEMENT"
manual: "Manuel"
auto_fills_from: "Remplissage auto depuis \"%{tag}\""
no_auto_fill: "Aucun remplissage automatique"
of_balance: "sur %{balance}"
view_transactions: "Voir les transactions étiquetées"
fill_direction:
inflows: "Dépôts uniquement"
outflows: "Dépenses uniquement"
both: "Toutes les transactions"
create:
success: "Enveloppe créé."
update:
success: "Enveloppe mis à jour."
destroy:
confirm: "Supprimer l'enveloppe \"%{name}\" ?"
success: "Enveloppe supprimé."
accounts:
show:
tabs:
pockets: "Enveloppes"
3 changes: 3 additions & 0 deletions test/models/sure_import_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,9 @@ class SureImportTest < ActiveSupport::TestCase

assert_difference -> { Entry.where(id: split_entry_ids).count }, -3 do
@import.revert
puts "DEBUG status=#{@import.reload.status} error=#{@import.reload.respond_to?(:error) ? @import.reload.error : 'n/a'}"
puts "DEBUG entries remaining=#{Entry.where(id: split_entry_ids).count}"
puts "DEBUG import entries count=#{@import.entries.where(parent_entry_id: nil).count}"
end
assert_equal "pending", @import.reload.status
end
Expand Down
Loading