module ClubBillingProfile extend ActiveSupport::Concern BILLING_ENTITY_TYPE_KEYS = %w[company individual nonprofit].freeze class_methods do def billing_entity_types ClubBillingProfile::BILLING_ENTITY_TYPE_KEYS.index_with { |key| I18n.t("billing.entity_types.#{key}") } end end included do validates :billing_entity_type, inclusion: { in: BILLING_ENTITY_TYPE_KEYS }, allow_nil: true validates :billing_email, format: { with: URI::MailTo::EMAIL_REGEXP }, allow_blank: true validates :billing_recipient_code, length: { is: 7 }, allow_blank: true validates :billing_province, length: { is: 2 }, allow_blank: true validates :billing_country, length: { is: 2 }, allow_blank: true validate :billing_profile_for_invoicing, on: :billing_profile end def billing_profile_complete? billing_profile_errors.empty? end # Campi minimi per intestazione fattura e invio (email PDF + SDI/PEC). def billing_profile_errors errors = [] errors << I18n.t("billing.profile_errors.entity_type") if billing_entity_type.blank? errors << I18n.t("billing.profile_errors.legal_name") if billing_legal_name.blank? errors << I18n.t("billing.profile_errors.email") if billing_email.blank? errors << I18n.t("billing.profile_errors.address") if billing_address_line.blank? errors << I18n.t("billing.profile_errors.city") if billing_city.blank? errors << I18n.t("billing.profile_errors.province") if billing_province.blank? || billing_province.to_s.length != 2 errors << I18n.t("billing.profile_errors.postal_code") if billing_postal_code.blank? errors << I18n.t("billing.profile_errors.country") if billing_country.blank? || billing_country.to_s.length != 2 errors.concat(billing_tax_id_errors) errors << I18n.t("billing.profile_errors.sdi_or_pec") if billing_recipient_code.blank? && billing_pec.blank? errors << I18n.t("billing.profile_errors.sdi_invalid") if billing_recipient_code.present? && billing_recipient_code.length != 7 errors end def billing_tax_id_errors case billing_entity_type when "company" billing_vat_number.blank? ? [I18n.t("billing.profile_errors.vat_number")] : [] when "individual" billing_fiscal_code.blank? ? [I18n.t("billing.profile_errors.fiscal_code")] : [] else billing_vat_number.blank? && billing_fiscal_code.blank? ? [I18n.t("billing.profile_errors.vat_or_fiscal")] : [] end end def billing_profile_summary parts = [billing_legal_name.presence, billing_vat_number.presence && "P.IVA #{billing_vat_number}"] parts.compact.join(" ยท ") end # Righe per intestazione fattura in admin (etichetta, valore). def billing_profile_invoice_lines lines = [] lines << ["Tipo", self.class.billing_entity_types[billing_entity_type]] if billing_entity_type.present? lines << ["Intestatario", billing_legal_name] if billing_legal_name.present? lines << ["P.IVA", billing_vat_number] if billing_vat_number.present? lines << ["Codice fiscale", billing_fiscal_code] if billing_fiscal_code.present? lines << ["Email fatturazione", billing_email] if billing_email.present? lines << ["Telefono", billing_phone] if billing_phone.present? core_address = [billing_address_line, billing_postal_code, billing_city, billing_province].compact_blank if core_address.any? core_address << billing_country if billing_country.present? lines << ["Indirizzo", core_address.join(", ")] end lines << ["SDI", billing_recipient_code] if billing_recipient_code.present? lines << ["PEC", billing_pec] if billing_pec.present? lines end # Stato profilo fiscale per badge admin: :complete | :incomplete | :absent def billing_profile_admin_status return :complete if billing_profile_complete? return :absent unless billing_profile_started? :incomplete end def billing_profile_started? billing_legal_name.present? || billing_vat_number.present? || billing_fiscal_code.present? || billing_email.present? || billing_phone.present? || billing_address_line.present? || billing_city.present? || billing_postal_code.present? || billing_province.present? || billing_recipient_code.present? || billing_pec.present? end private def billing_profile_for_invoicing billing_profile_errors.each do |message| errors.add(:base, message) end end end