mirror of
https://github.com/we-promise/sure.git
synced 2026-05-25 13:34:58 +00:00
* 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>
157 lines
5.8 KiB
Ruby
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
|