<commit_before># frozen_string_literal: true

module Spree
  class CreditCard < ApplicationRecord
    belongs_to :payment_method
    belongs_to :user

    has_many :payments, as: :source

    before_save :set_last_digits

    attr_accessor :verification_value
    attr_reader :number
    attr_writer :save_requested_by_customer # For holding customer preference in memory

    validates :month, :year, numericality: { only_integer: true }
    validates :number, presence: true, unless: :has_payment_profile?, on: :create
    validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create
    validate :expiry_not_in_the_past

    after_create :ensure_single_default_card
    after_save :ensure_single_default_card, if: :default_card_needs_updating?

    scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }

    # needed for some of the ActiveMerchant gateways (eg. SagePay)
    alias_attribute :brand, :cc_type

    def expiry=(expiry)
      self[:month], self[:year] = expiry.split(" / ")
      self[:year] = "20" + self[:year]
    end

    def number=(num)
      @number = begin
                  num.gsub(/[^0-9]/, '')
                rescue StandardError
                  nil
                end
    end

    # cc_type is set by jquery.payment, which helpfully provides different
    # types from Active Merchant. Converting them is necessary.
    def cc_type=(type)
      real_type = case type
                  when 'mastercard', 'maestro'
                    'master'
                  when 'amex'
                    'american_express'
                  when 'dinersclub'
                    'diners_club'
                  else
                    type
                  end
      self[:cc_type] = real_type
    end

    def set_last_digits
      number.to_s.gsub!(/\s/, '')
      verification_value.to_s.gsub!(/\s/, '')
      self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
    end

    def name?
      first_name? && last_name?
    end

    def name
      "#{first_name} #{last_name}"
    end

    def verification_value?
      verification_value.present?
    end

    # Show the card number, with all but last 4 numbers replace with "X". (XXXX-XXXX-XXXX-4338)
    def display_number
      "XXXX-XXXX-XXXX-#{last_digits}"
    end

    def actions
      %w{capture void credit resend_authorization_email}<commit_msg>Replace gsub! with gsub so that strings are not modified<commit_after># frozen_string_literal: true

module Spree
  class CreditCard < ApplicationRecord
    belongs_to :payment_method
    belongs_to :user

    has_many :payments, as: :source

    before_save :set_last_digits

    attr_accessor :verification_value
    attr_reader :number
    attr_writer :save_requested_by_customer # For holding customer preference in memory

    validates :month, :year, numericality: { only_integer: true }
    validates :number, presence: true, unless: :has_payment_profile?, on: :create
    validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create
    validate :expiry_not_in_the_past

    after_create :ensure_single_default_card
    after_save :ensure_single_default_card, if: :default_card_needs_updating?

    scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }

    # needed for some of the ActiveMerchant gateways (eg. SagePay)
    alias_attribute :brand, :cc_type

    def expiry=(expiry)
      self[:month], self[:year] = expiry.split(" / ")
      self[:year] = "20" + self[:year]
    end

    def number=(num)
      @number = begin
                  num.gsub(/[^0-9]/, '')
                rescue StandardError
                  nil
                end
    end

    # cc_type is set by jquery.payment, which helpfully provides different
    # types from Active Merchant. Converting them is necessary.
    def cc_type=(type)
      real_type = case type
                  when 'mastercard', 'maestro'
                    'master'
                  when 'amex'
                    'american_express'
                  when 'dinersclub'
                    'diners_club'
                  else
                    type
                  end
      self[:cc_type] = real_type
    end

    def set_last_digits
      number = @number.to_s.gsub(/\s/, '')
      verification_value = verification_value.to_s.gsub(/\s/, '')
      self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
    end

    def name?
      first_name? && last_name?
    end

    def name
      "#{first_name} #{last_name}"
    end

    def verification_value?
      verification_value.present?
    end

    # Show the card number, with all but last 4 numbers replace with "X". (XXXX-XXXX-XXXX-4338)
    def display_number
      "XXXX-XXXX-XXXX-#{last_digits}"
    end

    def actions
      %w{capture void credit resend_authorization_email}
{'fraction_non_alphanumeric': 0.08954008954008955, 'fraction_numerical': 0.004884004884004884, 'mean_word_length': 2.3526603001364257, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1760317', 'n_tokens_mistral': 1524, 'n_tokens_neox': 1448, 'n_words': 376}