Skip to content

Commit

Permalink
business contact validation + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
OlegPhenomenon committed Sep 24, 2024
1 parent 4f2c29f commit d1a43ad
Show file tree
Hide file tree
Showing 23 changed files with 962 additions and 2 deletions.
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
postgresql-client \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN apt-get remove -y google-chrome-stable
RUN apt-get purge -y google-chrome-stable
RUN apt-get autoremove -y && apt-get clean

ENV CHROME_VERSION="128.0.6613.137"

RUN wget -q "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chrome-linux64.zip" \
&& unzip chrome-linux64.zip -d /opt/ \
&& rm chrome-linux64.zip

RUN wget -q "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chromedriver-linux64.zip" \
&& unzip chromedriver-linux64.zip -d /opt/ \
&& mv /opt/chromedriver-linux64/chromedriver /usr/local/bin/ \
&& rm -rf chromedriver-linux64.zip /opt/chromedriver-linux64

RUN mkdir -p /opt/webapps/app/tmp/pids
WORKDIR /opt/webapps/app
COPY Gemfile Gemfile.lock ./
# ADD vendor/gems/omniauth-tara ./vendor/gems/omniauth-tara
RUN gem install bundler && bundle install --jobs 20 --retry 5

ENV PATH="/opt/chrome-linux64:${PATH}"

EXPOSE 3000
17 changes: 17 additions & 0 deletions ai/sop/update_company_status_rake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Steps to Update company_status.rake

- [x] Modify the CSV output to include the contact type (role) information
- [x] Filter the output to include only Estonian organization type contacts
- [ ] Ensure only registrant contacts are included in the output
- [ ] Remove duplicate entries for the same organization
- [ ] Add a column to indicate if the contact is deleted due to an overdue annual statement
- [ ] Create a separate CSV file for invalid registrant contacts
- [ ] Update the existing CSV output to include only contacts that fail validation against the business registry and whitelist
- [ ] Add error handling and logging for better debugging
- [ ] Update the task description and comments to reflect the new functionality
- [ ] Add a new rake task or option to generate the separate registrant-only CSV file
- [ ] Implement validation against the business registry for Estonian organization contacts
- [ ] Implement validation against the whitelist for Estonian organization contacts
- [ ] Optimize the code for better performance, especially when dealing with large datasets
- [ ] Add unit tests for the new functionality
- [ ] Update the documentation to reflect the changes and new output format
11 changes: 11 additions & 0 deletions app/interactions/actions/contact_create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def call
maybe_attach_legal_doc
validate_ident
maybe_change_email
maybe_company_is_relevant
commit
validate_contact
end
Expand Down Expand Up @@ -77,6 +78,16 @@ def validate_ident_birthday
@error = true
end

def maybe_company_is_relevant
return true unless contact.org?

company_status = contact.return_company_status
return if [Contact::REGISTERED, Contact::LIQUIDATED].include? company_status

contact.add_epp_error('2003', nil, 'ident', I18n.t('errors.messages.company_not_registered'))
@error = true
end

def maybe_attach_legal_doc
::Actions::BaseAction.attach_legal_doc_to_new(contact, legal_document, domain: false)
end
Expand Down
2 changes: 2 additions & 0 deletions app/interactions/domains/force_delete/set_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def force_delete_fast_track
expire_warning_period_days +
redemption_grace_period_days
domain.force_delete_start = Time.zone.today + 1.day

domain.status_notes[DomainStatus::FORCE_DELETE] = "Company no: #{domain.registrant.ident}" if reason == 'invalid_company'
end

def force_delete_soft
Expand Down
113 changes: 113 additions & 0 deletions app/jobs/company_register_status_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
require 'zip'

class CompanyRegisterStatusJob < ApplicationJob
PAYMENT_STATEMENT_BUSINESS_REGISTRY_REASON = 'Kustutamiskanne dokumentide hoidjata'

queue_as :default

def perform(days_interval = 14, spam_time_delay = 1, batch_size = 100)
sampling_registrant_contact(days_interval).find_in_batches(batch_size: batch_size) do |contacts|
contacts.reject { |contact| whitelisted_company?(contact) }.each { |contact| proceed_company_status(contact, spam_time_delay) }
end
end

private

def proceed_company_status(contact, spam_time_delay)
# avoid spamming company register
sleep spam_time_delay

company_status = contact.return_company_status
contact.update!(company_register_status: company_status, checked_company_at: Time.zone.now)

puts "company id #{contact.id} status: #{company_status}"

case company_status
when Contact::REGISTERED
lift_force_delete(contact) if check_for_force_delete(contact)
when Contact::LIQUIDATED
ContactInformMailer.company_liquidation(contact: contact).deliver_now
else
delete_process(contact)
end

status = company_status.blank? ? Contact::DELETED : company_status
update_validation_company_status(contact:contact , status: status)
end

def sampling_registrant_contact(days_interval)
Registrant.where(ident_type: 'org', ident_country_code: 'EE').where(
"(company_register_status IS NULL OR checked_company_at IS NULL) OR
(company_register_status = ? AND checked_company_at < ?) OR
company_register_status IN (?)",
Contact::REGISTERED, days_interval.days.ago, [Contact::LIQUIDATED, Contact::BANKRUPT, Contact::DELETED]
)

end

def update_validation_company_status(contact:, status:)
contact.update(company_register_status: status, checked_company_at: Time.zone.now)
end

def schedule_force_delete(contact)
contact.domains.each do |domain|
next if domain.schedule_force_delete?

domain.schedule_force_delete(
type: :fast_track,
notify_by_email: true,
reason: 'invalid_company',
email: contact.email
)
end
end

def check_for_force_delete(contact)
contact.domains.any? && domain.status_notes[DomainStatus::FORCE_DELETE].include?("Company no: #{contact.ident}") do |domain|
domain.schedule_force_delete?
end
end

def lift_force_delete(contact)
contact.domains.each(&:lift_force_delete)
end

def delete_process(contact)
company_details_response = contact.return_company_details

if company_details_response.empty?
schedule_force_delete(contact)
return
end

kandeliik_tekstina = extract_kandeliik_tekstina(company_details_response)

if kandeliik_tekstina == PAYMENT_STATEMENT_BUSINESS_REGISTRY_REASON
soft_delete_company(contact)
else
schedule_force_delete(contact)
end
end

private

def extract_kandeliik_tekstina(company_details_response)
company_details_response.first.kandeliik.last.last.kandeliik_tekstina
end

def soft_delete_company(contact)
contact.domains.reject { |domain| domain.force_delete_scheduled? }.each do |domain|
domain.schedule_force_delete(type: :soft)
end

puts "Soft delete process initiated for company: #{contact.name} with ID: #{contact.id}"
end

def whitelisted_companies
@whitelisted_companies ||= ENV['whitelist_companies'].split(',')
end

def whitelisted_company?(contact)
whitelisted_companies.include?(contact.ident)
end
end
7 changes: 7 additions & 0 deletions app/mailers/contact_inform_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ def notify_nameserver(contact:, domain:, nameserver:)
mail(to: contact.email, subject: subject)
end

def company_liquidation(contact:)
@registrant = contact

subject = "Kas soovite oma .ee domeeni säilitada? / Do you wish to preserve your .ee registration?"
mail(to: contact.email, subject: subject)
end

private

def address_processing
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/domain/force_delete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def hold_status?

def notification_template(explicit: nil)
reason = explicit&.downcase
return reason if %w[invalid_email invalid_phone].include?(reason)
return reason if %w[invalid_email invalid_phone invalid_company].include?(reason)

if contact_emails_verification_failed.present?
'invalid_email'
Expand Down
1 change: 1 addition & 0 deletions app/models/contact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Contact < ApplicationRecord
include Contact::Transferable
include Contact::Identical
include Contact::Archivable
include Contact::CompanyRegister
include EmailVerifable

belongs_to :original, class_name: 'Contact'
Expand Down
38 changes: 38 additions & 0 deletions app/models/contact/company_register.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module Contact::CompanyRegister
extend ActiveSupport::Concern

REGISTERED = 'R'.freeze
LIQUIDATED = 'L'.freeze
BANKRUPT = 'N'.freeze
DELETED = 'K'.freeze

def company_is_relevant?
company_register_status == REGISTERED && company_register_status == LIQUIDATED
end

def return_company_status
return if return_company_data.blank?

return_company_data.first[:status]
end

def return_company_data
return unless org?

company_register.simple_data(registration_number: ident)
rescue CompanyRegister::NotAvailableError
[]
end

def return_company_details
return unless org?

company_register.company_details(registration_number: ident)
rescue CompanyRegister::NotAvailableError
[]
end

def company_register
@company_register ||= CompanyRegister::Client.new
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<p>Lugupeetud ettevõtte <%= @registrant.name %> esindaja,</p>

<p>Eesti Interneti Sihtasutusele (EIS) on äriregistri vahendusel teatavaks saanud, et ettevõtte <%= @registrant.name %> äriregistrikoodiga <%= @registrant.ident %> suhtes käib likvideerimismenetlus. Tuletame teile meelde, et tulenevalt .ee domeenireeglitest peab domeeni registreerijaks olema eksisteeriv era- või juriidiline isik. Seega käivitame ettevõtte likvideerimise järel sellele kuuluvate registreeringute kustutusmenetluse. Kustutusmenetluse tulemusena eemaldatakse .ee domeeninimi registrist ning vabaneb kõigile soovijatele taaskord registreerimiseks.</p>
<p>Kui soovite ettevõttele kuuluvaid registreeritud domeene ka edaspidi kasutada, soovitame teil ette valmistada registreeringute üleandmine uuele omanikule enne praeguse omaniku likvideerimist. Lähemalt leiate selle kohta infot meie kodulehelt.</p>

<p>.ee domeeni registris kuuluvad ettevõttele <%= @registrant.ident %> järgmised registreeringud:</p>
<ul>
<% @registrant.domains.each do |domain| %>
<li><%= domain.name %></li>
<% end %>
</ul>

<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrant.registrar %>
<%= render 'mailers/shared/signatures/signature.et.html' %>

<hr>

<p>Dear representative of <%= @registrant.name %>,</p>

<p>The Estonian Internet Foundation (EIS) has found through the Estonian business register that the company <%= @registrant.name %> with the business registry code <%= @registrant.ident %> is in liquidation proceedings. Please note that according to the .ee domain regulation, the registrant of the domain must be an existing private or legal entity. Therefore, the registry will start the registration deletion procedure once the liquidation of the company has been finalized. After the registration deletion procedure, the domain name will be open to register again for everyone.</p>
<p>If you want to continue to use the registered domains belonging to your company, we recommend you to prepare the transfer of the registrations to the new owner before the liquidation of the current owner will be finalized. Learn more on our website.</p>

<p>The following registrations belong to the company <%= @registrant.ident %> in the .ee domain register:</p>
<ul>
<% @registrant.domains.each do |domain| %>
<li><%= domain.name %></li>
<% end %>
</ul>

<p>Should you have additional questions, please contact your registrar:</p>
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrant.registrar %>
<%= render 'mailers/shared/signatures/signature.en.html' %>
<hr>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Lugupeetud ettevõtte <%= @registrant.name %> esindaja

Eesti Interneti Sihtasutusele (EIS) on äriregistri vahendusel teatavaks saanud, et ettevõtte <%= @registrant.name %> äriregistrikoodiga <%= @registrant.ident %> suhtes käib likvideerimismenetlus. Tuletame teile meelde, et tulenevalt .ee domeenireeglitest peab domeeni registreerijaks olema eksisteeriv era- või juriidiline isik. Seega käivitame ettevõtte likvideerimise järel sellele kuuluvate registreeringute kustutusmenetluse. Kustutusmenetluse tulemusena eemaldatakse .ee domeeninimi registrist ning vabaneb kõigile soovijatele taaskord registreerimiseks.
Kui soovite ettevõttele kuuluvaid registreeritud domeene ka edaspidi kasutada, soovitame teil ette valmistada registreeringute üleandmine uuele omanikule enne praeguse omaniku likvideerimist. Lähemalt leiate selle kohta infot meie kodulehelt.

.ee domeeni registris kuuluvad ettevõttele <%= @registrant.ident %> järgmised registreeringud:

<% @registrant.domains.each do |domain| %>
<%= domain.name %>
<% end %>


Lisaküsimuste korral võtke palun ühendust oma registripidajaga:
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrant.registrar %>
<%= render 'mailers/shared/signatures/signature.et.html' %>

---

Dear representative of <%= @registrant.name %>,

The Estonian Internet Foundation (EIS) has found through the Estonian business register that the company <%= @registrant.name %> with the business registry code <%= @registrant.ident %> is in liquidation proceedings. Please note that according to the .ee domain regulation, the registrant of the domain must be an existing private or legal entity. Therefore, the registry will start the registration deletion procedure once the liquidation of the company has been finalized. After the registration deletion procedure, the domain name will be open to register again for everyone.
If you want to continue to use the registered domains belonging to your company, we recommend you to prepare the transfer of the registrations to the new owner before the liquidation of the current owner will be finalized. Learn more on our website.

The following registrations belong to the company <%= @registrant.ident %> in the .ee domain register:

<% @registrant.domains.each do |domain| %>
<%= domain.name %>
<% end %>

Should you have additional questions, please contact your registrar:
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrant.registrar %>
<%= render 'mailers/shared/signatures/signature.en.html' %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<p>Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt</p>

<p>Eesti Interneti Sihtasutusele on saanud teatavaks, et juriidiline isik registrikoodiga <%= @domain.registrant.ident %> on äriregistrist kustutatud.</p>

<p>Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes 45 päevane kustutusmenetlus. Menetluse käigus on domeen 15 esimest päeva internetis kättesaadav.</p>

<p>Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus koos seda tõendava dokumendiga.</p>

<p>Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile <a href="https://auction.internet.ee">.ee oksjonikeskkonda</a>. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe <a href="https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused">siit</a>.</p>

<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
<%= render 'mailers/shared/signatures/signature.et.html' %>

<hr>

<p>Dear registrant/administrative contact of .ee domain,</p>

<p>Estonian Internet Foundation has learned that the legal person with registry code <%= @domain.registrant.ident %> has been deleted from the Business Registry.</p>

<p>As a terminated legal person cannot be the registrant of a domain, a 45-day deletion process has started for the <%= @domain.name %> domain. For the first 15 days the domain will remain available on the Internet during the deletion process.</p>

<p>The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %> with legal documentation.</p>

<p>If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the <a href="https://auction.internet.ee">.ee auction environment</a>. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">here</a>.</p>

<p>Should you have additional questions, please contact your registrar:</p>
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
<%= render 'mailers/shared/signatures/signature.en.html' %>
<hr>

<p>Уважаемый регистрант/административный контакт домена .ee</p>

<p>Целевому учреждению Eesti Internet (EIS) стало известно, что юридическое лицо с регистрационным кодом <%= @domain.registrant.ident %> удалено из коммерческого реестра.</p>

<p>Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, <%= Date.today.strftime('%d.%m.%y') %> начат 45-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении 15 дней после начала процесса удаления.</p>

<p>Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение 45 дней.</p>

<p>Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в <a href="https://auction.internet.ee">аукционной среде.ee</a>. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">здесь</a>.</p>

<p>В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %></p>

<%= render 'mailers/shared/signatures/signature.ru.html' %>
Loading

0 comments on commit d1a43ad

Please sign in to comment.