From 6ff5e55a243b5fdd4d167d23abf48fb6ba864d43 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Tue, 24 Sep 2024 15:04:02 +0300 Subject: [PATCH 01/15] business contact validation + tests --- Dockerfile | 17 ++ ai/sop/update_company_status_rake.md | 17 ++ app/interactions/actions/contact_create.rb | 11 + .../domains/force_delete/set_status.rb | 2 + app/jobs/company_register_status_job.rb | 113 +++++++++ app/mailers/contact_inform_mailer.rb | 7 + app/models/concerns/domain/force_delete.rb | 2 +- app/models/contact.rb | 1 + app/models/contact/company_register.rb | 38 +++ .../company_liquidation.html.erb | 34 +++ .../company_liquidation.text.erb | 32 +++ .../forced/invalid_company.html.erb | 45 ++++ .../forced/invalid_company.text.erb | 46 ++++ config/application.yml.sample | 4 + config/locales/en.yml | 1 + ...0154_add_checked_company_at_to_contacts.rb | 5 + ...add_company_register_status_to_contacts.rb | 5 + db/structure.sql | 132 +++++++++- ettevotja_rekvisiidid__lihtandmed.csv.zip | Bin 0 -> 225 bytes lib/tasks/company_status.rake | 209 +++++++++++++++ test/tasks/company_status_task_test.rb | 239 ++++++++++++++++++ test_data 2.csv | 2 + test_data.csv | 2 + 23 files changed, 962 insertions(+), 2 deletions(-) create mode 100644 ai/sop/update_company_status_rake.md create mode 100644 app/jobs/company_register_status_job.rb create mode 100644 app/models/contact/company_register.rb create mode 100644 app/views/mailers/contact_inform_mailer/company_liquidation.html.erb create mode 100644 app/views/mailers/contact_inform_mailer/company_liquidation.text.erb create mode 100644 app/views/mailers/domain_delete_mailer/forced/invalid_company.html.erb create mode 100644 app/views/mailers/domain_delete_mailer/forced/invalid_company.text.erb create mode 100644 db/migrate/20230710120154_add_checked_company_at_to_contacts.rb create mode 100644 db/migrate/20230711083811_add_company_register_status_to_contacts.rb create mode 100644 ettevotja_rekvisiidid__lihtandmed.csv.zip create mode 100644 lib/tasks/company_status.rake create mode 100644 test/tasks/company_status_task_test.rb create mode 100644 test_data 2.csv create mode 100644 test_data.csv diff --git a/Dockerfile b/Dockerfile index b3d32624d3..98d37d92b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/ai/sop/update_company_status_rake.md b/ai/sop/update_company_status_rake.md new file mode 100644 index 0000000000..821754b72f --- /dev/null +++ b/ai/sop/update_company_status_rake.md @@ -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 diff --git a/app/interactions/actions/contact_create.rb b/app/interactions/actions/contact_create.rb index c1b091a1fc..0793abcd2d 100644 --- a/app/interactions/actions/contact_create.rb +++ b/app/interactions/actions/contact_create.rb @@ -14,6 +14,7 @@ def call maybe_attach_legal_doc validate_ident maybe_change_email + maybe_company_is_relevant commit validate_contact end @@ -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 diff --git a/app/interactions/domains/force_delete/set_status.rb b/app/interactions/domains/force_delete/set_status.rb index b0a53ad822..770903d5a8 100644 --- a/app/interactions/domains/force_delete/set_status.rb +++ b/app/interactions/domains/force_delete/set_status.rb @@ -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 diff --git a/app/jobs/company_register_status_job.rb b/app/jobs/company_register_status_job.rb new file mode 100644 index 0000000000..b8c3107b58 --- /dev/null +++ b/app/jobs/company_register_status_job.rb @@ -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 diff --git a/app/mailers/contact_inform_mailer.rb b/app/mailers/contact_inform_mailer.rb index bf5037cbfa..cb04037686 100644 --- a/app/mailers/contact_inform_mailer.rb +++ b/app/mailers/contact_inform_mailer.rb @@ -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 diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 3fa3bf627a..e0f98ea84e 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -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' diff --git a/app/models/contact.rb b/app/models/contact.rb index 0e076155bf..b7fc85dde8 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -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' diff --git a/app/models/contact/company_register.rb b/app/models/contact/company_register.rb new file mode 100644 index 0000000000..1c436eff75 --- /dev/null +++ b/app/models/contact/company_register.rb @@ -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 diff --git a/app/views/mailers/contact_inform_mailer/company_liquidation.html.erb b/app/views/mailers/contact_inform_mailer/company_liquidation.html.erb new file mode 100644 index 0000000000..f191889b65 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/company_liquidation.html.erb @@ -0,0 +1,34 @@ +

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:

+ + +

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:

+ + +

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' %> +
diff --git a/app/views/mailers/contact_inform_mailer/company_liquidation.text.erb b/app/views/mailers/contact_inform_mailer/company_liquidation.text.erb new file mode 100644 index 0000000000..2b5134c5e0 --- /dev/null +++ b/app/views/mailers/contact_inform_mailer/company_liquidation.text.erb @@ -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' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_company.html.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_company.html.erb new file mode 100644 index 0000000000..ae7a41fb47 --- /dev/null +++ b/app/views/mailers/domain_delete_mailer/forced/invalid_company.html.erb @@ -0,0 +1,45 @@ +

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

+ +

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

+ +

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.

+ +

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

+ +

Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. 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 siit.

+ +

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.et.html' %> + +
+ +

Dear registrant/administrative contact of .ee domain,

+ +

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

+ +

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.

+ +

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.

+ +

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 .ee auction environment. 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 here.

+ +

Should you have additional questions, please contact your registrar:

+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.en.html' %> +
+ +

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

+ +

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

+ +

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

+ +

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

+ +

Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в аукционной среде.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте здесь.

+ +

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

+ +<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_company.text.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_company.text.erb new file mode 100644 index 0000000000..f3aaca27a6 --- /dev/null +++ b/app/views/mailers/domain_delete_mailer/forced/invalid_company.text.erb @@ -0,0 +1,46 @@ +

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

+ +

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

+ +

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.

+ +

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

+ +

Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. 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 siit.

+ +

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.et.html' %> + +
+ +

Dear registrant/administrative contact of .ee domain,

+ +

Estonian Internet Foundation has learned that contact(s) phone number data of the domain <%= @domain.name %> are invalid.

+

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

+ +

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.

+ +

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.

+ +

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 .ee auction environment. 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 here.

+ +

Should you have additional questions, please contact your registrar:

+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.en.html' %> +
+ +

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

+ +

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

+ +

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

+ +

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

+ +

Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в аукционной среде.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте здесь.

+ +

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

+ +<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/config/application.yml.sample b/config/application.yml.sample index 0d2fd399cd..edc5872378 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -252,3 +252,7 @@ billing_system_integrated: 'true' secret_access_word: 'please-Give-Me-accesS' secret_word: 'this-secret-should-be-change' allow_accr_endspoints: 'true' + +whitelist_companies: + - '12345678' + - '87654321' \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index e9553aa207..d3d6ec6707 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -202,6 +202,7 @@ en: invalid_cert: 'Invalid certificate' failed_epp_conn: 'Failed to open connection to EPP server!' epp_conn_error: 'CONNECTION ERROR - Is the EPP server running?' + company_not_registered: 'Company is not registered' code: 'Code' action: 'Action' diff --git a/db/migrate/20230710120154_add_checked_company_at_to_contacts.rb b/db/migrate/20230710120154_add_checked_company_at_to_contacts.rb new file mode 100644 index 0000000000..e7f9d5f1a7 --- /dev/null +++ b/db/migrate/20230710120154_add_checked_company_at_to_contacts.rb @@ -0,0 +1,5 @@ +class AddCheckedCompanyAtToContacts < ActiveRecord::Migration[6.1] + def change + add_column :contacts, :checked_company_at, :datetime + end +end diff --git a/db/migrate/20230711083811_add_company_register_status_to_contacts.rb b/db/migrate/20230711083811_add_company_register_status_to_contacts.rb new file mode 100644 index 0000000000..615151721e --- /dev/null +++ b/db/migrate/20230711083811_add_company_register_status_to_contacts.rb @@ -0,0 +1,5 @@ +class AddCompanyRegisterStatusToContacts < ActiveRecord::Migration[6.1] + def change + add_column :contacts, :company_register_status, :string + end +end diff --git a/db/structure.sql b/db/structure.sql index fc2c2df125..6b189b54c1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -692,7 +692,9 @@ CREATE TABLE public.contacts ( uuid uuid DEFAULT public.gen_random_uuid() NOT NULL, disclosed_attributes character varying[] DEFAULT '{}'::character varying[] NOT NULL, email_history character varying, - registrant_publishable boolean DEFAULT false + registrant_publishable boolean DEFAULT false, + checked_company_at timestamp without time zone, + company_register_status character varying ); @@ -1099,6 +1101,45 @@ CREATE SEQUENCE public.email_addresses_verifications_id_seq ALTER SEQUENCE public.email_addresses_verifications_id_seq OWNED BY public.email_addresses_verifications.id; +-- +-- Name: epp_logs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.epp_logs ( + id bigint NOT NULL, + request text, + response text, + request_command character varying(255), + request_object character varying, + request_successful boolean, + api_user_name character varying(255), + api_user_registrar character varying(255), + ip character varying(255), + created_at timestamp without time zone, + updated_at timestamp without time zone, + uuid character varying +); + + +-- +-- Name: epp_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.epp_logs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: epp_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.epp_logs_id_seq OWNED BY public.epp_logs.id; + + -- -- Name: epp_sessions; Type: TABLE; Schema: public; Owner: - -- @@ -2553,6 +2594,45 @@ CREATE SEQUENCE public.registrars_id_seq ALTER SEQUENCE public.registrars_id_seq OWNED BY public.registrars.id; +-- +-- Name: repp_logs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.repp_logs ( + id bigint NOT NULL, + request_path character varying(255), + request_method character varying(255), + request_params text, + response text, + response_code character varying(255), + api_user_name character varying(255), + api_user_registrar character varying(255), + ip character varying(255), + created_at timestamp without time zone, + updated_at timestamp without time zone, + uuid character varying +); + + +-- +-- Name: repp_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.repp_logs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: repp_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.repp_logs_id_seq OWNED BY public.repp_logs.id; + + -- -- Name: reserved_domains; Type: TABLE; Schema: public; Owner: - -- @@ -3061,6 +3141,13 @@ ALTER TABLE ONLY public.email_addresses_validations ALTER COLUMN id SET DEFAULT ALTER TABLE ONLY public.email_addresses_verifications ALTER COLUMN id SET DEFAULT nextval('public.email_addresses_verifications_id_seq'::regclass); +-- +-- Name: epp_logs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.epp_logs ALTER COLUMN id SET DEFAULT nextval('public.epp_logs_id_seq'::regclass); + + -- -- Name: epp_sessions id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3320,6 +3407,13 @@ ALTER TABLE ONLY public.registrant_verifications ALTER COLUMN id SET DEFAULT nex ALTER TABLE ONLY public.registrars ALTER COLUMN id SET DEFAULT nextval('public.registrars_id_seq'::regclass); +-- +-- Name: repp_logs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repp_logs ALTER COLUMN id SET DEFAULT nextval('public.repp_logs_id_seq'::regclass); + + -- -- Name: reserved_domains id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3567,6 +3661,14 @@ ALTER TABLE ONLY public.email_addresses_verifications ADD CONSTRAINT email_addresses_verifications_pkey PRIMARY KEY (id); +-- +-- Name: epp_logs epp_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.epp_logs + ADD CONSTRAINT epp_logs_pkey PRIMARY KEY (id); + + -- -- Name: epp_sessions epp_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -3863,6 +3965,14 @@ ALTER TABLE ONLY public.registrars ADD CONSTRAINT registrars_pkey PRIMARY KEY (id); +-- +-- Name: repp_logs repp_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.repp_logs + ADD CONSTRAINT repp_logs_pkey PRIMARY KEY (id); + + -- -- Name: reserved_domains reserved_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4055,6 +4165,13 @@ ALTER TABLE ONLY public.zones ADD CONSTRAINT zones_pkey PRIMARY KEY (id); +-- +-- Name: epp_logs_uuid; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX epp_logs_uuid ON public.epp_logs USING btree (uuid); + + -- -- Name: index_account_activities_on_account_id; Type: INDEX; Schema: public; Owner: - -- @@ -4755,6 +4872,13 @@ CREATE INDEX log_domains_object_legacy_id ON public.log_contacts USING btree ((( CREATE INDEX log_nameservers_object_legacy_id ON public.log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer)); +-- +-- Name: repp_logs_uuid; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX repp_logs_uuid ON public.repp_logs USING btree (uuid); + + -- -- Name: unique_data_migrations; Type: INDEX; Schema: public; Owner: - -- @@ -4992,6 +5116,7 @@ ALTER TABLE ONLY public.users SET search_path TO "$user", public; INSERT INTO "schema_migrations" (version) VALUES +('0'), ('20140616073945'), ('20140620130107'), ('20140627082711'), @@ -5470,7 +5595,12 @@ INSERT INTO "schema_migrations" (version) VALUES ('20221214073933'), ('20221214074252'), ('20230531111154'), +('20230612094319'), +('20230612094326'), +('20230612094335'), ('20230707084741'), +('20230710120154'), +('20230711083811'), ('20240816091049'), ('20240816092636'); diff --git a/ettevotja_rekvisiidid__lihtandmed.csv.zip b/ettevotja_rekvisiidid__lihtandmed.csv.zip new file mode 100644 index 0000000000000000000000000000000000000000..0e28fcb10906b8c7dbd95c1d5d6fd4f1d4b181ea GIT binary patch literal 225 zcmWIWW@Zs#U|`^22urYtl-+-Mmno2E48*EHoLW+nT9#jul^9=?nq8JzoSB)DnGzqL zlbKPHn3s~9nxdCnT;{EFO2^ChypEpcsh;!a&ih~V)YbIVJ*|Jzt4CkY(?>^B_nDE2 zk(r^X@%9UzK6)p0yq_{L1b8ztnK0wF8E82JBM>(=bkBfy)L4WyV62!nxi1&G4{ E0I_a9^8f$< literal 0 HcmV?d00001 diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake new file mode 100644 index 0000000000..87d6fadf6d --- /dev/null +++ b/lib/tasks/company_status.rake @@ -0,0 +1,209 @@ +require 'csv' +require 'open-uri' +require 'zip' +require 'net/http' +require 'uri' +require 'optparse' +require 'rake_option_parser_boilerplate' + +namespace :company_status do + # bundle exec rake company_status:check_all -- --open_data_file_path=tmp/ettevotja_rekvisiidid__lihtandmed.csv --missing_companies_output_path=tmp/missing_companies_in_business_registry.csv --deleted_companies_output_path=tmp/deleted_companies_from_business_registry.csv --download_path=https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip --soft_delete_enable=false --registrants_only=true + desc 'Get Estonian companies status from Business Registry.' + + DELETED_FROM_REGISTRY_STATUS = 'K' + DESTINATION = Rails.root.join('tmp').to_s + '/' + COMPANY_STATUS = 'ettevotja_staatus' + BUSINESS_REGISTRY_CODE = 'ariregistri_kood' + + task :check_all => :environment do + options = initialize_rake_task + + open_data_file_path = options[:open_data_file_path] + missing_companies_in_business_registry_path = options[:missing_companies_output_path] + deleted_companies_from_business_registry_path = options[:deleted_companies_output_path] + download_path = options[:download_path] + soft_delete_enable = options[:soft_delete_enable] + downloaded_filename = File.basename(URI(download_path).path) + are_registrants_only = options[:registrants_only] + + puts "*** Run 1 step. Downloading fresh open data file. ***" + remove_old_file(DESTINATION + downloaded_filename) + download_open_data_file(download_path, downloaded_filename) + unzip_file(downloaded_filename, DESTINATION) + + puts "*** Run 2 step. I am collecting data from open business registry sources. ***" + company_data = collect_company_data(open_data_file_path) + + puts "*** Run 3 step. I process companies, update their information, and sort them into different files based on whether the companies are missing or removed from the business registry ***" + + whitelisted_companies = JSON.parse(ENV['whitelist_companies']) # ["12345678", "87654321"] + + contacts_query = Contact.where(ident_type: 'org', ident_country_code: 'EE') + + if are_registrants_only + contacts_query = contacts_query.joins(:registrant_domains).distinct + end + + unique_contacts = contacts_query.to_a.uniq(&:ident) + + unique_contacts.each do |contact| + next if whitelisted_companies.include?(contact.ident) + + if company_data.key?(contact.ident) + update_company_status(contact: contact, status: company_data[contact.ident][COMPANY_STATUS]) + puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status: #{company_data[contact.ident][COMPANY_STATUS]}" + else + update_company_status(contact: contact, status: 'K') + sort_companies_to_files( + contact: contact, + missing_companies_in_business_registry_path: missing_companies_in_business_registry_path, + deleted_companies_from_business_registry_path: deleted_companies_from_business_registry_path, + soft_delete_enable: soft_delete_enable + ) + end + end + + puts '*** Done ***' + end + + private + + def initialize_rake_task + open_data_file_path = "#{DESTINATION}ettevotja_rekvisiidid__lihtandmed.csv" + missing_companies_in_business_registry_path = "#{DESTINATION}missing_companies_in_business_registry.csv" + deleted_companies_from_business_registry_path = "#{DESTINATION}deleted_companies_from_business_registry.csv" + url = 'https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip' + + options = { + open_data_file_path: open_data_file_path, + missing_companies_output_path: missing_companies_in_business_registry_path, + deleted_companies_output_path: deleted_companies_from_business_registry_path, + download_path: url, + soft_delete_enable: false, + registrants_only: false, + } + + banner = 'Usage: rake companies:check_all -- [options]' + RakeOptionParserBoilerplate.process_args(options: options, + banner: banner, + hash: companies_opts_hash) + end + + def companies_opts_hash + { + open_data_file_path: ['-o [OPEN_DATA_FILE_PATH]', '--open_data_file_path [DOMAIN_NAME]', String], + missing_companies_output_path: ['-m [MISSING_COMPANIES_OUTPUT_PATH]', '--missing_companies_output_path [MISSING_COMPANIES_OUTPUT_PATH]', String], + deleted_companies_output_path: ['-s [DELETED_COMPANIES_OUTPUT_PATH]', '--deleted_companies_output_path [DELETED_COMPANIES_OUTPUT_PATH]', String], + download_path: ['-d [DOWNLOAD_PATH]', '--download_path [DOWNLOAD_PATH]', String], + soft_delete_enable: ['-e [SOFT_DELETE_ENABLE]', '--soft_delete_enable [SOFT_DELETE_ENABLE]', FalseClass], + registrants_only: ['-r', '--registrants_only [REGISTRANTS_ONLY]', FalseClass], + } + end + + def remove_old_file(output_file_path) + FileUtils.rm(output_file_path) if File.exist?(output_file_path) + end + + + def unzip_file(filename, destination) + Zip::File.open(filename) do |zip_file| + zip_file.each do |entry| + entry.extract(File.join(destination, entry.name)) { true } + end + end + + puts "Archive invoke to #{destination}" + end + + def collect_company_data(open_data_file_path) + company_data = {} + + CSV.foreach(open_data_file_path, headers: true, col_sep: ';', quote_char: '"', liberal_parsing: true) do |row| + company_data[row[BUSINESS_REGISTRY_CODE]] = row + end + + company_data + end + + def download_open_data_file(url, filename) + uri = URI(url) + + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| + request = Net::HTTP::Get.new(uri) + response = http.request(request) + + if response.code == '200' + File.open(filename, 'wb') do |file| + file.write(response.body) + end + else + puts "Failed to download file: #{response.code} #{response.message}" + end + end + + puts "File saved as #{filename}" + end + + def update_company_status(contact:, status:) + contact.update(company_register_status: status, checked_company_at: Time.zone.now) + end + + def put_company_to_missing_file(contact:, path:) + write_to_csv_file(csv_file_path: path, headers: ["ID", "Ident", "Name", "Contact Type"], attrs: [contact.id, contact.ident, contact.name, determine_contact_type(contact)]) + end + + def sort_companies_to_files(contact:, missing_companies_in_business_registry_path:, deleted_companies_from_business_registry_path:, soft_delete_enable:) + sleep 1 + resp = contact.return_company_details + + if resp.empty? + put_company_to_missing_file(contact: contact, path: missing_companies_in_business_registry_path) + puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} is missing in registry, company id: #{contact.id}" + soft_delete_company(contact) if soft_delete_enable + else + status = resp.first.status.upcase + kandeliik_type = resp.first.kandeliik.last.last.kandeliik + kandeliik_tekstina = resp.first.kandeliik.last.last.kandeliik_tekstina + kande_kpv = resp.first.kandeliik.last.last.kande_kpv + + if status == DELETED_FROM_REGISTRY_STATUS + csv_file_path = deleted_companies_from_business_registry_path + headers = ["ID", "Ident", "Name", "Status", "Kandeliik Type", "Kandeliik Tekstina", "kande_kpv", "Contact Type"] + attrs = [contact.id, contact.ident, contact.name, status, kandeliik_type, kandeliik_tekstina, kande_kpv, determine_contact_type(contact)] + write_to_csv_file(csv_file_path: csv_file_path, headers: headers, attrs: attrs) + + puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status #{status}, company id: #{contact.id}" + soft_delete_company(contact) if soft_delete_enable + end + end + end + + def determine_contact_type(contact) + roles = [] + roles << 'Registrant' if contact.registrant_domains.any? + roles += contact.domain_contacts.pluck(:type).uniq if contact.domain_contacts.any? + roles << 'Unknown' if roles.empty? + roles.join(', ') + 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 write_to_csv_file(csv_file_path:, headers:, attrs:) + write_headers = !File.exist?(csv_file_path) + + begin + CSV.open(csv_file_path, "ab", write_headers: write_headers, headers: headers) do |csv| + csv << attrs + end + puts "Successfully wrote to CSV: #{csv_file_path}" + rescue => e + puts "Error writing to CSV: #{e.message}" + end + end +end diff --git a/test/tasks/company_status_task_test.rb b/test/tasks/company_status_task_test.rb new file mode 100644 index 0000000000..3f40df88c5 --- /dev/null +++ b/test/tasks/company_status_task_test.rb @@ -0,0 +1,239 @@ +require 'test_helper' +require 'webmock/minitest' +require 'tempfile' +require 'csv' +require 'zip' + +module CompanyStatusTaskTestOverrides + def download_open_data_file(url, filename) + uri = URI(url) + + Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| + request = Net::HTTP::Get.new(uri) + response = http.request(request) + + if response.code == '200' + File.open(filename, 'wb') do |file| + file.write(response.body) + end + else + puts "Failed to download file: #{response.code} #{response.message}" + end + end + + puts "File saved as #{filename}" + end + + def unzip_file(filename, destination) + Zip::File.open(filename) do |zip_file| + zip_file.each do |entry| + entry_path = File.join(destination, entry.name) + entry.extract(entry_path) { true } # Overwrite existing files + end + end + true + end + + def collect_company_data(open_data_file_path) + $test_options = open_data_file_path + # Return test data + { '12345678' => { 'ettevotja_staatus' => 'active' } } + end + + def update_company_status(contact:, status:) + # Do nothing + end + + def sort_companies_to_files(contact:, missing_companies_in_business_registry_path:, deleted_companies_from_business_registry_path:, soft_delete_enable:) + # Do nothing + end + + def initialize_rake_task + options = { + open_data_file_path: "#{DESTINATION}ettevotja_rekvisiidid__lihtandmed.csv", + missing_companies_output_path: "#{DESTINATION}missing_companies_in_business_registry.csv", + deleted_companies_output_path: "#{DESTINATION}deleted_companies_from_business_registry.csv", + download_path: 'https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip', + soft_delete_enable: false, + registrants_only: false, + } + + # Process command line arguments + RakeOptionParserBoilerplate.process_args( + options: options, + banner: 'Usage: rake company_status:check_all [options]', + hash: { + open_data_file_path: ['-o', '--open_data_file_path PATH', String], + missing_companies_output_path: ['-m', '--missing_companies_output_path PATH', String], + deleted_companies_output_path: ['-d', '--deleted_companies_output_path PATH', String], + download_path: ['-u', '--download_path URL', String], + soft_delete_enable: ['-s', '--soft_delete_enable', :NONE], + registrants_only: ['-r', '--registrants_only', :NONE] + } + ) + + options + end +end + +class CompanyStatusTaskTest < ActiveSupport::TestCase + include CompanyStatusTaskTestOverrides + + def setup + super # Always call super when overriding setup + + # Create temporary CSV file with test data + @temp_csv = Tempfile.new(['test_data', '.csv']) + CSV.open(@temp_csv.path, 'wb') do |csv| + csv << ['ariregistri_kood', 'ettevotja_staatus'] + csv << ['12345678', 'active'] + end + + @temp_csv_path = @temp_csv.path + $temp_csv_path = @temp_csv.path # Set the global variable + + # Create temporary zip file containing our CSV + @temp_zip = Tempfile.new(['test_data', '.zip']) + Zip::File.open(@temp_zip.path, Zip::File::CREATE) do |zipfile| + zipfile.add('ettevotja_rekvisiidid__lihtandmed.csv', @temp_csv_path) + end + + # Stub HTTP request + stub_request(:get, 'https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip') + .to_return(status: 200, body: File.read(@temp_zip.path), headers: {}) + + # Prepend the module to the main object to override methods + main = TOPLEVEL_BINDING.eval('self') + main.singleton_class.prepend(CompanyStatusTaskTestOverrides) + end + + def teardown + super # Always call super when overriding teardown + + @temp_csv.close if @temp_csv + @temp_csv.unlink if @temp_csv + @temp_zip.close if @temp_zip + @temp_zip.unlink if @temp_zip + WebMock.reset! + end + + test "initialize_rake_task sets default options correctly and handles file processing" do + stub_request(:get, 'https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip') + .to_return(status: 200, body: File.read(@temp_zip.path), headers: {}) + + ENV['whitelist_companies'] = '["12345678", "87654321"]' + $test_options = nil + + # No need to prepend again; it's already done in setup + + # Stub external dependencies + RakeOptionParserBoilerplate.stub :process_args, ->(options:, banner:, hash:) { options } do + run_task + + # Assertions + assert_not_nil $test_options, "Options should not be nil" + + expected_path = Rails.root.join('tmp', 'ettevotja_rekvisiidid__lihtandmed.csv').to_s + assert_equal expected_path, $test_options + + # Add more assertions as needed + end + + assert_requested :get, 'https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip' + end + + test "initialize_rake_task processes command line arguments" do + simulated_args = [ + '--open_data_file_path=/custom/path.csv', + '--missing_companies_output_path=/custom/missing.csv', + '--deleted_companies_output_path=/custom/deleted.csv', + '--download_path=https://example.com/custom.zip', + '--soft_delete_enable', + '--registrants_only' + ] + + # Replace ARGV with simulated arguments + original_argv = ARGV.dup + ARGV.replace(simulated_args) + + # Stub RakeOptionParserBoilerplate to process ARGV + RakeOptionParserBoilerplate.stub :process_args, ->(options:, banner:, hash:) { + OptionParser.new do |opts| + hash.each do |key, (short, long, type)| + opts.on(*[short, long, type].compact) do |value| + # Convert string 'true'/'false' to boolean if needed + if [TrueClass, FalseClass].include?(type) + value = true + end + options[key] = value + end + end + end.parse!(ARGV) + options + } do + options = initialize_rake_task + + # Assertions + assert_equal '/custom/path.csv', options[:open_data_file_path] + assert_equal '/custom/missing.csv', options[:missing_companies_output_path] + assert_equal '/custom/deleted.csv', options[:deleted_companies_output_path] + assert_equal 'https://example.com/custom.zip', options[:download_path] + assert_equal true, options[:soft_delete_enable] + assert_equal true, options[:registrants_only] + end + + # Restore ARGV + ARGV.replace(original_argv) + end + + test "download_open_data_file downloads file successfully" do + # Setup a temporary filename + temp_filename = 'test_download.zip' + + # Stub the HTTP request + stub_request(:get, 'https://example.com/test.zip') + .to_return(status: 200, body: 'Test content', headers: {}) + + # Call the actual method + download_open_data_file('https://example.com/test.zip', temp_filename) + + # Assertions + assert File.exist?(temp_filename), "File should exist after download" + assert_equal 'Test content', File.read(temp_filename) + + assert_requested :get, 'https://example.com/test.zip' + + # Cleanup + File.delete(temp_filename) if File.exist?(temp_filename) + end + + test "unzip_file extracts contents correctly" do + # Create a temporary zip file with known content + temp_zip = Tempfile.new(['test', '.zip']) + temp_dir = Dir.mktmpdir + + Zip::File.open(temp_zip.path, Zip::File::CREATE) do |zipfile| + zipfile.get_output_stream('test.txt') { |f| f.write 'Hello, world!' } + end + + # Call the method + unzip_file(temp_zip.path, temp_dir) + + # Assertions + extracted_file = File.join(temp_dir, 'test.txt') + puts "Extracted file path: #{extracted_file}" # Add debug information + puts "Directory contents: #{Dir.entries(temp_dir)}" # Add debug information + + assert File.exist?(extracted_file), "File should be extracted" + assert_equal 'Hello, world!', File.read(extracted_file) + + # Cleanup + temp_zip.close + temp_zip.unlink + FileUtils.remove_entry(temp_dir) + end + + def run_task + Rake::Task['company_status:check_all'].execute + end +end diff --git a/test_data 2.csv b/test_data 2.csv new file mode 100644 index 0000000000..25728e63df --- /dev/null +++ b/test_data 2.csv @@ -0,0 +1,2 @@ +company_code,company_name,status +12345678,Test Company,active diff --git a/test_data.csv b/test_data.csv new file mode 100644 index 0000000000..25728e63df --- /dev/null +++ b/test_data.csv @@ -0,0 +1,2 @@ +company_code,company_name,status +12345678,Test Company,active From 61497deb2a41cb107ebd4a45011817bb8e3bf263 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Tue, 24 Sep 2024 15:39:07 +0300 Subject: [PATCH 02/15] added more tests --- ettevotja_rekvisiidid__lihtandmed.csv.zip | Bin 225 -> 225 bytes .../repp/v1/contacts/create_test.rb | 69 ++++ test/jobs/company_register_status_job_test.rb | 384 ++++++++++++++++++ test/mailers/contact_inform_mailer_test.rb | 19 + test/models/contact/company_register_test.rb | 43 ++ test/test_helper.rb | 6 +- 6 files changed, 520 insertions(+), 1 deletion(-) create mode 100644 test/jobs/company_register_status_job_test.rb create mode 100644 test/mailers/contact_inform_mailer_test.rb create mode 100644 test/models/contact/company_register_test.rb diff --git a/ettevotja_rekvisiidid__lihtandmed.csv.zip b/ettevotja_rekvisiidid__lihtandmed.csv.zip index 0e28fcb10906b8c7dbd95c1d5d6fd4f1d4b181ea..5189a5e6c0070fc25085baf8dce5814893a5e3ae 100644 GIT binary patch delta 26 gcmaFJ_>hq&z?+#xgn@y9gFz)_B2NVqkZg+v08fktC;$Ke delta 26 gcmaFJ_>hq&z?+#xgn@y9gCQ(oB2NVqkZg+v08(@Yga7~l diff --git a/test/integration/repp/v1/contacts/create_test.rb b/test/integration/repp/v1/contacts/create_test.rb index b9eda19c19..aa252ddca0 100644 --- a/test/integration/repp/v1/contacts/create_test.rb +++ b/test/integration/repp/v1/contacts/create_test.rb @@ -1,10 +1,13 @@ require 'test_helper' +Company = Struct.new(:registration_number, :company_name, :status) + class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest def setup @user = users(:api_bestnames) token = Base64.encode64("#{@user.username}:#{@user.plain_text_password}") token = "Basic #{token}" + @company_register_stub = CompanyRegister::Client.new @auth_headers = { 'Authorization' => token } @@ -184,4 +187,70 @@ def test_returns_error_response_if_throttled ENV['shunter_default_threshold'] = '10000' ENV['shunter_enabled'] = 'false' end + + def test_returns_error_response_if_company_not_existed + original_new_method = CompanyRegister::Client.method(:new) + CompanyRegister::Client.define_singleton_method(:new) do + object = original_new_method.call + def object.simple_data(registration_number:) + [Company.new('1234567', 'ACME Ltd', 'K')] + end + object + end + + request_body = { + "contact": { + "name": 'Donald Trump', + "phone": '+372.51111112', + "email": 'donald@trumptower.com', + "ident": { + "ident_type": 'org', + "ident_country_code": 'EE', + "ident": '70000313', + }, + }, + } + + post '/repp/v1/contacts', headers: @auth_headers, params: request_body + json = JSON.parse(response.body, symbolize_names: true) + + assert_response :bad_request + assert_equal 2003, json[:code] + puts json[:message] + assert json[:message].include? 'Company is not registered' + + CompanyRegister::Client.define_singleton_method(:new, original_new_method) + end + + def test_contact_created_with_existed_company + original_new_method = CompanyRegister::Client.method(:new) + CompanyRegister::Client.define_singleton_method(:new) do + object = original_new_method.call + def object.simple_data(registration_number:) + [Company.new('1234567', 'ACME Ltd', 'R')] + end + object + end + + request_body = { + "contact": { + "name": 'Donald Trump', + "phone": '+372.51111112', + "email": 'donald@trumptower.com', + "ident": { + "ident_type": 'org', + "ident_country_code": 'EE', + "ident": '70000313', + }, + }, + } + + post '/repp/v1/contacts', headers: @auth_headers, params: request_body + json = JSON.parse(response.body, symbolize_names: true) + + assert_response :ok + assert_equal 1000, json[:code] + + CompanyRegister::Client.define_singleton_method(:new, original_new_method) + end end diff --git a/test/jobs/company_register_status_job_test.rb b/test/jobs/company_register_status_job_test.rb new file mode 100644 index 0000000000..363b8ed46f --- /dev/null +++ b/test/jobs/company_register_status_job_test.rb @@ -0,0 +1,384 @@ +require "test_helper" + +Company = Struct.new(:registration_number, :company_name, :status) + +class CompanyRegisterStatusJobTest < ActiveSupport::TestCase + include ActionMailer::TestHelper + + REGISTERED = 'R' + LIQUIDATED = 'L' + BANKRUPT = 'N' + DELETED = 'K' + + setup do + @registrant_acme = contacts(:acme_ltd).becomes(Registrant) + @registrant_jack = contacts(:jack).becomes(Registrant) + @registrant_william = contacts(:william).becomes(Registrant) + + contact = contacts(:john) + @registrant = contact.becomes(Registrant) + end + + def test_if_company_wasn_not_checked_before_it_should_be_checked + original_new_method = CompanyRegister::Client.method(:new) + CompanyRegister::Client.define_singleton_method(:new) do + object = original_new_method.call + def object.simple_data(registration_number:) + [Company.new('1234567', 'ACME Ltd', REGISTERED)] + end + object + end + + @registrant_acme.update!(company_register_status: nil, checked_company_at: nil, ident_type: 'org', ident_country_code: 'EE', ident: '16752073') + @registrant_jack.update!(company_register_status: nil, checked_company_at: nil, ident_type: 'org', ident_country_code: 'EE', ident: '14112620') + + @registrant_acme.reload && @registrant_jack.reload + + assert_nil @registrant_acme.checked_company_at + assert_nil @registrant_acme.company_register_status + assert_nil @registrant_jack.checked_company_at + assert_nil @registrant_jack.company_register_status + + CompanyRegisterStatusJob.perform_now(14, 0, 100) + + @registrant_acme.reload && @registrant_jack.reload + + assert_not_nil @registrant_acme.checked_company_at + assert_not_nil @registrant_acme.company_register_status + assert_not_nil @registrant_jack.checked_company_at + assert_not_nil @registrant_jack.company_register_status + + CompanyRegister::Client.define_singleton_method(:new, original_new_method) + end + + def test_companies_what_was_checked_before_specific_days_should_be_not_checked + end + + def test_companies_from_other_countries_are_skipped + end + + def test_companies_what_was_checked_before_specific_days_should_be_checked + end + + def test_companies_with_force_delete_and_status_R_should_be_lifted + end + + def test_companies_with_status_L_should_be_inform_by_email + end + + def test_companies_with_status_N_should_be_scheduled_for_force_delete + end + + def test_companies_with_status_K_should_be_scheduled_for_force_delete + end + + def test_company_information_what_was_not_found_in_register_should_be_deleted + end + + # def test_contact_who_never_checked_before + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', REGISTERED)] + # end + # object + # end + + # @registrant_acme.update!(company_register_status: nil, checked_company_at: nil) + # @registrant_jack.update!(company_register_status: nil, checked_company_at: nil) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_nil @registrant_acme.checked_company_at + # assert_nil @registrant_acme.company_register_status + # assert_nil @registrant_jack.checked_company_at + # assert_nil @registrant_jack.company_register_status + + # CompanyRegisterStatusJob.perform_now(14, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_not_nil @registrant_acme.checked_company_at + # assert_not_nil @registrant_acme.company_register_status + # assert_not_nil @registrant_jack.checked_company_at + # assert_not_nil @registrant_jack.company_register_status + + # CompanyRegister::Client.define_singleton_method(:new, original_new_method) + # end + + # def test_contact_who_was_checked_some_days_ago + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', REGISTERED)] + # end + # object + # end + + # interval_days = 14 + # current_time = Time.zone.now + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - (interval_days.days + 1.day)) + # @registrant_jack.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - (interval_days.days + 2.days)) + + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::REGISTERED, @registrant_acme.company_register_status + # assert_equal Contact::REGISTERED, @registrant_jack.company_register_status + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + # assert_equal current_time.to_date, @registrant_jack.checked_company_at.to_date + + # CompanyRegister::Client.define_singleton_method(:new, original_new_method) + # end + + # def test_it_should_not_check_contact_what_days_limit_not_reached + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', REGISTERED)] + # end + # object + # end + + # interval_days = 14 + # current_time = Time.zone.now + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - (interval_days.days - 1.day)) + # @registrant_jack.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - (interval_days.days - 2.days)) + + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal (current_time - (interval_days.days - 1.day)).to_date, @registrant_acme.checked_company_at.to_date + # assert_equal (current_time - (interval_days.days - 2.days)).to_date, @registrant_jack.checked_company_at.to_date + + # CompanyRegister::Client.define_singleton_method(:new, original_new_method) + # end + + # def test_contacts_who_has_liquidated_company_status + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', LIQUIDATED)] + # end + # object + # end + + # interval_days = 5 + # current_time = Time.zone.now + + # @registrant_acme.update!(company_register_status: Contact::LIQUIDATED, checked_company_at: current_time - interval_days.days) + # @registrant_jack.update!(company_register_status: Contact::LIQUIDATED, checked_company_at: current_time - (interval_days.days + 2.days)) + + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::LIQUIDATED, @registrant_acme.company_register_status + # assert_equal Contact::LIQUIDATED, @registrant_jack.company_register_status + + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + # assert_equal current_time.to_date, @registrant_jack.checked_company_at.to_date + + # CompanyRegister::Client.define_singleton_method(:new, original_new_method) + # end + + # def test_liquided_and_registered_companies + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', LIQUIDATED)] + # end + # object + # end + + # interval_days = 5 + # current_time = Time.zone.now + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - interval_days.days) + # @registrant_jack.update!(company_register_status: Contact::LIQUIDATED, checked_company_at: current_time - 2.days) + + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::LIQUIDATED, @registrant_acme.company_register_status + # assert_equal Contact::LIQUIDATED, @registrant_jack.company_register_status + + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + # assert_equal current_time.to_date, @registrant_jack.checked_company_at.to_date + + # CompanyRegister::Client.define_singleton_method(:new, original_new_method) + # end + + # def test_put_force_delete_for_bankroupted_companies + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', BANKRUPT)] + # end + # object + # end + + # interval_days = 5 + # current_time = Time.zone.now + + # refute @registrant_acme.domains.any?(&:force_delete_scheduled?) + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - interval_days.days) + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::BANKRUPT, @registrant_acme.company_register_status + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + + # assert @registrant_acme.domains.all?(&:force_delete_scheduled?) + # end + + # def test_puts_force_delete_for_deleted_companies + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', DELETED)] + # end + # object + # end + + # interval_days = 5 + # current_time = Time.zone.now + + # refute @registrant_acme.domains.any?(&:force_delete_scheduled?) + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - interval_days.days) + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::DELETED, @registrant_acme.company_register_status + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + + # assert @registrant_acme.domains.all?(&:force_delete_scheduled?) + # end + + # def test_should_inform_contact_by_email_if_force_delete_has_been_set + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', DELETED)] + # end + # object + # end + + # ActionMailer::Base.deliveries.clear + # assert_emails 0 + + # interval_days = 5 + # current_time = Time.zone.now + + # refute @registrant_acme.domains.any?(&:force_delete_scheduled?) + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - interval_days.days) + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::DELETED, @registrant_acme.company_register_status + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + + # assert @registrant_acme.domains.all?(&:force_delete_scheduled?) + + # assert_emails 4 + # end + + # def test_should_inform_contact_by_poll_message_if_force_delete_has_been_set + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', DELETED)] + # end + # object + # end + + # @registrant_acme.registrar.notifications.destroy_all && @registrant_acme.reload + # assert_equal @registrant_acme.registrar.notifications.count, 0 + + # interval_days = 5 + # current_time = Time.zone.now + + # refute @registrant_acme.domains.any?(&:force_delete_scheduled?) + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - interval_days.days) + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::DELETED, @registrant_acme.company_register_status + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + + # assert @registrant_acme.domains.all?(&:force_delete_scheduled?) + + # assert_equal @registrant_acme.registrar.notifications.count, 2 + # end + + # def test_should_inform_contact_if_his_company_in_liquadation + # original_new_method = CompanyRegister::Client.method(:new) + # CompanyRegister::Client.define_singleton_method(:new) do + # object = original_new_method.call + # def object.simple_data(registration_number:) + # [Company.new('1234567', 'ACME Ltd', LIQUIDATED)] + # end + # object + # end + + # ActionMailer::Base.deliveries.clear + # assert_emails 0 + + # interval_days = 5 + # current_time = Time.zone.now + + # @registrant_acme.update!(company_register_status: Contact::REGISTERED, checked_company_at: current_time - interval_days.days) + # @registrant_acme.reload && @registrant_jack.reload + + # CompanyRegisterStatusJob.perform_now(interval_days, 0, 100, true) + + # @registrant_acme.reload && @registrant_jack.reload + + # assert_equal Contact::LIQUIDATED, @registrant_acme.company_register_status + # assert_equal current_time.to_date, @registrant_acme.checked_company_at.to_date + + # mail = ActionMailer::Base.deliveries.first + # mail_html = Nokogiri::HTML(mail.html_part.body.decoded) + # text = mail_html.css('p')[1].text + + # assert_equal text, "Eesti Interneti Sihtasutusele (EIS) on äriregistri vahendusel teatavaks saanud, et ettevõtte #{@registrant_jack.name} äriregistrikoodiga #{@registrant_jack.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." + # end +end diff --git a/test/mailers/contact_inform_mailer_test.rb b/test/mailers/contact_inform_mailer_test.rb new file mode 100644 index 0000000000..37e6578925 --- /dev/null +++ b/test/mailers/contact_inform_mailer_test.rb @@ -0,0 +1,19 @@ +require 'test_helper' + +class ContactInformMailerTest < ActionMailer::TestCase + setup do + @contact = contacts(:john) + end + + def test_liquidation_email + assert_equal 'john-001', @contact.code + assert_equal 'john@inbox.test', @contact.email + + email = ContactInformMailer.company_liquidation(contact: @contact).deliver_now + + assert_emails 1 + + assert_equal %w[john@inbox.test], email.to + assert_equal 'Kas soovite oma .ee domeeni säilitada? / Do you wish to preserve your .ee registration?', email.subject + end +end diff --git a/test/models/contact/company_register_test.rb b/test/models/contact/company_register_test.rb new file mode 100644 index 0000000000..7b43d4b6ed --- /dev/null +++ b/test/models/contact/company_register_test.rb @@ -0,0 +1,43 @@ +require 'test_helper' + +Company = Struct.new(:registration_number, :company_name, :status) + +class CompanyRegisterTest < ActiveSupport::TestCase + def setup + @acme_ltd = contacts(:acme_ltd) + @john = contacts(:john) + @company_register_stub = CompanyRegister::Client.new + end + + def test_return_company_status + original_new_method = CompanyRegister::Client.method(:new) + CompanyRegister::Client.define_singleton_method(:new) do + object = original_new_method.call + def object.simple_data(registration_number:) + [Company.new('1234567', 'ACME Ltd', 'R')] + end + object + end + + assert_equal Contact::CompanyRegister::REGISTERED.downcase, @acme_ltd.return_company_status.downcase + + CompanyRegister::Client.define_singleton_method(:new, original_new_method) + end + + def test_return_company_data + assert_equal 'ACME Ltd', @acme_ltd.return_company_data.first[:company_name] + assert_equal '1234567', @acme_ltd.return_company_data.first[:registration_number] + end + + def test_only_org_can_be_checked + assert_nil @john.return_company_status + end + + def test_should_return_liquided_value + @company_register_stub.stub :simple_data, [Company.new('1234567', 'ACME Ltd', 'L')] do + @acme_ltd.stub :company_register, @company_register_stub do + assert_equal Contact::CompanyRegister::LIQUIDATED.downcase, @acme_ltd.return_company_status.downcase + end + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 3f1989c02d..9cfe2b8df0 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -33,11 +33,15 @@ ActiveJob::Base.queue_adapter = :test class CompanyRegisterClientStub - Company = Struct.new(:registration_number, :company_name) + Company = Struct.new(:registration_number, :company_name, :status) def representation_rights(citizen_personal_code:, citizen_country_code:) [Company.new('1234567', 'ACME Ltd')] end + + def simple_data(registration_number:) + [Company.new('1234567', 'ACME Ltd', 'R')] + end end CompanyRegister::Client = CompanyRegisterClientStub From a13ef336288621c264d1fdd9b43a955715de53c3 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Wed, 25 Sep 2024 11:22:17 +0300 Subject: [PATCH 03/15] fixed method for check force delete --- Gemfile | 2 +- Gemfile.lock | 75 ++++++++++++++++--------- app/jobs/company_register_status_job.rb | 5 +- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/Gemfile b/Gemfile index a3e57665fc..bb467a35d0 100644 --- a/Gemfile +++ b/Gemfile @@ -69,7 +69,7 @@ gem 'redis' gem 'sidekiq', '~> 7.0' gem 'company_register', github: 'internetee/company_register', - branch: 'master' + branch: '4-check-for-company-existence' gem 'domain_name' gem 'e_invoice', github: 'internetee/e_invoice', branch: :master gem 'haml', '~> 6.0' diff --git a/Gemfile.lock b/Gemfile.lock index ff13b65890..0f155855a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GIT remote: https://github.com/internetee/company_register.git - revision: 4181b2fff9080e2d87d15612561131f9e3fdfb4c - branch: master + revision: 6465d5c49478b9de5a5fa009cb6b8123b3956dd1 + branch: 4-check-for-company-existence specs: company_register (0.1.0) activesupport @@ -139,14 +139,15 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.1) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) aes_key_wrap (1.1.0) airbrake (11.0.3) airbrake-ruby (~> 5.1) airbrake-ruby (5.2.0) rbtree3 (~> 0.5) - akami (1.3.1) + akami (1.3.3) + base64 gyoku (>= 0.4.0) nokogiri apipie-rails (0.6.0) @@ -167,14 +168,16 @@ GEM aws-sigv4 (~> 1.1) aws-sigv4 (1.2.4) aws-eventstream (~> 1, >= 1.0.2) + base64 (0.2.0) bcrypt (3.1.16) + bigdecimal (3.1.8) bindata (2.4.14) bootsnap (1.17.1) msgpack (~> 1.2) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) - builder (3.2.4) + builder (3.3.0) cancancan (3.3.0) capybara (3.35.3) addressable @@ -194,7 +197,7 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) countries (4.0.1) i18n_data (~> 0.13.0) @@ -246,8 +249,9 @@ GEM grpc (1.60.0-x86_64-linux) google-protobuf (~> 3.25) googleapis-common-protos-types (~> 1.0) - gyoku (1.3.1) + gyoku (1.4.0) builder (>= 2.1.2) + rexml (~> 3.0) haml (6.0.0) temple (>= 0.8.2) thor @@ -259,10 +263,12 @@ GEM http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) - httpi (2.4.5) - rack - socksify - i18n (1.14.5) + httpi (4.0.4) + base64 + mutex_m + nkf + rack (>= 2.0, < 4) + i18n (1.14.6) concurrent-ruby (~> 1.0) i18n_data (0.13.0) isikukood (0.1.2) @@ -310,8 +316,8 @@ GEM nokogiri (~> 1) rake mini_mime (1.1.5) - mini_portile2 (2.8.6) - minitest (5.18.1) + mini_portile2 (2.8.7) + minitest (5.25.1) minitest-stub_any_instance (1.0.3) monetize (1.9.4) money (~> 6.12) @@ -323,9 +329,13 @@ GEM money (~> 6.13.2) railties (>= 3.0) msgpack (1.7.2) +<<<<<<< HEAD net-ftp (0.3.7) net-protocol time +======= + mutex_m (0.2.0) +>>>>>>> 5f9bc1f5e (fixed method for check force delete) net-protocol (0.1.3) timeout net-smtp (0.3.3) @@ -336,12 +346,14 @@ GEM newrelic_rpm (= 8.1.0) newrelic_rpm (8.1.0) nio4r (2.5.9) - nokogiri (1.16.5) + nkf (0.2.0) + nokogiri (1.16.7) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.16.5-x86_64-linux) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) - nori (2.6.0) + nori (2.7.1) + bigdecimal omniauth (2.1.0) hashie (>= 3.4.6) rack (>= 2.2.3) @@ -373,11 +385,16 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) +<<<<<<< HEAD public_suffix (5.0.0) puma (5.6.9) +======= + public_suffix (6.0.1) + puma (5.6.8) +>>>>>>> 5f9bc1f5e (fixed method for check force delete) nio4r (~> 2.0) - racc (1.7.3) - rack (2.2.8.1) + racc (1.8.1) + rack (2.2.9) rack-oauth2 (1.21.3) activesupport attr_required @@ -449,14 +466,15 @@ GEM sprockets (> 3.0) sprockets-rails tilt - savon (2.12.1) + savon (2.15.1) akami (~> 1.2) builder (>= 2.1.2) gyoku (~> 1.2) - httpi (~> 2.3) + httpi (>= 4, < 5) + mail (~> 2.5) nokogiri (>= 1.8.1) nori (~> 2.4) - wasabi (~> 3.4) + wasabi (>= 3.7, < 6) select2-rails (4.0.13) selectize-rails (0.12.6) selenium-webdriver (3.142.7) @@ -474,7 +492,6 @@ GEM simplecov-html (0.10.2) simpleidn (0.2.3) sixarm_ruby_unaccent (1.2.0) - socksify (1.7.1) sprockets (4.0.3) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -515,10 +532,10 @@ GEM simpleidn warden (1.2.9) rack (>= 2.0.9) - wasabi (3.6.1) + wasabi (5.0.3) addressable - httpi (~> 2.0) - nokogiri (>= 1.4.2) + faraday (>= 1.9, < 3) + nokogiri (>= 1.13.9) webfinger (1.2.0) activesupport httpclient (>= 2.4) @@ -534,7 +551,7 @@ GEM wkhtmltopdf-binary (0.12.6.6) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.13) + zeitwerk (2.6.18) PLATFORMS ruby @@ -611,4 +628,8 @@ DEPENDENCIES wkhtmltopdf-binary (~> 0.12.6.1) BUNDLED WITH +<<<<<<< HEAD 2.5.15 +======= + 2.5.19 +>>>>>>> 5f9bc1f5e (fixed method for check force delete) diff --git a/app/jobs/company_register_status_job.rb b/app/jobs/company_register_status_job.rb index b8c3107b58..36b292cbfe 100644 --- a/app/jobs/company_register_status_job.rb +++ b/app/jobs/company_register_status_job.rb @@ -51,7 +51,7 @@ def update_validation_company_status(contact:, status:) def schedule_force_delete(contact) contact.domains.each do |domain| - next if domain.schedule_force_delete? + next if domain.force_delete_scheduled? domain.schedule_force_delete( type: :fast_track, @@ -64,7 +64,7 @@ def schedule_force_delete(contact) 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? + domain.force_delete_scheduled? end end @@ -77,6 +77,7 @@ def delete_process(contact) if company_details_response.empty? schedule_force_delete(contact) + return end From 487c600b11c765f14a49d5ed0c27d4c9687d5e0d Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Thu, 26 Sep 2024 14:16:57 +0300 Subject: [PATCH 04/15] change iterator and added logs --- .gitignore | 1 + ettevotja_rekvisiidid__lihtandmed.csv.zip | Bin 225 -> 0 bytes lib/tasks/company_status.rake | 11 +++++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) delete mode 100644 ettevotja_rekvisiidid__lihtandmed.csv.zip diff --git a/.gitignore b/.gitignore index 6b81c1a7e0..523cb5a8c7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ .DS_Store /node_modules /import +ettevotja_rekvisiidid__lihtandmed.csv.zip diff --git a/ettevotja_rekvisiidid__lihtandmed.csv.zip b/ettevotja_rekvisiidid__lihtandmed.csv.zip deleted file mode 100644 index 5189a5e6c0070fc25085baf8dce5814893a5e3ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmWIWW@Zs#U|`^2P)V_fl-+-Mmno2E48*EHoLW+nT9#jul^9=?nq8JzoSB)DnGzqL zlbKPHn3s~9nxdCnT;{EFO2^ChypEpcsh;!a&ih~V)YbIVJ*|Jzt4CkY(?>^B_nDE2 zk(r^X@%9UzK6)p0yq_{L1b8ztnK0wF8E82JBM>(=bkBfy)L4WyV62!nxi1&G4{ E0D2BSmjD0& diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index 87d6fadf6d..924f2fa219 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -187,11 +187,18 @@ namespace :company_status do end def soft_delete_company(contact) - contact.domains.reject { |domain| domain.force_delete_scheduled? }.each do |domain| + # contact.domains.reject { |domain| domain.force_delete_scheduled? }.each do |domain| + # domain.schedule_force_delete(type: :soft) + # end + # + + contact.domains.each do |domain| + next if domain.force_delete_scheduled? + domain.schedule_force_delete(type: :soft) + puts "Soft delete process initiated for company: #{contact.name} with ID: #{contact.id} domain: #{domain.name}" end - puts "Soft delete process initiated for company: #{contact.name} with ID: #{contact.id}" end def write_to_csv_file(csv_file_path:, headers:, attrs:) From 44958c79bb833dea82147567cbac12fd24f2e23b Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Thu, 26 Sep 2024 15:13:04 +0300 Subject: [PATCH 05/15] added sleep delay configurable --- config/application.yml.sample | 4 +++- lib/tasks/company_status.rake | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/application.yml.sample b/config/application.yml.sample index edc5872378..1fae6d98b3 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -255,4 +255,6 @@ allow_accr_endspoints: 'true' whitelist_companies: - '12345678' - - '87654321' \ No newline at end of file + - '87654321' + +business_registry_sleep_time: 4 \ No newline at end of file diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index 924f2fa219..fd3c16eb0d 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -153,7 +153,7 @@ namespace :company_status do end def sort_companies_to_files(contact:, missing_companies_in_business_registry_path:, deleted_companies_from_business_registry_path:, soft_delete_enable:) - sleep 1 + sleep ENV['business_registry_sleep_time'].present? ? ENV['business_registry_sleep_time'].to_i : 2 resp = contact.return_company_details if resp.empty? From 468e9e829f50da4b0f0ba1e5f0b33e485b8ec4b9 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Thu, 26 Sep 2024 15:18:45 +0300 Subject: [PATCH 06/15] added sleep delay flag --- config/application.yml.sample | 2 -- lib/tasks/company_status.rake | 15 +++++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/config/application.yml.sample b/config/application.yml.sample index 1fae6d98b3..91f6d09b03 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -256,5 +256,3 @@ allow_accr_endspoints: 'true' whitelist_companies: - '12345678' - '87654321' - -business_registry_sleep_time: 4 \ No newline at end of file diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index fd3c16eb0d..abb93b5848 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -7,7 +7,7 @@ require 'optparse' require 'rake_option_parser_boilerplate' namespace :company_status do - # bundle exec rake company_status:check_all -- --open_data_file_path=tmp/ettevotja_rekvisiidid__lihtandmed.csv --missing_companies_output_path=tmp/missing_companies_in_business_registry.csv --deleted_companies_output_path=tmp/deleted_companies_from_business_registry.csv --download_path=https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip --soft_delete_enable=false --registrants_only=true + # bundle exec rake company_status:check_all -- --open_data_file_path=tmp/ettevotja_rekvisiidid__lihtandmed.csv --missing_companies_output_path=tmp/missing_companies_in_business_registry.csv --deleted_companies_output_path=tmp/deleted_companies_from_business_registry.csv --download_path=https://avaandmed.ariregister.rik.ee/sites/default/files/avaandmed/ettevotja_rekvisiidid__lihtandmed.csv.zip --soft_delete_enable=false --sleep_time=4 --registrants_only=true desc 'Get Estonian companies status from Business Registry.' DELETED_FROM_REGISTRY_STATUS = 'K' @@ -25,6 +25,7 @@ namespace :company_status do soft_delete_enable = options[:soft_delete_enable] downloaded_filename = File.basename(URI(download_path).path) are_registrants_only = options[:registrants_only] + sleep_time = options[:sleep_time] puts "*** Run 1 step. Downloading fresh open data file. ***" remove_old_file(DESTINATION + downloaded_filename) @@ -58,7 +59,8 @@ namespace :company_status do contact: contact, missing_companies_in_business_registry_path: missing_companies_in_business_registry_path, deleted_companies_from_business_registry_path: deleted_companies_from_business_registry_path, - soft_delete_enable: soft_delete_enable + soft_delete_enable: soft_delete_enable, + sleep_time: sleep_time ) end end @@ -81,6 +83,7 @@ namespace :company_status do download_path: url, soft_delete_enable: false, registrants_only: false, + sleep_time: 2, } banner = 'Usage: rake companies:check_all -- [options]' @@ -97,6 +100,7 @@ namespace :company_status do download_path: ['-d [DOWNLOAD_PATH]', '--download_path [DOWNLOAD_PATH]', String], soft_delete_enable: ['-e [SOFT_DELETE_ENABLE]', '--soft_delete_enable [SOFT_DELETE_ENABLE]', FalseClass], registrants_only: ['-r', '--registrants_only [REGISTRANTS_ONLY]', FalseClass], + sleep_time: ['-s', '--sleep_time [SLEEP_TIME]', Integer], } end @@ -152,8 +156,11 @@ namespace :company_status do write_to_csv_file(csv_file_path: path, headers: ["ID", "Ident", "Name", "Contact Type"], attrs: [contact.id, contact.ident, contact.name, determine_contact_type(contact)]) end - def sort_companies_to_files(contact:, missing_companies_in_business_registry_path:, deleted_companies_from_business_registry_path:, soft_delete_enable:) - sleep ENV['business_registry_sleep_time'].present? ? ENV['business_registry_sleep_time'].to_i : 2 + def sort_companies_to_files(contact:, missing_companies_in_business_registry_path:, deleted_companies_from_business_registry_path:, soft_delete_enable:, sleep_time:) + sleep sleep_time + puts "Sleeping for #{sleep_time} seconds" + + resp = contact.return_company_details if resp.empty? From 6b1a62cf2c6b218b86aebe3755ef03752ea3c918 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Thu, 26 Sep 2024 15:39:48 +0300 Subject: [PATCH 07/15] test: remove force delete enable --- lib/tasks/company_status.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index abb93b5848..f3970f7ea3 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -166,7 +166,7 @@ namespace :company_status do if resp.empty? put_company_to_missing_file(contact: contact, path: missing_companies_in_business_registry_path) puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} is missing in registry, company id: #{contact.id}" - soft_delete_company(contact) if soft_delete_enable + soft_delete_company(contact) else status = resp.first.status.upcase kandeliik_type = resp.first.kandeliik.last.last.kandeliik @@ -180,7 +180,7 @@ namespace :company_status do write_to_csv_file(csv_file_path: csv_file_path, headers: headers, attrs: attrs) puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status #{status}, company id: #{contact.id}" - soft_delete_company(contact) if soft_delete_enable + soft_delete_company(contact) end end end From b3ac165bd39b87ed2a5a028b8bfdff7fd194a1e5 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Fri, 27 Sep 2024 10:20:16 +0300 Subject: [PATCH 08/15] added logs --- .../domains/force_delete/post_set_process.rb | 2 ++ .../domains/force_delete/set_force_delete.rb | 1 + app/models/concerns/domain/force_delete.rb | 1 + lib/tasks/company_status.rake | 11 +++++++++-- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/interactions/domains/force_delete/post_set_process.rb b/app/interactions/domains/force_delete/post_set_process.rb index 4b0f618ade..a4b24eb817 100644 --- a/app/interactions/domains/force_delete/post_set_process.rb +++ b/app/interactions/domains/force_delete/post_set_process.rb @@ -11,6 +11,8 @@ def execute # Allow deletion statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED) + + puts "Try to save domain: #{domain.name} with statuses: #{statuses}" domain.save(validate: false) end end diff --git a/app/interactions/domains/force_delete/set_force_delete.rb b/app/interactions/domains/force_delete/set_force_delete.rb index f7cde0cc38..5ff94fe90d 100644 --- a/app/interactions/domains/force_delete/set_force_delete.rb +++ b/app/interactions/domains/force_delete/set_force_delete.rb @@ -9,6 +9,7 @@ def execute compose(NotifyRegistrar, inputs.to_h) compose(NotifyByEmail, inputs.to_h) compose(NotifyMultiyearsExpirationDomain, inputs.to_h) + puts "SetForceDelete has been executed" end end end diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index e0f98ea84e..5a68013fc5 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -48,6 +48,7 @@ def force_delete_scheduled? end def schedule_force_delete(type: :fast_track, notify_by_email: false, reason: nil, email: nil) + puts "Schedule force delete for domain: #{name} with type: #{type}" Domains::ForceDelete::SetForceDelete.run(domain: self, type: type, reason: reason, notify_by_email: notify_by_email, email: email) end diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index f3970f7ea3..5b341ed31f 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -27,6 +27,8 @@ namespace :company_status do are_registrants_only = options[:registrants_only] sleep_time = options[:sleep_time] + puts "SOFT DELETE ENABLE: #{soft_delete_enable}" + puts "*** Run 1 step. Downloading fresh open data file. ***" remove_old_file(DESTINATION + downloaded_filename) download_open_data_file(download_path, downloaded_filename) @@ -166,7 +168,7 @@ namespace :company_status do if resp.empty? put_company_to_missing_file(contact: contact, path: missing_companies_in_business_registry_path) puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} is missing in registry, company id: #{contact.id}" - soft_delete_company(contact) + soft_delete_company(contact) if soft_delete_enable else status = resp.first.status.upcase kandeliik_type = resp.first.kandeliik.last.last.kandeliik @@ -180,7 +182,7 @@ namespace :company_status do write_to_csv_file(csv_file_path: csv_file_path, headers: headers, attrs: attrs) puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status #{status}, company id: #{contact.id}" - soft_delete_company(contact) + soft_delete_company(contact) if soft_delete_enable end end end @@ -198,10 +200,15 @@ namespace :company_status do # domain.schedule_force_delete(type: :soft) # end # + + puts "Try to set soft delete for company: #{contact.name} with ID: #{contact.id}" + puts "Contact domains: #{contact.domains.map(&:name)}" contact.domains.each do |domain| + puts "Domain: #{domain.name} with force delete scheduled: #{domain.force_delete_scheduled?}" next if domain.force_delete_scheduled? + puts "Try to set soft delete for domain: #{domain.name}" domain.schedule_force_delete(type: :soft) puts "Soft delete process initiated for company: #{contact.name} with ID: #{contact.id} domain: #{domain.name}" end From 6f8a4a478f0724f333e92c4dc6ce31f93cdf0d6b Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Fri, 27 Sep 2024 11:14:08 +0300 Subject: [PATCH 09/15] change contact domains method --- lib/tasks/company_status.rake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index 5b341ed31f..638cf91525 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -162,7 +162,6 @@ namespace :company_status do sleep sleep_time puts "Sleeping for #{sleep_time} seconds" - resp = contact.return_company_details if resp.empty? @@ -202,9 +201,9 @@ namespace :company_status do # puts "Try to set soft delete for company: #{contact.name} with ID: #{contact.id}" - puts "Contact domains: #{contact.domains.map(&:name)}" + puts "Contact (registrant) domains: #{contact.registrant_domains.map(&:name)}" - contact.domains.each do |domain| + contact.registrant_domains.each do |domain| puts "Domain: #{domain.name} with force delete scheduled: #{domain.force_delete_scheduled?}" next if domain.force_delete_scheduled? From ba9aeb437dd6be6fc56334a704fdc4e1e702dc33 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Fri, 27 Sep 2024 14:05:05 +0300 Subject: [PATCH 10/15] remove logs, fixed company register status job --- .../domains/force_delete/set_force_delete.rb | 1 - app/jobs/company_register_status_job.rb | 8 ++++---- app/models/concerns/domain/force_delete.rb | 1 - app/models/contact.rb | 3 --- app/models/domain.rb | 2 ++ lib/tasks/company_status.rake | 10 ---------- 6 files changed, 6 insertions(+), 19 deletions(-) diff --git a/app/interactions/domains/force_delete/set_force_delete.rb b/app/interactions/domains/force_delete/set_force_delete.rb index 5ff94fe90d..f7cde0cc38 100644 --- a/app/interactions/domains/force_delete/set_force_delete.rb +++ b/app/interactions/domains/force_delete/set_force_delete.rb @@ -9,7 +9,6 @@ def execute compose(NotifyRegistrar, inputs.to_h) compose(NotifyByEmail, inputs.to_h) compose(NotifyMultiyearsExpirationDomain, inputs.to_h) - puts "SetForceDelete has been executed" end end end diff --git a/app/jobs/company_register_status_job.rb b/app/jobs/company_register_status_job.rb index 36b292cbfe..96a24f06b3 100644 --- a/app/jobs/company_register_status_job.rb +++ b/app/jobs/company_register_status_job.rb @@ -50,7 +50,7 @@ def update_validation_company_status(contact:, status:) end def schedule_force_delete(contact) - contact.domains.each do |domain| + contact.registrant_domains.each do |domain| next if domain.force_delete_scheduled? domain.schedule_force_delete( @@ -63,13 +63,13 @@ def schedule_force_delete(contact) end def check_for_force_delete(contact) - contact.domains.any? && domain.status_notes[DomainStatus::FORCE_DELETE].include?("Company no: #{contact.ident}") do |domain| + contact.registrant_domains.any? && domain.status_notes[DomainStatus::FORCE_DELETE].include?("Company no: #{contact.ident}") do |domain| domain.force_delete_scheduled? end end def lift_force_delete(contact) - contact.domains.each(&:lift_force_delete) + contact.registrant_domains.each(&:lift_force_delete) end def delete_process(contact) @@ -97,7 +97,7 @@ def extract_kandeliik_tekstina(company_details_response) end def soft_delete_company(contact) - contact.domains.reject { |domain| domain.force_delete_scheduled? }.each do |domain| + contact.registrant_domains.reject { |domain| domain.force_delete_scheduled? }.each do |domain| domain.schedule_force_delete(type: :soft) end diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 5a68013fc5..e0f98ea84e 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -48,7 +48,6 @@ def force_delete_scheduled? end def schedule_force_delete(type: :fast_track, notify_by_email: false, reason: nil, email: nil) - puts "Schedule force delete for domain: #{name} with type: #{type}" Domains::ForceDelete::SetForceDelete.run(domain: self, type: type, reason: reason, notify_by_email: notify_by_email, email: email) end diff --git a/app/models/contact.rb b/app/models/contact.rb index b7fc85dde8..51c5ecd2c0 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -87,9 +87,6 @@ class Contact < ApplicationRecord after_save :update_related_whois_records before_validation :clear_address_modifications, if: -> { !self.class.address_processing? } - # after_save :validate_email_by_regex_and_mx - # after_save :remove_force_delete_for_valid_contact - self.ignored_columns = %w[legacy_id legacy_history_id] ORG = 'org'.freeze diff --git a/app/models/domain.rb b/app/models/domain.rb index b58bdb7d86..1f4d0c510f 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -38,6 +38,8 @@ class Domain < ApplicationRecord :epp_pending_delete, :reserved_pw + attr_accessor :skip_multiyears_expiration_email_validation + alias_attribute :on_hold_time, :outzone_at alias_attribute :outzone_time, :outzone_at alias_attribute :auth_info, :transfer_code # Old attribute name; for PaperTrail diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index 638cf91525..11fd50ef36 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -195,19 +195,9 @@ namespace :company_status do 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 "Try to set soft delete for company: #{contact.name} with ID: #{contact.id}" - puts "Contact (registrant) domains: #{contact.registrant_domains.map(&:name)}" - contact.registrant_domains.each do |domain| - puts "Domain: #{domain.name} with force delete scheduled: #{domain.force_delete_scheduled?}" next if domain.force_delete_scheduled? - puts "Try to set soft delete for domain: #{domain.name}" domain.schedule_force_delete(type: :soft) puts "Soft delete process initiated for company: #{contact.name} with ID: #{contact.id} domain: #{domain.name}" end From c4f35522ca54b58dad220792488c9a48893a43ff Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Mon, 30 Sep 2024 15:34:14 +0300 Subject: [PATCH 11/15] mend --- app/jobs/company_register_status_job.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/jobs/company_register_status_job.rb b/app/jobs/company_register_status_job.rb index 96a24f06b3..b7f4433ed3 100644 --- a/app/jobs/company_register_status_job.rb +++ b/app/jobs/company_register_status_job.rb @@ -17,6 +17,8 @@ def proceed_company_status(contact, spam_time_delay) # avoid spamming company register sleep spam_time_delay + puts "WHAT YOU GONNA DO WHEN I COME FOR YOU?" + company_status = contact.return_company_status contact.update!(company_register_status: company_status, checked_company_at: Time.zone.now) @@ -63,8 +65,8 @@ def schedule_force_delete(contact) end def check_for_force_delete(contact) - contact.registrant_domains.any? && domain.status_notes[DomainStatus::FORCE_DELETE].include?("Company no: #{contact.ident}") do |domain| - domain.force_delete_scheduled? + contact.registrant_domains.any? do |domain| + domain.status_notes[DomainStatus::FORCE_DELETE].include?("Company no: #{contact.ident}") end end From 7da6eea85c526565d1884b4d18573d15493c043b Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Mon, 7 Oct 2024 11:04:56 +0300 Subject: [PATCH 12/15] updated FD conditions --- lib/tasks/company_status.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index 11fd50ef36..1553c870de 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -196,9 +196,9 @@ namespace :company_status do def soft_delete_company(contact) contact.registrant_domains.each do |domain| - next if domain.force_delete_scheduled? + # next if domain.force_delete_scheduled? - domain.schedule_force_delete(type: :soft) + domain.schedule_force_delete(type: :soft, notify_by_email: true, reason: 'invalid_company', email: contact.email) puts "Soft delete process initiated for company: #{contact.name} with ID: #{contact.id} domain: #{domain.name}" end From 3cf4e295314bb886747a593925c34934affb7f90 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Tue, 8 Oct 2024 11:29:12 +0300 Subject: [PATCH 13/15] change unique collection from by ident to code --- app/jobs/company_register_status_job.rb | 2 +- lib/tasks/company_status.rake | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/jobs/company_register_status_job.rb b/app/jobs/company_register_status_job.rb index b7f4433ed3..274a425095 100644 --- a/app/jobs/company_register_status_job.rb +++ b/app/jobs/company_register_status_job.rb @@ -71,7 +71,7 @@ def check_for_force_delete(contact) end def lift_force_delete(contact) - contact.registrant_domains.each(&:lift_force_delete) + contact.registrant_domains.each(&:cancel_force_delete) end def delete_process(contact) diff --git a/lib/tasks/company_status.rake b/lib/tasks/company_status.rake index 1553c870de..2ee90c5448 100644 --- a/lib/tasks/company_status.rake +++ b/lib/tasks/company_status.rake @@ -47,16 +47,17 @@ namespace :company_status do contacts_query = contacts_query.joins(:registrant_domains).distinct end - unique_contacts = contacts_query.to_a.uniq(&:ident) + unique_contacts = contacts_query.to_a.uniq(&:code) unique_contacts.each do |contact| next if whitelisted_companies.include?(contact.ident) - if company_data.key?(contact.ident) - update_company_status(contact: contact, status: company_data[contact.ident][COMPANY_STATUS]) - puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status: #{company_data[contact.ident][COMPANY_STATUS]}" - else - update_company_status(contact: contact, status: 'K') + status = company_data.fetch(contact.ident, {}).fetch(COMPANY_STATUS, 'K') + update_company_status(contact: contact, status: status) + puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status: #{status}" + + puts "Contact domain: #{contact.registrant_domains.pluck(:name)}" + if status == 'K' sort_companies_to_files( contact: contact, missing_companies_in_business_registry_path: missing_companies_in_business_registry_path, @@ -155,7 +156,7 @@ namespace :company_status do end def put_company_to_missing_file(contact:, path:) - write_to_csv_file(csv_file_path: path, headers: ["ID", "Ident", "Name", "Contact Type"], attrs: [contact.id, contact.ident, contact.name, determine_contact_type(contact)]) + write_to_csv_file(csv_file_path: path, headers: ["ID", "Code", "Ident", "Name", "Contact Type"], attrs: [contact.id, contact.code, contact.ident, contact.name, determine_contact_type(contact)]) end def sort_companies_to_files(contact:, missing_companies_in_business_registry_path:, deleted_companies_from_business_registry_path:, soft_delete_enable:, sleep_time:) @@ -176,8 +177,8 @@ namespace :company_status do if status == DELETED_FROM_REGISTRY_STATUS csv_file_path = deleted_companies_from_business_registry_path - headers = ["ID", "Ident", "Name", "Status", "Kandeliik Type", "Kandeliik Tekstina", "kande_kpv", "Contact Type"] - attrs = [contact.id, contact.ident, contact.name, status, kandeliik_type, kandeliik_tekstina, kande_kpv, determine_contact_type(contact)] + headers = ["ID", "Code", "Ident", "Name", "Status", "Kandeliik Type", "Kandeliik Tekstina", "kande_kpv", "Contact Type"] + attrs = [contact.id, contact.code, contact.ident, contact.name, status, kandeliik_type, kandeliik_tekstina, kande_kpv, determine_contact_type(contact)] write_to_csv_file(csv_file_path: csv_file_path, headers: headers, attrs: attrs) puts "Company: #{contact.name} with ident: #{contact.ident} and ID: #{contact.id} has status #{status}, company id: #{contact.id}" From 81512dff6574d69a7cc80339e40f6fd16d6258d3 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Mon, 21 Oct 2024 12:32:31 +0300 Subject: [PATCH 14/15] update dockerfile --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 98d37d92b9..7b561825c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ FROM internetee/ruby:3.0-buster -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4EB27DB2A3B88B8B -RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - postgresql-client \ - && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +# # RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4EB27DB2A3B88B8B +# RUN apt-get update && apt-get install -y --no-install-recommends \ +# git \ +# 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 From 0a08d77b1c127bc1086c554d29bd44c14be3cae5 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Fri, 8 Nov 2024 12:46:39 +0200 Subject: [PATCH 15/15] fixed conflict --- Gemfile.lock | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0f155855a0..ca18578e19 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -329,13 +329,10 @@ GEM money (~> 6.13.2) railties (>= 3.0) msgpack (1.7.2) -<<<<<<< HEAD net-ftp (0.3.7) net-protocol time -======= mutex_m (0.2.0) ->>>>>>> 5f9bc1f5e (fixed method for check force delete) net-protocol (0.1.3) timeout net-smtp (0.3.3) @@ -385,13 +382,8 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) -<<<<<<< HEAD - public_suffix (5.0.0) - puma (5.6.9) -======= public_suffix (6.0.1) puma (5.6.8) ->>>>>>> 5f9bc1f5e (fixed method for check force delete) nio4r (~> 2.0) racc (1.8.1) rack (2.2.9) @@ -628,8 +620,4 @@ DEPENDENCIES wkhtmltopdf-binary (~> 0.12.6.1) BUNDLED WITH -<<<<<<< HEAD - 2.5.15 -======= 2.5.19 ->>>>>>> 5f9bc1f5e (fixed method for check force delete)