mirror of
https://github.com/internetee/registry.git
synced 2025-07-31 23:16:23 +02:00
Merge branch 'master' into 2334-remove-que
This commit is contained in:
commit
a6a3f72032
240 changed files with 5827 additions and 1432 deletions
|
@ -34,9 +34,11 @@ class Ability
|
|||
if @user.registrar.api_ip_white?(@ip)
|
||||
can :manage, Depp::Contact
|
||||
can :manage, :xml_console
|
||||
can :manage, Depp::Domain
|
||||
can :manage, Depp::Domain
|
||||
end
|
||||
|
||||
can :manage, Account
|
||||
|
||||
# Poll
|
||||
can :manage, :poll
|
||||
|
||||
|
@ -65,12 +67,13 @@ class Ability
|
|||
can(:update, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||
can(:delete, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||
can(:renew, Epp::Contact)
|
||||
can(:transfer, Epp::Contact)
|
||||
can(:transfer, Epp::Contact)
|
||||
can(:view_password, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||
end
|
||||
|
||||
def billing # Registrar/api_user dynamic role
|
||||
can(:manage, Invoice) { |i| i.buyer_id == @user.registrar_id }
|
||||
can :manage, Account
|
||||
can :manage, :deposit
|
||||
can :read, AccountActivity
|
||||
can :manage, :balance_auto_reload
|
||||
|
@ -95,6 +98,7 @@ class Ability
|
|||
can :manage, User
|
||||
can :manage, ApiUser
|
||||
can :manage, AdminUser
|
||||
can :manage, Auction
|
||||
can :manage, Certificate
|
||||
can :manage, LegalDocument
|
||||
can :manage, BankStatement
|
||||
|
|
|
@ -28,14 +28,20 @@ class Action < ApplicationRecord
|
|||
end
|
||||
|
||||
def to_non_available_contact_codes
|
||||
return [] unless bulk_action?
|
||||
return [serialized_contact(contact)] unless bulk_action?
|
||||
|
||||
subactions.map do |a|
|
||||
{
|
||||
code: a.contact.code,
|
||||
avail: 0,
|
||||
reason: 'in use',
|
||||
}
|
||||
serialized_contact(a.contact)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def serialized_contact(contact)
|
||||
{
|
||||
code: contact.code,
|
||||
avail: 0,
|
||||
reason: 'in use',
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ class AdminDomainContact < DomainContact
|
|||
skipped_domains = []
|
||||
admin_contacts = where(contact: current_contact)
|
||||
|
||||
admin_contacts.each do |admin_contact|
|
||||
admin_contacts.includes(:domain).find_each do |admin_contact|
|
||||
if admin_contact.domain.bulk_update_prohibited?
|
||||
skipped_domains << admin_contact.domain.name
|
||||
next
|
||||
|
|
|
@ -30,11 +30,11 @@ class ApiUser < User
|
|||
|
||||
alias_attribute :login, :username
|
||||
|
||||
SUPER = 'super'
|
||||
EPP = 'epp'
|
||||
BILLING = 'billing'
|
||||
SUPER = 'super'.freeze
|
||||
EPP = 'epp'.freeze
|
||||
BILLING = 'billing'.freeze
|
||||
|
||||
ROLES = %w(super epp billing) # should not match to admin roles
|
||||
ROLES = %w[super epp billing].freeze # should not match to admin roles
|
||||
|
||||
def ability
|
||||
@ability ||= Ability.new(self)
|
||||
|
@ -72,8 +72,9 @@ class ApiUser < User
|
|||
|
||||
def linked_users
|
||||
self.class.where(identity_code: identity_code)
|
||||
.where("identity_code IS NOT NULL AND identity_code != ''")
|
||||
.where.not(id: id)
|
||||
.where("identity_code IS NOT NULL AND identity_code != ''")
|
||||
.where.not(id: id)
|
||||
.includes(:registrar)
|
||||
end
|
||||
|
||||
def linked_with?(another_api_user)
|
||||
|
|
|
@ -9,11 +9,30 @@ class Auction < ApplicationRecord
|
|||
domain_not_registered: 'domain_not_registered',
|
||||
}
|
||||
|
||||
enum platform: %i[auto manual]
|
||||
|
||||
PENDING_STATUSES = [statuses[:started],
|
||||
statuses[:awaiting_payment],
|
||||
statuses[:payment_received]].freeze
|
||||
|
||||
private_constant :PENDING_STATUSES
|
||||
|
||||
scope :with_status, ->(status) {
|
||||
where(status: status) if status.present?
|
||||
}
|
||||
|
||||
scope :with_start_created_at_date, ->(start_created_at) {
|
||||
where('created_at >= ?', start_created_at) if start_created_at.present?
|
||||
}
|
||||
|
||||
scope :with_end_created_at_date, ->(end_created_at) {
|
||||
where('created_at <= ?', end_created_at) if end_created_at.present?
|
||||
}
|
||||
|
||||
scope :with_domain_name, ->(domain_name) {
|
||||
where('domain ilike ?', "%#{domain_name.strip}%") if domain_name.present?
|
||||
}
|
||||
|
||||
def self.pending(domain_name)
|
||||
find_by(domain: domain_name.to_s, status: PENDING_STATUSES)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module BalanceAutoReloadTypes
|
||||
class Threshold
|
||||
include ActiveModel::Model
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :amount, :threshold
|
||||
|
||||
|
@ -11,8 +12,9 @@ module BalanceAutoReloadTypes
|
|||
Setting.minimum_deposit
|
||||
end
|
||||
|
||||
def as_json(options)
|
||||
def as_json(options = nil)
|
||||
{ name: name }.merge(super)
|
||||
.except('errors', 'validation_context')
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -33,10 +33,10 @@ class BankTransaction < ApplicationRecord
|
|||
return unless autobindable?
|
||||
|
||||
channel = manual ? 'admin_payment' : 'system_payment'
|
||||
create_internal_payment_record(channel: channel, invoice: invoice, registrar: registrar)
|
||||
create_internal_payment_record(invoice: invoice, registrar: registrar, channel: channel)
|
||||
end
|
||||
|
||||
def create_internal_payment_record(channel: nil, invoice:, registrar:)
|
||||
def create_internal_payment_record(invoice:, registrar:, channel: nil)
|
||||
if channel.nil?
|
||||
create_activity(invoice.buyer, invoice)
|
||||
return
|
||||
|
@ -47,9 +47,12 @@ class BankTransaction < ApplicationRecord
|
|||
|
||||
if create_activity(registrar, invoice)
|
||||
payment_order.paid!
|
||||
EisBilling::SendInvoiceStatus.send_info(invoice_number: invoice.number,
|
||||
status: 'paid')
|
||||
else
|
||||
payment_order.update(notes: 'Failed to create activity', status: 'failed')
|
||||
end
|
||||
invoice
|
||||
end
|
||||
|
||||
def bind_invoice(invoice_no, manual: false)
|
||||
|
@ -62,8 +65,8 @@ class BankTransaction < ApplicationRecord
|
|||
validate_invoice_data(invoice)
|
||||
return if errors.any?
|
||||
|
||||
create_internal_payment_record(channel: (manual ? 'admin_payment' : nil), invoice: invoice,
|
||||
registrar: invoice.buyer)
|
||||
create_internal_payment_record(invoice: invoice, registrar: invoice.buyer,
|
||||
channel: (manual ? 'admin_payment' : nil))
|
||||
end
|
||||
|
||||
def validate_invoice_data(invoice)
|
||||
|
|
|
@ -4,8 +4,8 @@ module Billing
|
|||
MULTI_REGEXP = /(\d{2,20})/
|
||||
|
||||
def self.generate
|
||||
base = Base.generate
|
||||
"#{base}#{base.check_digit}"
|
||||
result = EisBilling::GetReferenceNumber.send_request
|
||||
JSON.parse(result.body)['reference_number']
|
||||
end
|
||||
|
||||
def self.valid?(ref)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
class BulkAction < Action; end
|
|
@ -1,22 +0,0 @@
|
|||
module Contact::Disclosable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
attr_accessor :disclosable_attributes
|
||||
end
|
||||
|
||||
included do
|
||||
self.disclosable_attributes = %w[name email]
|
||||
validate :validate_disclosed_attributes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_disclosed_attributes
|
||||
return if disclosed_attributes.empty?
|
||||
|
||||
has_undisclosable_attributes = (disclosed_attributes - self.class.disclosable_attributes)
|
||||
.any?
|
||||
errors.add(:disclosed_attributes, :invalid) if has_undisclosable_attributes
|
||||
end
|
||||
end
|
|
@ -18,9 +18,7 @@ module EmailVerifable
|
|||
def need_to_start_force_delete?
|
||||
flag = false
|
||||
ValidationEvent::INVALID_EVENTS_COUNT_BY_LEVEL.each do |level, count|
|
||||
if validation_events.count >= count && validate_email_data(level: level, count: count)
|
||||
flag = true
|
||||
end
|
||||
flag = true if validation_events.count >= count && validate_email_data(level: level, count: count)
|
||||
end
|
||||
|
||||
flag
|
||||
|
|
|
@ -5,12 +5,22 @@ module Invoice::Cancellable
|
|||
scope :non_cancelled, -> { where(cancelled_at: nil) }
|
||||
end
|
||||
|
||||
def can_be_cancelled?
|
||||
unless cancellable?
|
||||
errors.add(:base, :invoice_status_prohibits_operation)
|
||||
return false
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def cancellable?
|
||||
unpaid? && not_cancelled?
|
||||
end
|
||||
|
||||
def cancel
|
||||
raise 'Invoice cannot be cancelled' unless cancellable?
|
||||
|
||||
update!(cancelled_at: Time.zone.now)
|
||||
end
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ module Invoice::Payable
|
|||
end
|
||||
|
||||
def receipt_date
|
||||
return unless paid?
|
||||
|
||||
account_activity.created_at.to_date
|
||||
end
|
||||
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
module Registrar::BookKeeping
|
||||
module Registrar::BookKeeping # rubocop:disable Metrics/ModuleLength
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI',
|
||||
'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze
|
||||
|
||||
included do
|
||||
scope :with_cash_accounts, (lambda do
|
||||
joins(:accounts).where('accounts.account_type = ? AND test_registrar != ?',
|
||||
Account::CASH,
|
||||
true)
|
||||
end)
|
||||
end
|
||||
|
||||
def monthly_summary(month:)
|
||||
activities = monthly_activites(month)
|
||||
return unless activities.any?
|
||||
|
||||
invoice = {
|
||||
'number': 1,
|
||||
'customer': compose_directo_customer,
|
||||
'number': 1, 'customer': compose_directo_customer,
|
||||
'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency,
|
||||
'date': month.end_of_month.strftime('%Y-%m-%d')
|
||||
}.as_json
|
||||
|
||||
invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities)
|
||||
|
||||
invoice
|
||||
end
|
||||
|
||||
|
@ -55,20 +60,25 @@ module Registrar::BookKeeping
|
|||
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
|
||||
end
|
||||
|
||||
def monthly_invoice(month:)
|
||||
invoices.where(monthly_invoice: true, issue_date: month.end_of_month.to_date,
|
||||
cancelled_at: nil).first
|
||||
end
|
||||
|
||||
def new_monthly_invoice_line(activity:, duration: nil)
|
||||
price = load_price(activity)
|
||||
line = {
|
||||
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
|
||||
'quantity': 1,
|
||||
'unit': language == 'en' ? 'pc' : 'tk',
|
||||
}
|
||||
}.with_indifferent_access
|
||||
|
||||
finalize_invoice_line(line, price: price, duration: duration, activity: activity)
|
||||
end
|
||||
|
||||
def finalize_invoice_line(line, price:, activity:, duration:)
|
||||
yearly = price.duration.in_years.to_i >= 1
|
||||
line['price'] = yearly ? (price.price.amount / price.duration.in_years.to_i) : price.price.amount
|
||||
line['price'] = yearly ? (price.price.amount / price.duration.in_years.to_i).to_f : price.price.amount.to_f
|
||||
line['description'] = description_in_language(price: price, yearly: yearly)
|
||||
|
||||
add_product_timeframe(line: line, activity: activity, duration: duration) if duration.present? && (duration > 1)
|
||||
|
@ -79,15 +89,16 @@ module Registrar::BookKeeping
|
|||
def add_product_timeframe(line:, activity:, duration:)
|
||||
create_time = activity.created_at
|
||||
line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d')
|
||||
line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d')
|
||||
line['end_date'] = (create_time + duration.year).end_of_month.strftime('%Y-%m-%d')
|
||||
end
|
||||
|
||||
def description_in_language(price:, yearly:)
|
||||
timeframe_string = yearly ? 'yearly' : 'monthly'
|
||||
locale_string = "registrar.invoice_#{timeframe_string}_product_description"
|
||||
length = yearly ? price.duration.in_years.to_i : price.duration.in_months.to_i
|
||||
|
||||
I18n.with_locale(language == 'en' ? 'en' : 'et') do
|
||||
I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.in_years.to_i)
|
||||
I18n.t(locale_string, tld: ".#{price.zone_name}", length: length)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ class Contact < ApplicationRecord
|
|||
include UserEvents
|
||||
include Contact::Transferable
|
||||
include Contact::Identical
|
||||
include Contact::Disclosable
|
||||
include Contact::Archivable
|
||||
include EmailVerifable
|
||||
|
||||
|
@ -16,7 +15,7 @@ class Contact < ApplicationRecord
|
|||
has_many :domain_contacts
|
||||
has_many :domains, through: :domain_contacts
|
||||
has_many :legal_documents, as: :documentable
|
||||
has_many :validation_events, as: :validation_eventable
|
||||
has_many :validation_events, as: :validation_eventable, dependent: :destroy
|
||||
has_many :registrant_domains, class_name: 'Domain', foreign_key: 'registrant_id'
|
||||
has_many :actions, dependent: :destroy
|
||||
|
||||
|
@ -55,7 +54,7 @@ class Contact < ApplicationRecord
|
|||
|
||||
validates :phone, presence: true, e164: true, phone: true
|
||||
|
||||
validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? }
|
||||
# validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? }
|
||||
|
||||
validates :code,
|
||||
uniqueness: { message: :epp_id_taken },
|
||||
|
@ -86,41 +85,41 @@ class Contact < ApplicationRecord
|
|||
|
||||
self.ignored_columns = %w[legacy_id legacy_history_id]
|
||||
|
||||
ORG = 'org'
|
||||
PRIV = 'priv'
|
||||
ORG = 'org'.freeze
|
||||
PRIV = 'priv'.freeze
|
||||
|
||||
# For foreign private persons who has no national identification number
|
||||
BIRTHDAY = 'birthday'.freeze
|
||||
|
||||
# From old registry software ("Fred"). No new contact can be created with this status
|
||||
PASSPORT = 'passport'
|
||||
PASSPORT = 'passport'.freeze
|
||||
|
||||
#
|
||||
# STATUSES
|
||||
#
|
||||
# Requests to delete the object MUST be rejected.
|
||||
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'
|
||||
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'
|
||||
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'.freeze
|
||||
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'.freeze
|
||||
|
||||
# Requests to transfer the object MUST be rejected.
|
||||
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'
|
||||
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'
|
||||
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'.freeze
|
||||
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'.freeze
|
||||
|
||||
# The contact object has at least one active association with
|
||||
# another object, such as a domain object. Servers SHOULD provide
|
||||
# services to determine existing object associations.
|
||||
# "linked" status MAY be combined with any status.
|
||||
LINKED = 'linked'
|
||||
LINKED = 'linked'.freeze
|
||||
|
||||
# This is the normal status value for an object that has no pending
|
||||
# operations or prohibitions. This value is set and removed by the
|
||||
# server as other status values are added or removed.
|
||||
# "ok" status MAY only be combined with "linked" status.
|
||||
OK = 'ok'
|
||||
OK = 'ok'.freeze
|
||||
|
||||
# Requests to update the object (other than to remove this status) MUST be rejected.
|
||||
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'
|
||||
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'
|
||||
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'.freeze
|
||||
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'.freeze
|
||||
|
||||
# A transform command has been processed for the object, but the
|
||||
# action has not been completed by the server. Server operators can
|
||||
|
@ -135,16 +134,16 @@ class Contact < ApplicationRecord
|
|||
# the status of the object has changed.
|
||||
# The pendingCreate, pendingDelete, pendingTransfer, and pendingUpdate
|
||||
# status values MUST NOT be combined with each other.
|
||||
PENDING_CREATE = 'pendingCreate'
|
||||
PENDING_CREATE = 'pendingCreate'.freeze
|
||||
# "pendingTransfer" status MUST NOT be combined with either
|
||||
# "clientTransferProhibited" or "serverTransferProhibited" status.
|
||||
PENDING_TRANSFER = 'pendingTransfer'
|
||||
PENDING_TRANSFER = 'pendingTransfer'.freeze
|
||||
# "pendingUpdate" status MUST NOT be combined with either
|
||||
# "clientUpdateProhibited" or "serverUpdateProhibited" status.
|
||||
PENDING_UPDATE = 'pendingUpdate'
|
||||
PENDING_UPDATE = 'pendingUpdate'.freeze
|
||||
# "pendingDelete" MUST NOT be combined with either
|
||||
# "clientDeleteProhibited" or "serverDeleteProhibited" status.
|
||||
PENDING_DELETE = 'pendingDelete'
|
||||
PENDING_DELETE = 'pendingDelete'.freeze
|
||||
|
||||
STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED,
|
||||
|
@ -152,18 +151,18 @@ class Contact < ApplicationRecord
|
|||
SERVER_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED, SERVER_UPDATE_PROHIBITED,
|
||||
OK, PENDING_CREATE, PENDING_DELETE, PENDING_TRANSFER,
|
||||
PENDING_UPDATE, LINKED
|
||||
]
|
||||
].freeze
|
||||
|
||||
CLIENT_STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
||||
CLIENT_UPDATE_PROHIBITED
|
||||
]
|
||||
].freeze
|
||||
|
||||
SERVER_STATUSES = [
|
||||
SERVER_UPDATE_PROHIBITED,
|
||||
SERVER_DELETE_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED
|
||||
]
|
||||
SERVER_TRANSFER_PROHIBITED,
|
||||
].freeze
|
||||
#
|
||||
# END OF STATUSES
|
||||
#
|
||||
|
@ -361,7 +360,7 @@ class Contact < ApplicationRecord
|
|||
@desc[dom.name][:roles] << :registrant
|
||||
end
|
||||
|
||||
domain_contacts.each do |dc|
|
||||
domain_contacts.includes(:domain).each do |dc|
|
||||
@desc[dc.domain.name] ||= { id: dc.domain.uuid, roles: [] }
|
||||
@desc[dc.domain.name][:roles] << dc.name.downcase.to_sym
|
||||
@desc[dc.domain.name] = @desc[dc.domain.name].compact
|
||||
|
@ -389,6 +388,10 @@ class Contact < ApplicationRecord
|
|||
"#{code} #{name}"
|
||||
end
|
||||
|
||||
def name_disclosed_by_registrar(reg_id)
|
||||
registrar_id == reg_id ? name : 'N/A'
|
||||
end
|
||||
|
||||
def strip_email
|
||||
self.email = email.to_s.strip
|
||||
end
|
||||
|
@ -411,7 +414,7 @@ class Contact < ApplicationRecord
|
|||
|
||||
# using small rails hack to generate outer join
|
||||
domains = if sorts.first == 'registrar_name'.freeze
|
||||
domains.includes(:registrar).where.not(registrars: { id: nil })
|
||||
domains.where.not(registrars: { id: nil })
|
||||
.order("registrars.name #{order} NULLS LAST")
|
||||
else
|
||||
domains.order("#{sort} #{order} NULLS LAST")
|
||||
|
@ -428,7 +431,6 @@ class Contact < ApplicationRecord
|
|||
end
|
||||
|
||||
domains.each { |d| d.roles = domain_c[d.id].uniq }
|
||||
|
||||
domains
|
||||
end
|
||||
|
||||
|
@ -444,18 +446,28 @@ class Contact < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def qualified_domain_ids(domain_filter)
|
||||
registrant_ids = registrant_domains.pluck(:id)
|
||||
return registrant_ids if domain_filter == 'Registrant'
|
||||
def qualified_domain_ids(filters)
|
||||
rant_domains = registrant_domains.map { |d| { id: d.id, type: ['Registrant'] } }
|
||||
contact_domains = domain_contacts.map { |dc| { id: dc.domain_id, type: [dc.type] } }
|
||||
grouped_domains = group_by_id_and_type(rant_domains + contact_domains)
|
||||
return grouped_domains.keys if filters.nil? || filters == ''
|
||||
|
||||
if %w[AdminDomainContact TechDomainContact].include? domain_filter
|
||||
DomainContact.select('domain_id').where(contact_id: id, type: domain_filter)
|
||||
else
|
||||
(DomainContact.select('domain_id').where(contact_id: id).pluck(:domain_id) +
|
||||
registrant_ids).uniq
|
||||
end
|
||||
# use domain_filters.sort == v.sort if should be exact match
|
||||
grouped_domains.reject { |_, v| ([].push(filters).flatten & v).empty? }.keys
|
||||
end
|
||||
|
||||
# def qualified_domain_ids(domain_filter)
|
||||
# registrant_ids = registrant_domains.pluck(:id)
|
||||
# return registrant_ids if domain_filter == 'Registrant'
|
||||
|
||||
# if %w[AdminDomainContact TechDomainContact].include? domain_filter
|
||||
# DomainContact.where(contact_id: id, type: domain_filter).pluck(:domain_id)
|
||||
# else
|
||||
# (DomainContact.where(contact_id: id).pluck(:domain_id) +
|
||||
# registrant_ids).uniq
|
||||
# end
|
||||
# end
|
||||
|
||||
def update_prohibited?
|
||||
(statuses & [
|
||||
CLIENT_UPDATE_PROHIBITED,
|
||||
|
@ -465,7 +477,7 @@ class Contact < ApplicationRecord
|
|||
PENDING_CREATE,
|
||||
PENDING_TRANSFER,
|
||||
PENDING_UPDATE,
|
||||
PENDING_DELETE
|
||||
PENDING_DELETE,
|
||||
]).present?
|
||||
end
|
||||
|
||||
|
@ -596,4 +608,14 @@ class Contact < ApplicationRecord
|
|||
def self.csv_header
|
||||
['Name', 'ID', 'Ident', 'E-mail', 'Created at', 'Registrar', 'Phone']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def group_by_id_and_type(domains_hash_array)
|
||||
domains_hash_array.group_by { |d| d[:id] }
|
||||
.transform_values do |v|
|
||||
v.each.with_object(:type)
|
||||
.map(&:[]).flatten
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
1
app/models/contact_update_action.rb
Normal file
1
app/models/contact_update_action.rb
Normal file
|
@ -0,0 +1 @@
|
|||
class ContactUpdateAction < Action; end
|
|
@ -33,6 +33,7 @@ class Deposit
|
|||
|
||||
def issue_prepayment_invoice
|
||||
return unless valid?
|
||||
|
||||
registrar.issue_prepayment_invoice(amount, description)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,8 +31,8 @@ module Depp
|
|||
|
||||
def request(xml)
|
||||
Nokogiri::XML(server.request(xml)).remove_namespaces!
|
||||
rescue EppErrorResponse => e
|
||||
Nokogiri::XML(e.response_xml.to_s).remove_namespaces!
|
||||
rescue EppErrorResponse => e
|
||||
Nokogiri::XML(e.response_xml.to_s).remove_namespaces!
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -35,6 +35,7 @@ module DNS
|
|||
def sell_at_auction
|
||||
auction = Auction.new
|
||||
auction.domain = name
|
||||
auction.platform = 'auto'
|
||||
auction.start
|
||||
ToStdout.msg "Created the auction: #{auction.inspect}"
|
||||
update_whois_from_auction(auction)
|
||||
|
|
|
@ -161,14 +161,6 @@ class Domain < ApplicationRecord
|
|||
attribute: 'hostname'
|
||||
}
|
||||
|
||||
validates :tech_domain_contacts, uniqueness_multi: {
|
||||
attribute: 'contact_code_cache'
|
||||
}
|
||||
|
||||
validates :admin_domain_contacts, uniqueness_multi: {
|
||||
attribute: 'contact_code_cache'
|
||||
}
|
||||
|
||||
validates :dnskeys, uniqueness_multi: {
|
||||
attribute: 'public_key'
|
||||
}
|
||||
|
@ -726,7 +718,6 @@ class Domain < ApplicationRecord
|
|||
hash = super
|
||||
hash['auth_info'] = hash.delete('transfer_code') # API v1 requirement
|
||||
hash['valid_from'] = hash['created_at'] # API v1 requirement
|
||||
hash.delete('statuses_before_force_delete')
|
||||
hash
|
||||
end
|
||||
|
||||
|
|
|
@ -6,32 +6,21 @@ class DomainContact < ApplicationRecord
|
|||
belongs_to :contact
|
||||
belongs_to :domain
|
||||
|
||||
validates :contact, presence: true
|
||||
|
||||
after_destroy :update_contact
|
||||
attr_accessor :value_typeahead
|
||||
attr_writer :contact_code
|
||||
|
||||
self.ignored_columns = %w[legacy_domain_id legacy_contact_id]
|
||||
|
||||
def epp_code_map
|
||||
{
|
||||
'2302' => [
|
||||
[:contact_code_cache, :taken, { value: { obj: 'contact', val: contact_code_cache } }]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def name
|
||||
return 'Tech' if type == 'TechDomainContact'
|
||||
return 'Admin' if type == 'AdminDomainContact'
|
||||
|
||||
''
|
||||
end
|
||||
|
||||
validates :contact, presence: true
|
||||
|
||||
before_save :update_contact_code_cache
|
||||
def update_contact_code_cache
|
||||
self.contact_code_cache = contact.code
|
||||
end
|
||||
|
||||
after_destroy :update_contact
|
||||
def update_contact
|
||||
Contact.find(contact_id).save
|
||||
end
|
||||
|
|
|
@ -4,10 +4,10 @@ class DomainTransfer < ApplicationRecord
|
|||
belongs_to :old_registrar, class_name: 'Registrar'
|
||||
belongs_to :new_registrar, class_name: 'Registrar'
|
||||
|
||||
PENDING = 'pending'
|
||||
CLIENT_APPROVED = 'clientApproved'
|
||||
CLIENT_REJECTED = 'clientRejected'
|
||||
SERVER_APPROVED = 'serverApproved'
|
||||
PENDING = 'pending'.freeze
|
||||
CLIENT_APPROVED = 'clientApproved'.freeze
|
||||
CLIENT_REJECTED = 'clientRejected'.freeze
|
||||
SERVER_APPROVED = 'serverApproved'.freeze
|
||||
|
||||
before_create :set_wait_until
|
||||
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
class Feature
|
||||
# def self.obj_and_extensions_statuses_enabled?
|
||||
# return false if ENV['obj_and_extensions_prohibited'] == 'false'
|
||||
#
|
||||
# ENV['obj_and_extensions_prohibited'] || false
|
||||
# end
|
||||
#
|
||||
# def self.enable_lock_domain_with_new_statuses?
|
||||
# return false if ENV['enable_lock_domain_with_new_statuses'] == 'false'
|
||||
#
|
||||
# ENV['enable_lock_domain_with_new_statuses'] || false
|
||||
# end
|
||||
def self.billing_system_integrated?
|
||||
return false if ENV['billing_system_integrated'] == 'false'
|
||||
|
||||
ENV['billing_system_integrated'] || false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,30 +32,43 @@ class Invoice < ApplicationRecord
|
|||
# rubocop:enable Layout/LineLength
|
||||
# rubocop:enable Style/MultilineBlockLayout
|
||||
validates :due_date, :currency, :seller_name,
|
||||
:seller_iban, :buyer_name, :items, presence: true
|
||||
:seller_iban, :buyer_name, presence: true
|
||||
validates :items, presence: true, unless: -> { monthly_invoice }
|
||||
|
||||
before_create :set_invoice_number
|
||||
before_create :calculate_total, unless: :total?
|
||||
before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no?
|
||||
skip_callback :create, :before, :set_invoice_number, if: -> { monthly_invoice }
|
||||
skip_callback :create, :before, :calculate_total, if: -> { monthly_invoice }
|
||||
|
||||
attribute :vat_rate, ::Type::VatRate.new
|
||||
|
||||
def set_invoice_number
|
||||
last_no = Invoice.order(number: :desc).limit(1).pick(:number)
|
||||
def validate_invoice_number(result)
|
||||
response = JSON.parse(result.body)
|
||||
|
||||
if last_no && last_no >= Setting.invoice_number_min.to_i
|
||||
self.number = last_no + 1
|
||||
else
|
||||
self.number = Setting.invoice_number_min.to_i
|
||||
end
|
||||
billing_restrictions_issue if response['code'] == '403'
|
||||
billing_out_of_range_issue if response['error'] == 'out of range'
|
||||
end
|
||||
|
||||
return if number <= Setting.invoice_number_max.to_i
|
||||
def billing_restrictions_issue
|
||||
errors.add(:base, I18n.t('cannot get access'))
|
||||
logger.error('PROBLEM WITH TOKEN')
|
||||
throw(:abort)
|
||||
end
|
||||
|
||||
def billing_out_of_range_issue
|
||||
errors.add(:base, I18n.t('failed_to_generate_invoice_invoice_number_limit_reached'))
|
||||
logger.error('INVOICE NUMBER LIMIT REACHED, COULD NOT GENERATE INVOICE')
|
||||
throw(:abort)
|
||||
end
|
||||
|
||||
def set_invoice_number
|
||||
result = EisBilling::GetInvoiceNumber.send_invoice
|
||||
validate_invoice_number(result)
|
||||
|
||||
self.number = JSON.parse(result.body)['invoice_number'].to_i
|
||||
end
|
||||
|
||||
def to_s
|
||||
I18n.t('invoice_no', no: number)
|
||||
end
|
||||
|
@ -82,7 +95,7 @@ class Invoice < ApplicationRecord
|
|||
end
|
||||
|
||||
def subtotal
|
||||
items.map(&:item_sum_without_vat).reduce(:+)
|
||||
items.map(&:item_sum_without_vat).reduce(:+) || 0
|
||||
end
|
||||
|
||||
def vat_amount
|
||||
|
@ -95,7 +108,11 @@ class Invoice < ApplicationRecord
|
|||
end
|
||||
|
||||
def each(&block)
|
||||
items.each(&block)
|
||||
if monthly_invoice
|
||||
metadata['items'].map { |el| OpenStruct.new(el) }.each(&block)
|
||||
else
|
||||
items.each(&block)
|
||||
end
|
||||
end
|
||||
|
||||
def as_pdf
|
||||
|
@ -144,6 +161,13 @@ class Invoice < ApplicationRecord
|
|||
|
||||
private
|
||||
|
||||
ransacker :number_str do
|
||||
Arel.sql(
|
||||
"regexp_replace(
|
||||
to_char(\"#{table_name}\".\"number\", '999999999999'), ' ', '', 'g')"
|
||||
)
|
||||
end
|
||||
|
||||
def receipt_date_status
|
||||
if paid?
|
||||
receipt_date
|
||||
|
|
|
@ -41,22 +41,16 @@ class Invoice
|
|||
|
||||
e_invoice_invoice_items = []
|
||||
invoice.each do |invoice_item|
|
||||
e_invoice_invoice_item = EInvoice::InvoiceItem.new.tap do |i|
|
||||
i.description = invoice_item.description
|
||||
i.price = invoice_item.price
|
||||
i.quantity = invoice_item.quantity
|
||||
i.unit = invoice_item.unit
|
||||
i.subtotal = invoice_item.subtotal
|
||||
i.vat_rate = invoice_item.vat_rate
|
||||
i.vat_amount = invoice_item.vat_amount
|
||||
i.total = invoice_item.total
|
||||
end
|
||||
e_invoice_invoice_item = generate_invoice_item(invoice, invoice_item)
|
||||
e_invoice_invoice_items << e_invoice_invoice_item
|
||||
end
|
||||
|
||||
e_invoice_name_item = e_invoice_invoice_items.shift if invoice.monthly_invoice
|
||||
|
||||
e_invoice_invoice = EInvoice::Invoice.new.tap do |i|
|
||||
i.seller = seller
|
||||
i.buyer = buyer
|
||||
i.name = e_invoice_name_item&.description
|
||||
i.items = e_invoice_invoice_items
|
||||
i.number = invoice.number
|
||||
i.date = invoice.issue_date
|
||||
|
@ -72,9 +66,33 @@ class Invoice
|
|||
i.currency = invoice.currency
|
||||
i.delivery_channel = %i[internet_bank portal]
|
||||
i.payable = payable
|
||||
i.monthly_invoice = invoice.monthly_invoice
|
||||
end
|
||||
|
||||
EInvoice::EInvoice.new(date: Time.zone.today, invoice: e_invoice_invoice)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_invoice_item(invoice, item)
|
||||
EInvoice::InvoiceItem.new.tap do |i|
|
||||
i.description = item.description
|
||||
i.unit = item.unit
|
||||
i.price = item.price
|
||||
i.quantity = item.quantity
|
||||
if invoice.monthly_invoice && item.price && item.quantity
|
||||
i.product_id = item.product_id
|
||||
i.vat_rate = invoice.vat_rate
|
||||
i.subtotal = (item.price * item.quantity).round(3)
|
||||
i.vat_amount = i.subtotal * (i.vat_rate / 100)
|
||||
i.total = i.subtotal + i.vat_amount
|
||||
else
|
||||
i.subtotal = item.subtotal
|
||||
i.vat_rate = item.vat_rate
|
||||
i.vat_amount = item.vat_amount
|
||||
i.total = item.total
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,8 @@ class Invoice
|
|||
private
|
||||
|
||||
def invoice_html
|
||||
ApplicationController.render(template: 'invoice/pdf', assigns: { invoice: invoice })
|
||||
template = invoice.monthly_invoice ? 'invoice/monthly_pdf' : 'invoice/pdf'
|
||||
ApplicationController.render(template: template, assigns: { invoice: invoice })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class Notification < ApplicationRecord
|
||||
include Versions # version/notification_version.rb
|
||||
include EppErrors
|
||||
|
||||
belongs_to :registrar
|
||||
belongs_to :action, optional: true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Registrar < ApplicationRecord
|
||||
class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||
include Versions # version/registrar_version.rb
|
||||
include Registrar::BookKeeping
|
||||
include EmailVerifable
|
||||
|
@ -34,12 +34,12 @@ class Registrar < ApplicationRecord
|
|||
attribute :vat_rate, ::Type::VatRate.new
|
||||
after_initialize :set_defaults
|
||||
|
||||
validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? }
|
||||
validate :correct_billing_email_format
|
||||
# validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? }
|
||||
# validate :correct_billing_email_format
|
||||
|
||||
alias_attribute :contact_email, :email
|
||||
|
||||
WHOIS_TRIGGERS = %w(name email phone street city state zip)
|
||||
WHOIS_TRIGGERS = %w[name email phone street city state zip].freeze
|
||||
|
||||
after_commit :update_whois_records
|
||||
def update_whois_records
|
||||
|
@ -56,9 +56,48 @@ class Registrar < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def issue_prepayment_invoice(amount, description = nil, payable: true)
|
||||
vat_rate = ::Invoice::VatRateCalculator.new(registrar: self).calculate
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def init_monthly_invoice(summary)
|
||||
Invoice.new(
|
||||
issue_date: summary['date'].to_date,
|
||||
due_date: summary['date'].to_date,
|
||||
currency: 'EUR',
|
||||
description: I18n.t('invoice.monthly_invoice_description'),
|
||||
seller_name: Setting.registry_juridical_name,
|
||||
seller_reg_no: Setting.registry_reg_no,
|
||||
seller_iban: Setting.registry_iban,
|
||||
seller_bank: Setting.registry_bank,
|
||||
seller_swift: Setting.registry_swift,
|
||||
seller_vat_no: Setting.registry_vat_no,
|
||||
seller_country_code: Setting.registry_country_code,
|
||||
seller_state: Setting.registry_state,
|
||||
seller_street: Setting.registry_street,
|
||||
seller_city: Setting.registry_city,
|
||||
seller_zip: Setting.registry_zip,
|
||||
seller_phone: Setting.registry_phone,
|
||||
seller_url: Setting.registry_url,
|
||||
seller_email: Setting.registry_email,
|
||||
seller_contact_name: Setting.registry_invoice_contact,
|
||||
buyer: self,
|
||||
buyer_name: name,
|
||||
buyer_reg_no: reg_no,
|
||||
buyer_country_code: address_country_code,
|
||||
buyer_state: address_state,
|
||||
buyer_street: address_street,
|
||||
buyer_city: address_city,
|
||||
buyer_zip: address_zip,
|
||||
buyer_phone: phone,
|
||||
buyer_url: website,
|
||||
buyer_email: email,
|
||||
reference_no: reference_no,
|
||||
vat_rate: calculate_vat_rate,
|
||||
monthly_invoice: true,
|
||||
metadata: { items: summary['invoice_lines'] },
|
||||
total: 0
|
||||
)
|
||||
end
|
||||
|
||||
def issue_prepayment_invoice(amount, description = nil, payable: true)
|
||||
invoice = invoices.create!(
|
||||
issue_date: Time.zone.today,
|
||||
due_date: (Time.zone.now + Setting.days_to_keep_invoices_active.days).to_date,
|
||||
|
@ -91,14 +130,14 @@ class Registrar < ApplicationRecord
|
|||
buyer_url: website,
|
||||
buyer_email: email,
|
||||
reference_no: reference_no,
|
||||
vat_rate: vat_rate,
|
||||
vat_rate: calculate_vat_rate,
|
||||
items_attributes: [
|
||||
{
|
||||
description: 'prepayment',
|
||||
unit: 'piece',
|
||||
quantity: 1,
|
||||
price: amount
|
||||
}
|
||||
price: amount,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -107,10 +146,17 @@ class Registrar < ApplicationRecord
|
|||
.deliver_later(wait: 1.minute)
|
||||
end
|
||||
|
||||
add_invoice_instance = EisBilling::AddDeposits.new(invoice)
|
||||
result = add_invoice_instance.send_invoice
|
||||
|
||||
link = JSON.parse(result.body)['everypay_link']
|
||||
|
||||
invoice.update(payment_link: link)
|
||||
SendEInvoiceJob.set(wait: 1.minute).perform_now(invoice.id, payable: payable)
|
||||
|
||||
invoice
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def cash_account
|
||||
accounts.find_by(account_type: Account::CASH)
|
||||
|
@ -175,9 +221,9 @@ class Registrar < ApplicationRecord
|
|||
end
|
||||
|
||||
def add_nameservers(new_attributes, domains: [])
|
||||
transaction do
|
||||
return if domains.empty?
|
||||
return [] if domains.empty?
|
||||
|
||||
transaction do
|
||||
approved_list = domain_list_processing(domains: domains, new_attributes: new_attributes)
|
||||
|
||||
self.domains.where(name: approved_list).find_each(&:update_whois_record) if approved_list.any?
|
||||
|
@ -220,13 +266,9 @@ class Registrar < ApplicationRecord
|
|||
def notify(action)
|
||||
text = I18n.t("notifications.texts.#{action.notification_key}", contact: action.contact&.code,
|
||||
count: action.subactions&.count)
|
||||
if action.bulk_action?
|
||||
notifications.create!(text: text, action_id: action.id,
|
||||
attached_obj_type: 'BulkAction',
|
||||
attached_obj_id: action.id)
|
||||
else
|
||||
notifications.create!(text: text)
|
||||
end
|
||||
notifications.create!(text: text, action_id: action.id,
|
||||
attached_obj_type: 'ContactUpdateAction',
|
||||
attached_obj_id: action.id)
|
||||
end
|
||||
|
||||
def e_invoice_iban
|
||||
|
@ -256,4 +298,8 @@ class Registrar < ApplicationRecord
|
|||
def vat_liable_in_foreign_country?
|
||||
!vat_liable_locally?
|
||||
end
|
||||
|
||||
def calculate_vat_rate
|
||||
::Invoice::VatRateCalculator.new(registrar: self).calculate
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class TechDomainContact < DomainContact
|
|||
skipped_domains = []
|
||||
tech_contacts = where(contact: current_contact)
|
||||
|
||||
tech_contacts.each do |tech_contact|
|
||||
tech_contacts.includes(:domain).find_each do |tech_contact|
|
||||
if irreplaceable?(tech_contact)
|
||||
skipped_domains << tech_contact.domain.name
|
||||
next
|
||||
|
|
|
@ -13,9 +13,9 @@ class User < ApplicationRecord
|
|||
|
||||
def self.from_omniauth(omniauth_hash)
|
||||
uid = omniauth_hash['uid']
|
||||
identity_code = uid.slice(2..-1)
|
||||
identity_code = uid&.slice(2..-1)
|
||||
# country_code = uid.slice(0..1)
|
||||
|
||||
find_by(identity_code: identity_code)
|
||||
find_by(identity_code: identity_code, active: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ class ValidationEvent < ApplicationRecord
|
|||
|
||||
belongs_to :validation_eventable, polymorphic: true
|
||||
|
||||
scope :recent, -> { where('created_at < ?', Time.zone.now - VALIDATION_PERIOD) }
|
||||
scope :old_records, -> { where('created_at < ?', Time.zone.now - VALIDATION_PERIOD) }
|
||||
scope :successful, -> { where(success: true) }
|
||||
scope :failed, -> { where(success: false) }
|
||||
scope :regex, -> { where('event_data @> ?', { 'check_level': 'regex' }.to_json) }
|
||||
|
@ -35,11 +35,11 @@ class ValidationEvent < ApplicationRecord
|
|||
scope :smtp, -> { where('event_data @> ?', { 'check_level': 'smtp' }.to_json) }
|
||||
scope :by_object, ->(object) { where(validation_eventable: object) }
|
||||
|
||||
after_create :check_for_force_delete
|
||||
|
||||
def self.validated_ids_by(klass)
|
||||
recent.successful.where('validation_eventable_type = ?', klass)
|
||||
.pluck(:validation_eventable_id)
|
||||
old_records
|
||||
.successful
|
||||
.where('validation_eventable_type = ?', klass)
|
||||
.pluck(:validation_eventable_id)
|
||||
end
|
||||
|
||||
def failed?
|
||||
|
@ -57,56 +57,4 @@ class ValidationEvent < ApplicationRecord
|
|||
def object
|
||||
validation_eventable
|
||||
end
|
||||
|
||||
def check_for_force_delete
|
||||
if object.need_to_start_force_delete?
|
||||
start_force_delete
|
||||
elsif object.need_to_lift_force_delete?
|
||||
refresh_status_notes
|
||||
lift_force_delete
|
||||
end
|
||||
end
|
||||
|
||||
def start_force_delete
|
||||
Domains::ForceDeleteEmail::Base.run(email: email)
|
||||
end
|
||||
|
||||
def refresh_status_notes
|
||||
domain_list.each do |domain|
|
||||
next unless domain.status_notes[DomainStatus::FORCE_DELETE]
|
||||
|
||||
domain.status_notes[DomainStatus::FORCE_DELETE].slice!(object.email_history)
|
||||
domain.status_notes[DomainStatus::FORCE_DELETE].lstrip!
|
||||
domain.save(validate: false)
|
||||
|
||||
notify_registrar(domain) unless domain.status_notes[DomainStatus::FORCE_DELETE].empty?
|
||||
end
|
||||
end
|
||||
|
||||
def domain_list
|
||||
domain_contacts = Contact.where(email: email).map(&:domain_contacts).flatten
|
||||
registrant_ids = Registrant.where(email: email).pluck(:id)
|
||||
|
||||
(domain_contacts.map(&:domain).flatten + Domain.where(registrant_id: registrant_ids)).uniq
|
||||
end
|
||||
|
||||
def notify_registrar(domain)
|
||||
domain.registrar.notifications.create!(text: I18n.t('force_delete_auto_email',
|
||||
domain_name: domain.name,
|
||||
outzone_date: domain.outzone_date,
|
||||
purge_date: domain.purge_date,
|
||||
email: domain.status_notes[DomainStatus::FORCE_DELETE]))
|
||||
end
|
||||
|
||||
def lift_force_delete
|
||||
# domain_contacts = Contact.where(email: email).map(&:domain_contacts).flatten
|
||||
# registrant_ids = Registrant.where(email: email).pluck(:id)
|
||||
#
|
||||
# domains = domain_contacts.map(&:domain).flatten +
|
||||
# Domain.where(registrant_id: registrant_ids)
|
||||
#
|
||||
# domains.each do |domain|
|
||||
# Domains::ForceDeleteLift::Base.run(domain: domain)
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue