diff --git a/Gemfile b/Gemfile
index 7b9ee143d..9ed6b8090 100644
--- a/Gemfile
+++ b/Gemfile
@@ -68,6 +68,8 @@ gem 'domain_name'
gem 'haml', '~> 5.0'
gem 'wkhtmltopdf-binary'
+gem 'directo', github: 'internetee/directo', branch: 'master'
+
group :development do
# deploy
gem 'mina', '0.3.1' # for fast deployment
diff --git a/Gemfile.lock b/Gemfile.lock
index 31b48d360..f0871bf85 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -7,6 +7,15 @@ GIT
activesupport
savon
+GIT
+ remote: https://github.com/internetee/directo.git
+ revision: 8cb63d2fb91c640b264d5af05f4a6afbcfd46979
+ branch: master
+ specs:
+ directo (1.0.0)
+ money (~> 6.13)
+ nokogiri (~> 1.10)
+
GIT
remote: https://github.com/internetee/e_invoice.git
revision: b374ffd7be77b559b30c7a0210dc0df5ac3ed723
@@ -466,6 +475,7 @@ DEPENDENCIES
database_cleaner
devise (~> 4.7)
digidoc_client!
+ directo!
domain_name
e_invoice!
epp!
diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb
new file mode 100644
index 000000000..6c3eb034c
--- /dev/null
+++ b/app/jobs/directo_invoice_forward_job.rb
@@ -0,0 +1,125 @@
+class DirectoInvoiceForwardJob < Que::Job
+ def run(monthly: false, dry: false)
+ @dry = dry
+ (@month = Time.zone.now - 1.month) if monthly
+ api_url = ENV['directo_invoice_url']
+ sales_agent = Setting.directo_sales_agent
+ payment_term = Setting.directo_receipt_payment_term
+ @prepayment_product_id = Setting.directo_receipt_product_name
+
+ @client = DirectoApi::Client.new(api_url, sales_agent, payment_term)
+ monthly ? send_monthly_invoices : send_receipts
+ end
+
+ def send_receipts
+ unsent_invoices = Invoice.where(in_directo: false).non_cancelled
+
+ Rails.logger.info("[DIRECTO] Trying to send #{unsent_invoices.count} prepayment invoices")
+ unsent_invoices.each do |invoice|
+ unless valid_invoice_conditions?(invoice)
+ Rails.logger.info "[DIRECTO] Invoice #{invoice.number} has been skipped"
+ next
+ end
+ @client.invoices.add_with_schema(invoice: invoice.as_directo_json, schema: 'prepayment')
+ end
+
+ sync_with_directo
+ end
+
+ def send_monthly_invoices
+ Registrar.where.not(test_registrar: true).find_each do |registrar|
+ fetch_monthly_summary(registrar: registrar)
+ end
+
+ return unless @client.invoices.count.positive?
+
+ sync_with_directo
+ end
+
+ def fetch_monthly_summary(registrar:)
+ return unless registrar.cash_account
+
+ summary = registrar.monthly_summary(month: @month)
+ @client.invoices.add_with_schema(invoice: summary, schema: 'summary') unless summary.nil?
+ end
+
+ def assign_monthly_numbers
+ if directo_counter_exceedable?(@client.invoices.count)
+ raise 'Directo Counter is going to be out of period!'
+ end
+
+ min_directo = Setting.directo_monthly_number_min.presence.try(:to_i)
+ directo_number = [Setting.directo_monthly_number_last.presence.try(:to_i),
+ min_directo].compact.max || 0
+
+ @client.invoices.each do |inv|
+ directo_number += 1
+ inv.number = directo_number
+ end
+ end
+
+ def valid_invoice_conditions?(invoice)
+ if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? ||
+ invoice.account_activity.bank_transaction.sum.nil? ||
+ invoice.account_activity.bank_transaction.sum != invoice.total
+ return false
+
+ end
+
+ true
+ end
+
+ def sync_with_directo
+ assign_monthly_numbers if @month
+ Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}")
+ return if @dry
+
+ res = @client.invoices.deliver(ssl_verify: false)
+ process_directo_response(res.body, @client.invoices.as_xml)
+ rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
+ EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
+ Rails.logger.info('[Directo] Failed to communicate via API')
+ end
+
+ def process_directo_response(xml, req)
+ Rails.logger.info "[Directo] - Responded with body: #{xml}"
+ Nokogiri::XML(xml).css('Result').each do |res|
+ if @month
+ mark_invoice_as_sent(res: res, req: req)
+ else
+ inv = Invoice.find_by(number: res.attributes['docid'].value.to_i)
+ mark_invoice_as_sent(invoice: inv, res: res, req: req)
+ end
+ end
+ end
+
+ def mark_invoice_as_sent(invoice: nil, res:, req:)
+ directo_record = Directo.new(response: res.as_json.to_h,
+ request: req, invoice_number: res.attributes['docid'].value.to_i)
+ if invoice
+ directo_record.item = invoice
+ invoice.update(in_directo: true)
+ else
+ update_directo_number(num: directo_record.invoice_number)
+ end
+
+ directo_record.save!
+ end
+
+ def update_directo_number(num:)
+ return unless num.to_i > Setting.directo_monthly_number_last.to_i
+
+ Setting.directo_monthly_number_last = num.to_i
+ end
+
+ def directo_counter_exceedable?(invoice_count)
+ min_directo = Setting.directo_monthly_number_min.presence.try(:to_i)
+ max_directo = Setting.directo_monthly_number_max.presence.try(:to_i)
+ last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i),
+ min_directo].compact.max || 0
+
+ return true if max_directo && max_directo < (last_directo + invoice_count)
+
+ false
+ end
+end
diff --git a/app/models/concerns/invoice/book_keeping.rb b/app/models/concerns/invoice/book_keeping.rb
new file mode 100644
index 000000000..2469f45eb
--- /dev/null
+++ b/app/models/concerns/invoice/book_keeping.rb
@@ -0,0 +1,26 @@
+module Concerns
+ module Invoice
+ module BookKeeping
+ extend ActiveSupport::Concern
+
+ def as_directo_json
+ invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self))
+ invoice['customer_code'] = buyer.accounting_customer_code
+ invoice['issue_date'] = issue_date.strftime('%Y-%m-%d')
+ invoice['transaction_date'] = account_activity
+ .bank_transaction&.paid_at&.strftime('%Y-%m-%d')
+ invoice['language'] = buyer.language == 'en' ? 'ENG' : ''
+ invoice['invoice_lines'] = compose_directo_product
+
+ invoice
+ end
+
+ def compose_directo_product
+ [{ 'product_id': Setting.directo_receipt_product_name, 'description': order,
+ 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision(
+ subtotal, precision: 2, separator: '.'
+ ) }].as_json
+ end
+ end
+ end
+end
diff --git a/app/models/concerns/registrar/book_keeping.rb b/app/models/concerns/registrar/book_keeping.rb
new file mode 100644
index 000000000..27645d2cb
--- /dev/null
+++ b/app/models/concerns/registrar/book_keeping.rb
@@ -0,0 +1,120 @@
+module Concerns
+ module Registrar
+ module BookKeeping
+ extend ActiveSupport::Concern
+
+ DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI',
+ 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze
+
+ def monthly_summary(month:)
+ activities = monthly_activites(month)
+ return unless activities.any?
+
+ invoice = {
+ 'number': 1,
+ 'customer_code': accounting_customer_code,
+ 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency,
+ 'date': month.end_of_month.strftime('%Y-%m-%d')
+ }.as_json
+
+ invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities)
+
+ invoice
+ end
+
+ def prepare_invoice_lines(month:, activities:)
+ lines = []
+
+ lines << { 'description': title_for_summary(month) }
+ activities.each do |activity|
+ fetch_invoice_lines(activity, lines)
+ end
+ lines << prepayment_for_all(lines)
+
+ lines.as_json
+ end
+
+ def title_for_summary(date)
+ I18n.with_locale(language == 'en' ? 'en' : 'et') do
+ I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y'))
+ end
+ end
+
+ def fetch_invoice_lines(activity, lines)
+ price = load_price(activity)
+ if price.duration.include? 'year'
+ price.duration.to_i.times do |duration|
+ lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json
+ end
+ else
+ lines << new_monthly_invoice_line(activity: activity).as_json
+ end
+ end
+
+ def monthly_activites(month)
+ AccountActivity.where(account_id: account_ids)
+ .where(created_at: month.beginning_of_month..month.end_of_month)
+ .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
+ end
+
+ def new_monthly_invoice_line(activity:, duration: nil)
+ price = load_price(activity)
+ line = {
+ 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
+ 'quantity': 1,
+ 'unit': language == 'en' ? 'pc' : 'tk',
+ }
+
+ finalize_invoice_line(line, price: price, duration: duration, activity: activity)
+ end
+
+ def finalize_invoice_line(line, price:, activity:, duration:)
+ yearly = price.duration.include?('year')
+
+ line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount
+ line['description'] = description_in_language(price: price, yearly: yearly)
+
+ if duration.present?
+ add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1
+ end
+
+ line
+ end
+
+ def add_product_timeframe(line:, activity:, duration:)
+ create_time = activity.created_at
+ line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d')
+ line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d')
+ end
+
+ def description_in_language(price:, yearly:)
+ timeframe_string = yearly ? 'yearly' : 'monthly'
+ locale_string = "registrar.invoice_#{timeframe_string}_product_description"
+
+ I18n.with_locale(language == 'en' ? 'en' : 'et') do
+ I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i)
+ end
+ end
+
+ def prepayment_for_all(lines)
+ total = 0
+ en = language == 'en'
+ lines.each { |l| total += l['quantity'].to_f * l['price'].to_f }
+ {
+ 'product_id': Setting.directo_receipt_product_name,
+ 'description': en ? 'Domains prepayment' : 'Domeenide ettemaks',
+ 'quantity': -1,
+ 'price': total,
+ 'unit': en ? 'pc' : 'tk',
+ }
+ end
+
+ def load_price(account_activity)
+ @pricelists ||= {}
+ return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
+
+ @pricelists[account_activity.price_id] = account_activity.price
+ end
+ end
+ end
+end
diff --git a/app/models/counter.rb b/app/models/counter.rb
deleted file mode 100644
index 7d1c2b926..000000000
--- a/app/models/counter.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class Counter
- def initialize value = 0
- @value = value
- end
- attr_accessor :value
- def method_missing *args, &blk
- @value.send(*args, &blk)
- end
- def to_s
- @value.to_s
- end
-
- def now
- @value
- end
-
- # pre-increment ".+" when x not present
- def next(x = 1)
- @value += x
- end
- def prev(x = 1)
- @value -= x
- end
-end
\ No newline at end of file
diff --git a/app/models/directo.rb b/app/models/directo.rb
index e311641e6..a4af6c134 100644
--- a/app/models/directo.rb
+++ b/app/models/directo.rb
@@ -1,201 +1,3 @@
class Directo < ApplicationRecord
- DOMAIN_TO_PRODUCT = {"ee" => "01EE", "com.ee" => "02COM", "pri.ee" => "03PRI", "fie.ee"=>"04FIE", "med.ee" => "05MED"}.freeze
belongs_to :item, polymorphic: true
-
- def self.send_receipts
- new_trans = Invoice.where(in_directo: false).non_cancelled
- total = new_trans.count
- counter = 0
- Rails.logger.info("[DIRECTO] Will try to send #{total} invoices")
-
- new_trans.find_in_batches(batch_size: 10).each do |group|
- mappers = {} # need them as no direct connection between invoice
- builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
- xml.invoices {
- group.each do |invoice|
-
- if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? ||
- invoice.account_activity.bank_transaction.sum.nil? || invoice.account_activity.bank_transaction.sum != invoice.total
- Rails.logger.info("[DIRECTO] Invoice #{invoice.number} has been skipped")
- next
- end
- counter += 1
-
- num = invoice.number
- paid_at = invoice.account_activity.bank_transaction&.paid_at&.strftime("%Y-%m-%d")
- mappers[num] = invoice
- xml.invoice(
- "SalesAgent" => Setting.directo_sales_agent,
- "Number" => num,
- "InvoiceDate" => invoice.issue_date.strftime("%Y-%m-%d"),
- 'TransactionDate' => paid_at,
- "PaymentTerm" => Setting.directo_receipt_payment_term,
- "Currency" => invoice.currency,
- "CustomerCode"=> invoice.buyer.accounting_customer_code
- ){
- xml.line(
- "ProductID" => Setting.directo_receipt_product_name,
- "Quantity" => 1,
- "UnitPriceWoVAT" => ActionController::Base.helpers.number_with_precision(invoice.subtotal, precision: 2, separator: "."),
- "ProductName" => invoice.order
- )
- }
- end
- }
- end
-
- data = builder.to_xml.gsub("\n",'')
- Rails.logger.info("[Directo] XML request: #{data}")
- response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false)
- Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}")
- dump_result_to_db(mappers: mappers, xml: response.to_s, data: data)
- end
-
- STDOUT << "#{Time.zone.now.utc} - Directo receipts sending finished. #{counter} of #{total} are sent\n"
- end
-
- def self.dump_result_to_db(mappers:, xml:, data:)
- Nokogiri::XML(xml).css("Result").each do |res|
- obj = mappers[res.attributes["docid"].value.to_i]
- obj.directo_records.create!(request: data,
- response: res.as_json.to_h,
- invoice_number: obj.number)
- obj.update_columns(in_directo: true)
- Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}")
- end
- end
-
-
- def self.send_monthly_invoices(debug: false)
- I18n.locale = :et unless Rails.env.test?
- month = Time.now - 1.month
- invoices_until = month.end_of_month
- date_format = "%Y-%m-%d"
- invoice_counter= Counter.new
-
- min_directo = Setting.directo_monthly_number_min.presence.try(:to_i)
- max_directo = Setting.directo_monthly_number_max.presence.try(:to_i)
- last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i), min_directo].compact.max || 0
- if max_directo && (max_directo <= last_directo + Registrar.count)
- raise 'Directo counter is out of period (max allowed number is smaller than last counter'\
- 'number plus Registrar\'s count)'
- end
-
- directo_next = last_directo
- Registrar.where.not(test_registrar: true).find_each do |registrar|
- unless registrar.cash_account
- Rails.logger.info("[DIRECTO] Monthly invoice for registrar #{registrar.id} has been skipped as it doesn't has cash_account")
- next
- end
- counter = Counter.new(1)
- items = {}
- registrar_activities = AccountActivity.where(account_id: registrar.account_ids).where("created_at BETWEEN ? AND ?",month.beginning_of_month, month.end_of_month)
-
- # adding domains items
- registrar_activities.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]).each do |activity|
- price = load_price(activity)
-
- if price.duration.include?('year')
- price.duration.to_i.times do |i|
- year = i+1
- hash = {
- "ProductID" => DOMAIN_TO_PRODUCT[price.zone_name],
- "Unit" => "tk",
- "ProductName" => ".#{price.zone_name} registreerimine: #{price.duration.to_i} aasta#{price.duration.to_i > 1 ? 't' : ''}",
- "UnitPriceWoVAT" => price.price.amount / price.duration.to_i
- }
- hash["StartDate"] = (activity.created_at + (year-1).year).end_of_month.strftime(date_format) if year > 1
- hash["EndDate"] = (activity.created_at + (year-1).year + 1).end_of_month.strftime(date_format) if year > 1
-
- if items.has_key?(hash)
- items[hash]["Quantity"] += 1
- else
- items[hash] = { "RN" => counter.next, "RR" => counter.now - i, "Quantity" => 1 }
- end
- end
- else
- 1.times do |i|
- quantity = price.account_activities
- .where(account_id: registrar.account_ids)
- .where(created_at: month.beginning_of_month..month.end_of_month)
- .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
- .count
-
- hash = {
- "ProductID" => DOMAIN_TO_PRODUCT[price.zone_name],
- "Unit" => "tk",
- "ProductName" => ".#{price.zone_name} registreerimine: #{price.duration.to_i} kuud",
- "UnitPriceWoVAT" => price.price.amount,
- }
-
- if items.has_key?(hash)
- #items[hash]["Quantity"] += 1
- else
- items[hash] = { "RN" => counter.next, "RR" => counter.now - i, "Quantity" => quantity }
- end
- end
- end
-
-
- end
-
- #adding prepaiments
- if items.any?
- total = 0
- items.each{ |key, val| total += val["Quantity"] * key["UnitPriceWoVAT"] }
- hash = {"ProductID" => Setting.directo_receipt_product_name, "Unit" => "tk", "ProductName" => "Domeenide ettemaks", "UnitPriceWoVAT"=>total}
- items[hash] = {"RN"=>counter.next, "RR" => counter.now, "Quantity"=> -1}
- end
-
- # generating XML
- if items.any?
- directo_next += 1
- invoice_counter.next
-
- builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
- xml.invoices{
- xml.invoice("Number" =>directo_next,
- "InvoiceDate" =>invoices_until.strftime(date_format),
- "PaymentTerm" =>Setting.directo_receipt_payment_term,
- "CustomerCode"=>registrar.accounting_customer_code,
- "Language" =>"",
- "Currency" =>registrar_activities.first.currency,
- "SalesAgent" =>Setting.directo_sales_agent){
- xml.line("RN" => 1, "RR"=>1, "ProductName"=> "Domeenide registreerimine - #{I18n.l(invoices_until, format: "%B %Y").titleize}")
- items.each do |line, val|
- xml.line(val.merge(line))
- end
- }
- }
- end
-
- data = builder.to_xml.gsub("\n",'')
- Rails.logger.info("[Directo] XML request: #{data}")
-
- if debug
- STDOUT << "#{Time.zone.now.utc} - Directo xml had to be sent #{data}\n"
- else
- response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false)
- Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}")
- response = response.to_s
-
- Setting.directo_monthly_number_last = directo_next
- Nokogiri::XML(response).css("Result").each do |res|
- Directo.create!(request: data, response: res.as_json.to_h, invoice_number: directo_next)
- Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}")
- end
- end
- else
- Rails.logger.info("[DIRECTO] Registrar #{registrar.id} has nothing to be sent to Directo")
- end
-
- end
- STDOUT << "#{Time.zone.now.utc} - Directo invoices sending finished. #{invoice_counter.now} are sent\n"
- end
-
- def self.load_price(account_activity)
- @pricelists ||= {}
- return @pricelists[account_activity.price_id] if @pricelists.has_key?(account_activity.price_id)
- @pricelists[account_activity.price_id] = account_activity.price
- end
end
diff --git a/app/models/invoice.rb b/app/models/invoice.rb
index 1c6bced6e..a130a90ff 100644
--- a/app/models/invoice.rb
+++ b/app/models/invoice.rb
@@ -2,6 +2,7 @@ class Invoice < ApplicationRecord
include Versions
include Concerns::Invoice::Cancellable
include Concerns::Invoice::Payable
+ include Concerns::Invoice::BookKeeping
belongs_to :buyer, class_name: 'Registrar'
has_one :account_activity
@@ -71,7 +72,7 @@ class Invoice < ApplicationRecord
Country.new(buyer_country_code)
end
-# order is used for directo/banklink description
+ # order is used for directo/banklink description
def order
"Order nr. #{number}"
end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index f657cdc74..c3522859e 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -1,5 +1,6 @@
class Registrar < ApplicationRecord
include Versions # version/registrar_version.rb
+ include Concerns::Registrar::BookKeeping
has_many :domains, dependent: :restrict_with_error
has_many :contacts, dependent: :restrict_with_error
diff --git a/config/locales/registrars.en.yml b/config/locales/registrars.en.yml
index 609f9f94a..c57f2e891 100644
--- a/config/locales/registrars.en.yml
+++ b/config/locales/registrars.en.yml
@@ -1,4 +1,8 @@
en:
+ registrar:
+ invoice_yearly_product_description: '%{tld} registration: %{length} year(s)'
+ invoice_monthly_product_description: '%{tld} registration: %{length} month(s)'
+ monthly_summary_title: 'Domain registrations - %{date}'
activerecord:
errors:
models:
@@ -8,4 +12,4 @@ en:
forbidden: is forbidden
vat_rate:
present: >-
- must be blank when a registrar is VAT-registered in the same country as registry
\ No newline at end of file
+ must be blank when a registrar is VAT-registered in the same country as registry
diff --git a/config/locales/registrars.et.yml b/config/locales/registrars.et.yml
new file mode 100644
index 000000000..1001638c1
--- /dev/null
+++ b/config/locales/registrars.et.yml
@@ -0,0 +1,5 @@
+et:
+ registrar:
+ invoice_yearly_product_description: '%{tld} registreerimine: %{length} aasta(t)'
+ invoice_monthly_product_description: '%{tld} registreerimine: %{length} kuu(d)'
+ monthly_summary_title: 'Domeenide registreerimine - %{date}'
diff --git a/test/fixtures/account_activities.yml b/test/fixtures/account_activities.yml
index dbe1dc2aa..8f883e424 100644
--- a/test/fixtures/account_activities.yml
+++ b/test/fixtures/account_activities.yml
@@ -2,4 +2,4 @@ one:
account: cash
invoice: one
bank_transaction: one
- created_at: <%= Time.zone.parse('2010-07-05 10:00') %>
\ No newline at end of file
+ created_at: <%= Time.zone.parse('2010-07-05 10:00') %>
diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb
new file mode 100644
index 000000000..8a4fb43aa
--- /dev/null
+++ b/test/jobs/directo_invoice_forward_job_test.rb
@@ -0,0 +1,146 @@
+require "test_helper"
+
+class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase
+ setup do
+ @invoice = invoices(:one)
+ @user = registrars(:bestnames)
+ travel_to Time.zone.parse('2010-08-06')
+ end
+
+ def teardown
+ Setting.clear_cache
+ Setting.directo_monthly_number_min = 309901
+ Setting.directo_monthly_number_max = 309999
+ Setting.directo_monthly_number_last = 309901
+ end
+
+ def test_xml_is_include_transaction_date
+ @invoice.update(total: @invoice.account_activity.bank_transaction.sum)
+ @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now)
+
+ response = <<-XML
+
+
+
+
+ XML
+
+ stub_request(:post, ENV['directo_invoice_url']).with do |request|
+ request.body.include? 'TransactionDate'
+ end.to_return(status: 200, body: response)
+
+ assert_nothing_raised do
+ DirectoInvoiceForwardJob.run(monthly: false, dry: false)
+ end
+
+ assert_not_empty @invoice.directo_records.first.request
+ end
+
+ def test_fails_if_directo_bounds_exceedable
+ activity = account_activities(:one)
+ price = billing_prices(:create_one_year)
+ activity.update!(activity_type: 'create', price: price)
+
+ Setting.directo_monthly_number_max = 30991
+
+ assert_raises 'RuntimeError' do
+ DirectoInvoiceForwardJob.run(monthly: true, dry: false)
+ end
+ end
+
+ def test_monthly_summary_is_delivered_in_estonian
+ activity = account_activities(:one)
+ price = billing_prices(:create_one_year)
+ activity.update!(activity_type: 'create', price: price)
+ @user.update(language: 'et')
+
+ response = <<-XML
+
+
+
+
+ XML
+
+ stub_request(:post, ENV['directo_invoice_url']).with do |request|
+ body = CGI.unescape(request.body)
+
+ (body.include? '.test registreerimine: 1 aasta(t)') &&
+ (body.include? 'Domeenide ettemaks') &&
+ (body.include? '309902')
+ end.to_return(status: 200, body: response)
+
+ assert_difference 'Setting.directo_monthly_number_last' do
+ DirectoInvoiceForwardJob.run(monthly: true, dry: false)
+ end
+ end
+
+ def test_monthly_summary_is_delivered_in_english
+ activity = account_activities(:one)
+ price = billing_prices(:create_one_year)
+ activity.update(activity_type: 'create', price: price)
+ @user.update(language: 'en')
+
+ response = <<-XML
+
+
+
+
+ XML
+
+ stub_request(:post, ENV['directo_invoice_url']).with do |request|
+ body = CGI.unescape(request.body)
+ (body.include? 'test registration') &&
+ (body.include? 'Domains prepayment') &&
+ (body.include? '309902')
+ end.to_return(status: 200, body: response)
+
+ assert_difference 'Setting.directo_monthly_number_last' do
+ DirectoInvoiceForwardJob.run(monthly: true, dry: false)
+ end
+ end
+
+ def test_multi_year_purchases_have_duration_assigned
+ activity = account_activities(:one)
+ price = billing_prices(:create_one_year)
+ price.update(duration: '3 years')
+ activity.update(activity_type: 'create', price: price)
+
+ response = <<-XML
+
+
+
+
+ XML
+
+ stub_request(:post, ENV['directo_invoice_url']).with do |request|
+ body = CGI.unescape(request.body)
+ (body.include? 'StartDate') && (body.include? 'EndDate')
+ end.to_return(status: 200, body: response)
+
+ assert_difference 'Setting.directo_monthly_number_last' do
+ DirectoInvoiceForwardJob.run(monthly: true, dry: false)
+ end
+ end
+
+ def test_monthly_duration_products_are_present_in_summary
+ activity = account_activities(:one)
+ price = billing_prices(:create_one_month)
+ activity.update(activity_type: 'create', price: price)
+
+ response = <<-XML
+
+
+
+
+ XML
+
+ stub_request(:post, ENV['directo_invoice_url']).with do |request|
+ body = CGI.unescape(request.body)
+ body.include? 'month(s)'
+ end.to_return(status: 200, body: response)
+
+ assert_difference 'Setting.directo_monthly_number_last' do
+ DirectoInvoiceForwardJob.run(monthly: true, dry: false)
+ end
+ end
+end
diff --git a/test/models/directo_test.rb b/test/models/directo_test.rb
index 086ce567b..603a38d15 100644
--- a/test/models/directo_test.rb
+++ b/test/models/directo_test.rb
@@ -1,42 +1,4 @@
require 'test_helper'
class DirectoTest < ActiveSupport::TestCase
- setup do
- @invoice = invoices(:one)
- end
-
- def test_monthly_invoices_max_range_raises_if_overlaps
-
- Setting.directo_monthly_number_max = Setting.directo_monthly_number_last.to_i + Registrar.count - 1
- error_message = 'Directo counter is out of period (max allowed number is smaller than last '\
- 'counternumber plus Registrar\'s count)'
-
- error = assert_raises RuntimeError do
- Directo.send_monthly_invoices
- end
-
- assert_equal error_message, error.message
- end
-
- def test_xml_is_include_transaction_date
- @invoice.update(total: @invoice.account_activity.bank_transaction.sum)
- @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now)
-
- response = <<-XML
-
-
-
-
- XML
-
- stub_request(:post, ENV['directo_invoice_url']).with do |request|
- request.body.include? 'TransactionDate'
- end.to_return(status: 200, body: response)
-
- assert_nothing_raised do
- Directo.send_receipts
- end
-
- assert_not_empty @invoice.directo_records.first.request
- end
end