Files
sure/app/controllers/family_merchants_controller.rb
Brendon Scheiber 7411db5689 feat(i18n): add Hungarian translations for strings extracted in #1806 (#1817)
* add missing Hungarian translations for newly extracted strings

Replace hard-coded UI strings with I18n lookups across controllers, models and views (breadcrumbs, dashboard, reports, settings, transactions, balance sheet, MFA status). Update models to use translations for category defaults, account/display names, classification group and period labels; remove a few hardcoded display_name methods. Add and update numerous locale files (English and extensive Hungarian translations, plus model/view/doorkeeper entries) to provide the required keys. These changes centralize copy for localization and prepare the app for Hungarian/English UI text.

* Pluralize account type labels; tidy Crypto model

Update English locale account type labels to use plural forms for consistency (Investment(s), Properties, Vehicles, Other Assets, Credit Cards, Loans, Other Liabilities). Also remove an extra blank line in app/models/crypto.rb to tidy up formatting.

* Back to singular

* fix(i18n): separate singular and group account labels

* Update _accountable_group.html.erb

* Use I18n plural names for account types

Change Accountable#display_name to look up pluralized account type names via I18n (accounts.types_plural.<underscored_class>) with a fallback to the legacy display logic. Add legacy_display_name helper to preserve previous behavior (singular for Depository and Crypto, pluralized otherwise). Add corresponding types_plural entries in English and Hungarian locale files for various account types.

---------

Co-authored-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: sure-admin <sure-admin@splashblot.com>
2026-05-18 20:49:28 +02:00

157 lines
5.8 KiB
Ruby

class FamilyMerchantsController < ApplicationController
before_action :set_merchant, only: %i[edit update destroy]
def index
@breadcrumbs = [ [ t("breadcrumbs.home"), root_path ], [ t("breadcrumbs.merchants"), nil ] ]
# Show all merchants for this family
@family_merchants = Current.family.merchants.alphabetically
@provider_merchants = Current.family.assigned_merchants_for(Current.user).where(type: "ProviderMerchant").alphabetically
# Show recently unlinked ProviderMerchants (within last 30 days)
# Exclude merchants that are already assigned to transactions (they appear in provider_merchants)
recently_unlinked_ids = FamilyMerchantAssociation
.where(family: Current.family)
.recently_unlinked
.pluck(:merchant_id)
assigned_ids = @provider_merchants.pluck(:id)
@unlinked_merchants = ProviderMerchant.where(id: recently_unlinked_ids - assigned_ids).alphabetically
@enhanceable_count = @provider_merchants.where(website_url: [ nil, "" ]).count
@llm_available = Provider::Registry.get_provider(:openai).present?
render layout: "settings"
end
def new
@family_merchant = FamilyMerchant.new(family: Current.family)
end
def create
@family_merchant = FamilyMerchant.new(merchant_params.merge(family: Current.family))
if @family_merchant.save
respond_to do |format|
format.html { redirect_to family_merchants_path, notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.action(:redirect, family_merchants_path) }
end
else
render :new, status: :unprocessable_entity
end
end
def edit
end
def update
if @merchant.is_a?(ProviderMerchant)
if merchant_params[:name].present? && merchant_params[:name] != @merchant.name
# Name changed — convert ProviderMerchant to FamilyMerchant for this family only
@family_merchant = @merchant.convert_to_family_merchant_for(Current.family, merchant_params)
respond_to do |format|
format.html { redirect_to family_merchants_path, notice: t(".converted_success") }
format.turbo_stream { render turbo_stream: turbo_stream.action(:redirect, family_merchants_path) }
end
else
# Only website changed — update the ProviderMerchant directly
@merchant.update!(merchant_params.slice(:website_url))
@merchant.generate_logo_url_from_website!
respond_to do |format|
format.html { redirect_to family_merchants_path, notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.action(:redirect, family_merchants_path) }
end
end
elsif @merchant.update(merchant_params)
respond_to do |format|
format.html { redirect_to family_merchants_path, notice: t(".success") }
format.turbo_stream { render turbo_stream: turbo_stream.action(:redirect, family_merchants_path) }
end
else
render :edit, status: :unprocessable_entity
end
rescue ActiveRecord::RecordInvalid => e
@family_merchant = e.record
render :edit, status: :unprocessable_entity
end
def destroy
if @merchant.is_a?(ProviderMerchant)
# Unlink from family's transactions only (don't delete the global merchant)
@merchant.unlink_from_family(Current.family)
redirect_to family_merchants_path, notice: t(".unlinked_success")
else
@merchant.destroy!
redirect_to family_merchants_path, notice: t(".success")
end
end
def enhance
cache_key = "enhance_provider_merchants:#{Current.family.id}"
already_running = !Rails.cache.write(cache_key, true, expires_in: 10.minutes, unless_exist: true)
if already_running
return redirect_to family_merchants_path, alert: t(".already_running")
end
EnhanceProviderMerchantsJob.perform_later(Current.family)
redirect_to family_merchants_path, notice: t(".success")
end
def merge
@merchants = all_family_merchants
end
def perform_merge
# Scope lookups to merchants valid for this family (FamilyMerchants + assigned ProviderMerchants)
valid_merchants = all_family_merchants
target = valid_merchants.find_by(id: params[:target_id])
unless target
return redirect_to merge_family_merchants_path, alert: t(".target_not_found")
end
sources = valid_merchants.where(id: params[:source_ids])
unless sources.any?
return redirect_to merge_family_merchants_path, alert: t(".invalid_merchants")
end
merger = Merchant::Merger.new(
family: Current.family,
target_merchant: target,
source_merchants: sources
)
if merger.merge!
redirect_to family_merchants_path, notice: t(".success", count: merger.merged_count)
else
redirect_to merge_family_merchants_path, alert: t(".no_merchants_selected")
end
rescue Merchant::Merger::UnauthorizedMerchantError => e
redirect_to merge_family_merchants_path, alert: e.message
end
private
def set_merchant
# Find merchant that either belongs to family OR is assigned to family's transactions
@merchant = Current.family.merchants.find_by(id: params[:id]) ||
Current.family.assigned_merchants.find(params[:id])
@family_merchant = @merchant # For backwards compatibility with views
end
def merchant_params
# Handle both family_merchant and provider_merchant param keys
key = params.key?(:family_merchant) ? :family_merchant : :provider_merchant
params.require(key).permit(:name, :color, :website_url)
end
def all_family_merchants
family_merchant_ids = Current.family.merchants.pluck(:id)
provider_merchant_ids = Current.family.assigned_merchants.where(type: "ProviderMerchant").pluck(:id)
combined_ids = (family_merchant_ids + provider_merchant_ids).uniq
Merchant.where(id: combined_ids)
.order(Arel.sql("LOWER(COALESCE(name, ''))"))
end
end