mirror of
https://github.com/internetee/registry.git
synced 2025-07-29 22:16:19 +02:00
Merge pull request #2456 from internetee/modify-monthly-invoice-generation
Refactored monthly invoice generation job
This commit is contained in:
commit
8244066d5d
21 changed files with 383 additions and 505 deletions
|
@ -1,15 +1,8 @@
|
||||||
class DirectoInvoiceForwardJob < ApplicationJob
|
class DirectoInvoiceForwardJob < ApplicationJob
|
||||||
def perform(monthly: false, dry: false)
|
def perform(dry: false)
|
||||||
data = nil
|
data = collect_receipts_data
|
||||||
|
|
||||||
if monthly
|
EisBilling::SendDataToDirecto.send_request(object_data: data, monthly: false, dry: dry)
|
||||||
@month = Time.zone.now - 1.month
|
|
||||||
data = collect_monthly_data
|
|
||||||
else
|
|
||||||
data = collect_receipts_data
|
|
||||||
end
|
|
||||||
|
|
||||||
EisBilling::SendDataToDirecto.send_request(object_data: data, monthly: monthly, dry: dry)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect_receipts_data
|
def collect_receipts_data
|
||||||
|
@ -38,47 +31,4 @@ class DirectoInvoiceForwardJob < ApplicationJob
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect_monthly_data
|
|
||||||
registrars_data = []
|
|
||||||
|
|
||||||
Registrar.where.not(test_registrar: true).find_each do |registrar|
|
|
||||||
registrars_data << {
|
|
||||||
registrar: registrar,
|
|
||||||
registrar_summery: registrar.monthly_summary(month: @month),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
registrars_data
|
|
||||||
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
|
end
|
||||||
|
|
|
@ -3,11 +3,10 @@ class SendEInvoiceJob < ApplicationJob
|
||||||
|
|
||||||
def perform(invoice_id, payable: true)
|
def perform(invoice_id, payable: true)
|
||||||
logger.info "Started to process e-invoice for invoice_id #{invoice_id}"
|
logger.info "Started to process e-invoice for invoice_id #{invoice_id}"
|
||||||
invoice = Invoice.find_by(id: invoice_id)
|
invoice = Invoice.find(invoice_id)
|
||||||
return unless need_to_process_invoice?(invoice: invoice, payable: payable)
|
return unless need_to_process_invoice?(invoice: invoice, payable: payable)
|
||||||
|
|
||||||
send_invoice_to_eis_billing(invoice: invoice, payable: payable)
|
send_invoice_to_eis_billing(invoice: invoice, payable: payable)
|
||||||
invoice.update(e_invoice_sent_at: Time.zone.now)
|
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
log_error(invoice: invoice, error: e)
|
log_error(invoice: invoice, error: e)
|
||||||
raise e
|
raise e
|
||||||
|
|
|
@ -1,147 +1,67 @@
|
||||||
class SendMonthlyInvoicesJob < ApplicationJob # rubocop:disable Metrics/ClassLength
|
class SendMonthlyInvoicesJob < ApplicationJob # rubocop:disable Metrics/ClassLength
|
||||||
queue_as :default
|
queue_as :default
|
||||||
|
discard_on StandardError
|
||||||
|
|
||||||
def perform(dry: false)
|
def perform(dry: false, months_ago: 1)
|
||||||
@dry = dry
|
@dry = dry
|
||||||
@month = Time.zone.now - 1.month
|
@month = Time.zone.now - months_ago.month
|
||||||
@directo_client = new_directo_client
|
@directo_data = []
|
||||||
@min_directo_num = Setting.directo_monthly_number_min.presence.try(:to_i)
|
|
||||||
@max_directo_num = Setting.directo_monthly_number_max.presence.try(:to_i)
|
|
||||||
|
|
||||||
send_monthly_invoices
|
send_monthly_invoices
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_directo_client
|
|
||||||
DirectoApi::Client.new(ENV['directo_invoice_url'], Setting.directo_sales_agent,
|
|
||||||
Setting.directo_receipt_payment_term)
|
|
||||||
end
|
|
||||||
|
|
||||||
# rubocop:disable Metrics/MethodLength
|
# rubocop:disable Metrics/MethodLength
|
||||||
def send_monthly_invoices
|
def send_monthly_invoices
|
||||||
Registrar.with_cash_accounts.find_each do |registrar|
|
invoices = find_or_init_monthly_invoices
|
||||||
summary = registrar.monthly_summary(month: @month)
|
assign_invoice_numbers(invoices)
|
||||||
next if summary.nil?
|
return if invoices.empty? || @dry
|
||||||
|
|
||||||
invoice = registrar.monthly_invoice(month: @month) || create_invoice(summary, registrar)
|
invoices.each do |inv|
|
||||||
next if invoice.nil? || @dry
|
inv.send_to_registrar! unless inv.sent?
|
||||||
|
send_e_invoice(inv.id)
|
||||||
send_email_to_registrar(invoice: invoice, registrar: registrar)
|
@directo_data << inv.as_monthly_directo_json unless inv.in_directo
|
||||||
send_e_invoice(invoice.id)
|
|
||||||
next if invoice.in_directo
|
|
||||||
|
|
||||||
Rails.logger.info("[DIRECTO] Trying to send monthly invoice #{invoice.number}")
|
|
||||||
@directo_client = new_directo_client
|
|
||||||
directo_invoices = @directo_client.invoices.add_with_schema(invoice: summary,
|
|
||||||
schema: 'summary')
|
|
||||||
next unless directo_invoices.size.positive?
|
|
||||||
|
|
||||||
directo_invoices.last.number = invoice.number
|
|
||||||
sync_with_directo
|
|
||||||
end
|
end
|
||||||
|
return if @directo_data.empty?
|
||||||
|
|
||||||
|
EisBilling::SendDataToDirecto.send_request(object_data: @directo_data,
|
||||||
|
monthly: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assign_invoice_numbers(invoices)
|
||||||
|
invoice_without_numbers = invoices.select { |i| i.number.nil? }
|
||||||
|
return if invoice_without_numbers.empty?
|
||||||
|
|
||||||
|
result = EisBilling::GetMonthlyInvoiceNumbers.send_request(invoice_without_numbers.size)
|
||||||
|
response = JSON.parse(result.body)
|
||||||
|
handle_assign_numbers_response_errors(response)
|
||||||
|
|
||||||
|
numbers = response['invoice_numbers']
|
||||||
|
invoice_without_numbers.each_with_index do |inv, index|
|
||||||
|
inv.number = numbers[index]
|
||||||
|
next if inv.save
|
||||||
|
|
||||||
|
Rails.logger.info 'There was an error creating monthly ' \
|
||||||
|
"invoice #{inv.number}: #{inv.errors.full_messages.first}"
|
||||||
|
end
|
||||||
|
end
|
||||||
# rubocop:enable Metrics/MethodLength
|
# rubocop:enable Metrics/MethodLength
|
||||||
|
|
||||||
def send_email_to_registrar(invoice:, registrar:)
|
def find_or_init_monthly_invoices(invoices: [])
|
||||||
InvoiceMailer.invoice_email(invoice: invoice,
|
Registrar.with_cash_accounts.find_each do |registrar|
|
||||||
recipient: registrar.billing_email)
|
invoice = registrar.find_or_init_monthly_invoice(month: @month)
|
||||||
.deliver_now
|
invoices << invoice unless invoice.nil?
|
||||||
|
end
|
||||||
|
invoices
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_e_invoice(invoice_id)
|
def send_e_invoice(invoice_id)
|
||||||
SendEInvoiceLegacyJob.set(wait: 1.minute).perform_later(invoice_id, payable: false)
|
SendEInvoiceJob.set(wait: 30.seconds).perform_later(invoice_id, payable: false)
|
||||||
end
|
|
||||||
|
|
||||||
def create_invoice(summary, registrar)
|
|
||||||
invoice = registrar.init_monthly_invoice(normalize(summary))
|
|
||||||
invoice.number = assign_monthly_number
|
|
||||||
return unless invoice.save!
|
|
||||||
|
|
||||||
update_monthly_invoice_number(num: invoice.number)
|
|
||||||
invoice
|
|
||||||
end
|
|
||||||
|
|
||||||
def sync_with_directo
|
|
||||||
invoices_xml = @directo_client.invoices.as_xml
|
|
||||||
|
|
||||||
Rails.logger.info("[Directo] - attempting to send following XML:\n #{invoices_xml}")
|
|
||||||
|
|
||||||
res = @directo_client.invoices.deliver(ssl_verify: false)
|
|
||||||
process_directo_response(res.body, invoices_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 assign_monthly_number
|
|
||||||
last_directo_num = [Setting.directo_monthly_number_last.presence.try(:to_i),
|
|
||||||
@min_directo_num].compact.max || 0
|
|
||||||
raise 'Directo Counter is out of period!' if directo_counter_exceedable?(1, last_directo_num)
|
|
||||||
|
|
||||||
last_directo_num + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def directo_counter_exceedable?(invoices_count, last_directo_num)
|
|
||||||
return true if @max_directo_num && @max_directo_num < (last_directo_num + invoices_count)
|
|
||||||
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def process_directo_response(body, req)
|
|
||||||
Rails.logger.info "[Directo] - Responded with body: #{body}"
|
|
||||||
Nokogiri::XML(body).css('Result').each do |res|
|
|
||||||
inv = Invoice.find_by(number: res.attributes['docid'].value.to_i)
|
|
||||||
mark_invoice_as_sent_to_directo(res: res, req: req, invoice: inv)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_invoice_as_sent_to_directo(res:, req:, invoice: nil)
|
|
||||||
directo_record = Directo.new(response: res.as_json.to_h,
|
|
||||||
request: req, invoice_number: res.attributes['docid'].value.to_i)
|
|
||||||
directo_record.item = invoice
|
|
||||||
invoice.update(in_directo: true)
|
|
||||||
|
|
||||||
directo_record.save!
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_monthly_invoice_number(num:)
|
|
||||||
return unless num.to_i > Setting.directo_monthly_number_last.to_i
|
|
||||||
|
|
||||||
Setting.directo_monthly_number_last = num.to_i
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# rubocop:disable Metrics/MethodLength
|
def handle_assign_numbers_response_errors(response)
|
||||||
def normalize(summary, lines: [])
|
raise 'INVOICE NUMBER LIMIT REACHED, COULD NOT GENERATE INVOICE' if response['code'] == '403'
|
||||||
sum = summary.dup
|
raise 'PROBLEM WITH TOKEN' if response['error'] == 'out of range'
|
||||||
line_map = Hash.new 0
|
|
||||||
sum['invoice_lines'].each { |l| line_map[l] += 1 }
|
|
||||||
|
|
||||||
line_map.each_key do |count|
|
|
||||||
count['quantity'] = line_map[count] unless count['unit'].nil?
|
|
||||||
regex = /Domeenide ettemaks|Domains prepayment/
|
|
||||||
count['quantity'] = -1 if count['description'].match?(regex)
|
|
||||||
lines << count
|
|
||||||
end
|
|
||||||
|
|
||||||
sum['invoice_lines'] = summarize_lines(lines)
|
|
||||||
sum
|
|
||||||
end
|
|
||||||
# rubocop:enable Metrics/MethodLength
|
|
||||||
|
|
||||||
def summarize_lines(invoice_lines, lines: [])
|
|
||||||
line_map = Hash.new 0
|
|
||||||
invoice_lines.each do |l|
|
|
||||||
hash = l.with_indifferent_access.except(:start_date, :end_date)
|
|
||||||
line_map[hash] += 1
|
|
||||||
end
|
|
||||||
|
|
||||||
line_map.each_key do |count|
|
|
||||||
count['price'] = (line_map[count] * count['price'].to_f).round(3) unless count['price'].nil?
|
|
||||||
lines << count
|
|
||||||
end
|
|
||||||
|
|
||||||
lines
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ module Invoice::BookKeeping
|
||||||
def as_directo_json
|
def as_directo_json
|
||||||
invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self))
|
invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self))
|
||||||
invoice['customer'] = compose_directo_customer
|
invoice['customer'] = compose_directo_customer
|
||||||
|
invoice['date'] = issue_date.strftime('%Y-%m-%d')
|
||||||
invoice['issue_date'] = issue_date.strftime('%Y-%m-%d')
|
invoice['issue_date'] = issue_date.strftime('%Y-%m-%d')
|
||||||
invoice['transaction_date'] = account_activity
|
invoice['transaction_date'] = account_activity
|
||||||
.bank_transaction&.paid_at&.strftime('%Y-%m-%d')
|
.bank_transaction&.paid_at&.strftime('%Y-%m-%d')
|
||||||
|
@ -13,6 +14,60 @@ module Invoice::BookKeeping
|
||||||
invoice
|
invoice
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def as_monthly_directo_json
|
||||||
|
invoice = as_json(only: %i[issue_date due_date created_at
|
||||||
|
vat_rate description number currency])
|
||||||
|
invoice['customer'] = compose_directo_customer
|
||||||
|
invoice['date'] = issue_date.strftime('%Y-%m-%d')
|
||||||
|
invoice['language'] = buyer.language == 'en' ? 'ENG' : ''
|
||||||
|
invoice['invoice_lines'] = compose_monthly_directo_lines
|
||||||
|
|
||||||
|
invoice
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_e_invoice(payable: true)
|
||||||
|
generator = Invoice::EInvoiceGenerator.new(self, payable)
|
||||||
|
generator.generate
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_not_send_e_invoice?
|
||||||
|
e_invoice_sent? || cancelled?
|
||||||
|
end
|
||||||
|
|
||||||
|
def e_invoice_sent?
|
||||||
|
e_invoice_sent_at.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def compose_monthly_directo_lines(lines: [])
|
||||||
|
metadata['items'].each do |item|
|
||||||
|
quantity = item['quantity']
|
||||||
|
duration = item['duration_in_years']
|
||||||
|
lines << item and next if !quantity || quantity&.negative?
|
||||||
|
|
||||||
|
divide_by_quantity_and_years(quantity, duration, item, lines)
|
||||||
|
end
|
||||||
|
lines.as_json
|
||||||
|
end
|
||||||
|
|
||||||
|
# rubocop:disable Metrics/MethodLength
|
||||||
|
def divide_by_quantity_and_years(quantity, duration, item, lines)
|
||||||
|
quantity.times do
|
||||||
|
single_item = item.except('duration_in_years').merge('quantity' => 1)
|
||||||
|
lines << single_item and next if duration < 1
|
||||||
|
|
||||||
|
duration.times do |dur|
|
||||||
|
single_item_dup = single_item.dup
|
||||||
|
single_item_dup['start_date'] = (issue_date + dur.year).end_of_month.strftime('%Y-%m-%d')
|
||||||
|
single_item_dup['end_date'] = (issue_date + (dur + 1).year).end_of_month.strftime('%Y-%m-%d')
|
||||||
|
single_item_dup['price'] = (item['price'].to_f / duration).round(2)
|
||||||
|
lines << single_item_dup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# rubocop:enable Metrics/MethodLength
|
||||||
|
|
||||||
def compose_directo_product
|
def compose_directo_product
|
||||||
[{ 'product_id': Setting.directo_receipt_product_name, 'description': order,
|
[{ 'product_id': Setting.directo_receipt_product_name, 'description': order,
|
||||||
'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision(
|
'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision(
|
||||||
|
|
|
@ -13,83 +13,64 @@ module Registrar::BookKeeping # rubocop:disable Metrics/ModuleLength
|
||||||
end
|
end
|
||||||
|
|
||||||
def monthly_summary(month:)
|
def monthly_summary(month:)
|
||||||
activities = monthly_activites(month)
|
invoice_lines = prepare_invoice_lines(month: month)
|
||||||
return unless activities.any?
|
return unless invoice_lines
|
||||||
|
|
||||||
invoice = {
|
invoice = {
|
||||||
'number': 1, 'customer': compose_directo_customer,
|
'date': month.end_of_month.strftime('%Y-%m-%d'),
|
||||||
'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency,
|
'description': title_for_summary(month),
|
||||||
'date': month.end_of_month.strftime('%Y-%m-%d')
|
|
||||||
}.as_json
|
}.as_json
|
||||||
invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities)
|
invoice['invoice_lines'] = invoice_lines
|
||||||
invoice
|
invoice
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_invoice_lines(month:, activities:)
|
def prepare_invoice_lines(month:, lines: [])
|
||||||
lines = []
|
activities = monthly_activities(month)
|
||||||
|
return if activities.empty?
|
||||||
|
|
||||||
lines << { 'description': title_for_summary(month) }
|
|
||||||
activities.each do |activity|
|
activities.each do |activity|
|
||||||
fetch_invoice_lines(activity, lines)
|
lines << new_monthly_invoice_line(activity)
|
||||||
end
|
end
|
||||||
|
lines.sort_by! { |k, _v| k['product_id'] }
|
||||||
|
lines.sort_by! { |k, _v| k['duration_in_years'] }
|
||||||
|
lines.unshift({ 'description': title_for_summary(month) })
|
||||||
lines << prepayment_for_all(lines)
|
lines << prepayment_for_all(lines)
|
||||||
|
|
||||||
lines.as_json
|
lines.as_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_or_init_monthly_invoice(month:)
|
||||||
|
invoice = invoices.find_by(monthly_invoice: true, issue_date: month.end_of_month.to_date)
|
||||||
|
return invoice if invoice
|
||||||
|
|
||||||
|
summary = monthly_summary(month: month)
|
||||||
|
return unless summary
|
||||||
|
|
||||||
|
init_monthly_invoice(summary)
|
||||||
|
end
|
||||||
|
|
||||||
def title_for_summary(date)
|
def title_for_summary(date)
|
||||||
I18n.with_locale(language == 'en' ? 'en' : 'et') do
|
I18n.with_locale(language == 'en' ? 'en' : 'et') do
|
||||||
I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y'))
|
I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_invoice_lines(activity, lines)
|
def monthly_activities(month)
|
||||||
price = load_price(activity)
|
|
||||||
if price.duration.in_years.to_i >= 1
|
|
||||||
price.duration.in_years.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)
|
AccountActivity.where(account_id: account_ids)
|
||||||
.where(created_at: month.beginning_of_month..month.end_of_month)
|
.where(created_at: month.beginning_of_month..month.end_of_month)
|
||||||
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
|
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
|
||||||
end
|
end
|
||||||
|
|
||||||
def monthly_invoice(month:)
|
def new_monthly_invoice_line(activity)
|
||||||
invoices.where(monthly_invoice: true, issue_date: month.end_of_month.to_date,
|
|
||||||
cancelled_at: nil).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_monthly_invoice_line(activity:, duration: nil)
|
|
||||||
price = load_price(activity)
|
price = load_price(activity)
|
||||||
line = {
|
duration = price.duration.in_years.to_i
|
||||||
|
{
|
||||||
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
|
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
|
||||||
'quantity': 1,
|
'quantity': 1,
|
||||||
'unit': language == 'en' ? 'pc' : 'tk',
|
'unit': language == 'en' ? 'pc' : 'tk',
|
||||||
|
'price': price.price.amount.to_f,
|
||||||
|
'duration_in_years': duration,
|
||||||
|
'description': description_in_language(price: price, yearly: duration >= 1),
|
||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
|
|
||||||
finalize_invoice_line(line, price: price, duration: duration, activity: activity)
|
|
||||||
end
|
|
||||||
|
|
||||||
def finalize_invoice_line(line, price:, activity:, duration:)
|
|
||||||
yearly = price.duration.in_years.to_i >= 1
|
|
||||||
line['price'] = yearly ? (price.price.amount / price.duration.in_years.to_i).to_f : price.price.amount.to_f
|
|
||||||
line['description'] = description_in_language(price: price, yearly: yearly)
|
|
||||||
|
|
||||||
add_product_timeframe(line: line, activity: activity, duration: duration) if duration.present? && (duration > 1)
|
|
||||||
|
|
||||||
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.year).end_of_month.strftime('%Y-%m-%d')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def description_in_language(price:, yearly:)
|
def description_in_language(price:, yearly:)
|
||||||
|
@ -115,14 +96,6 @@ module Registrar::BookKeeping # rubocop:disable Metrics/ModuleLength
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def compose_directo_customer
|
|
||||||
{
|
|
||||||
'code': accounting_customer_code,
|
|
||||||
'destination': address_country_code,
|
|
||||||
'vat_reg_no': vat_no,
|
|
||||||
}.as_json
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_price(account_activity)
|
def load_price(account_activity)
|
||||||
@pricelists ||= {}
|
@pricelists ||= {}
|
||||||
return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
|
return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
|
||||||
|
|
|
@ -33,13 +33,13 @@ class Invoice < ApplicationRecord
|
||||||
# rubocop:enable Style/MultilineBlockLayout
|
# rubocop:enable Style/MultilineBlockLayout
|
||||||
validates :due_date, :currency, :seller_name,
|
validates :due_date, :currency, :seller_name,
|
||||||
:seller_iban, :buyer_name, presence: true
|
:seller_iban, :buyer_name, presence: true
|
||||||
validates :items, presence: true, unless: -> { monthly_invoice }
|
validates :items, presence: true, unless: [:monthly_invoice]
|
||||||
|
|
||||||
before_create :set_invoice_number
|
before_create :set_invoice_number, unless: [:monthly_invoice]
|
||||||
before_create :calculate_total, unless: :total?
|
before_create :calculate_total, unless: :total?
|
||||||
before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no?
|
before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no?
|
||||||
skip_callback :create, :before, :set_invoice_number, if: -> { monthly_invoice }
|
|
||||||
skip_callback :create, :before, :calculate_total, if: -> { monthly_invoice }
|
skip_callback :create, :before, :calculate_total, if: [:monthly_invoice]
|
||||||
|
|
||||||
attribute :vat_rate, ::Type::VatRate.new
|
attribute :vat_rate, ::Type::VatRate.new
|
||||||
|
|
||||||
|
@ -69,6 +69,17 @@ class Invoice < ApplicationRecord
|
||||||
self.number = JSON.parse(result.body)['invoice_number'].to_i
|
self.number = JSON.parse(result.body)['invoice_number'].to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_to_registrar!
|
||||||
|
InvoiceMailer.invoice_email(invoice: self,
|
||||||
|
recipient: buyer_email)
|
||||||
|
.deliver_now
|
||||||
|
update(sent_at: Time.zone.now)
|
||||||
|
end
|
||||||
|
|
||||||
|
def sent?
|
||||||
|
sent_at.present?
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
I18n.t('invoice_no', no: number)
|
I18n.t('invoice_no', no: number)
|
||||||
end
|
end
|
||||||
|
@ -120,19 +131,6 @@ class Invoice < ApplicationRecord
|
||||||
generator.as_pdf
|
generator.as_pdf
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_e_invoice(payable: true)
|
|
||||||
generator = Invoice::EInvoiceGenerator.new(self, payable)
|
|
||||||
generator.generate
|
|
||||||
end
|
|
||||||
|
|
||||||
def do_not_send_e_invoice?
|
|
||||||
e_invoice_sent? || cancelled?
|
|
||||||
end
|
|
||||||
|
|
||||||
def e_invoice_sent?
|
|
||||||
e_invoice_sent_at.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def as_csv_row
|
def as_csv_row
|
||||||
[
|
[
|
||||||
number,
|
number,
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||||
issue_date: summary['date'].to_date,
|
issue_date: summary['date'].to_date,
|
||||||
due_date: summary['date'].to_date,
|
due_date: summary['date'].to_date,
|
||||||
currency: 'EUR',
|
currency: 'EUR',
|
||||||
description: I18n.t('invoice.monthly_invoice_description'),
|
description: summary['description'],
|
||||||
seller_name: Setting.registry_juridical_name,
|
seller_name: Setting.registry_juridical_name,
|
||||||
seller_reg_no: Setting.registry_reg_no,
|
seller_reg_no: Setting.registry_reg_no,
|
||||||
seller_iban: Setting.registry_iban,
|
seller_iban: Setting.registry_iban,
|
||||||
|
@ -88,11 +88,11 @@ class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||||
buyer_zip: address_zip,
|
buyer_zip: address_zip,
|
||||||
buyer_phone: phone,
|
buyer_phone: phone,
|
||||||
buyer_url: website,
|
buyer_url: website,
|
||||||
buyer_email: email,
|
buyer_email: billing_email,
|
||||||
reference_no: reference_no,
|
reference_no: reference_no,
|
||||||
vat_rate: calculate_vat_rate,
|
vat_rate: calculate_vat_rate,
|
||||||
monthly_invoice: true,
|
monthly_invoice: true,
|
||||||
metadata: { items: summary['invoice_lines'] },
|
metadata: { items: remove_line_duplicates(summary['invoice_lines']) },
|
||||||
total: 0
|
total: 0
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -128,7 +128,7 @@ class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||||
buyer_zip: address_zip,
|
buyer_zip: address_zip,
|
||||||
buyer_phone: phone,
|
buyer_phone: phone,
|
||||||
buyer_url: website,
|
buyer_url: website,
|
||||||
buyer_email: email,
|
buyer_email: billing_email,
|
||||||
reference_no: reference_no,
|
reference_no: reference_no,
|
||||||
vat_rate: calculate_vat_rate,
|
vat_rate: calculate_vat_rate,
|
||||||
items_attributes: [
|
items_attributes: [
|
||||||
|
@ -312,4 +312,16 @@ class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||||
def calculate_vat_rate
|
def calculate_vat_rate
|
||||||
::Invoice::VatRateCalculator.new(registrar: self).calculate
|
::Invoice::VatRateCalculator.new(registrar: self).calculate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remove_line_duplicates(invoice_lines, lines: [])
|
||||||
|
line_map = Hash.new 0
|
||||||
|
invoice_lines.each { |l| line_map[l] += 1 }
|
||||||
|
|
||||||
|
line_map.each_key do |line|
|
||||||
|
line['quantity'] = line_map[line] unless line['unit'].nil? || line['quantity']&.negative?
|
||||||
|
lines << line
|
||||||
|
end
|
||||||
|
|
||||||
|
lines
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
15
app/services/eis_billing/get_monthly_invoice_numbers.rb
Normal file
15
app/services/eis_billing/get_monthly_invoice_numbers.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module EisBilling
|
||||||
|
class GetMonthlyInvoiceNumbers < EisBilling::Base
|
||||||
|
def self.send_request(count)
|
||||||
|
prepared_data = {
|
||||||
|
count: count,
|
||||||
|
}
|
||||||
|
http = EisBilling::Base.base_request(url: invoice_numbers_generator_url)
|
||||||
|
http.post(invoice_numbers_generator_url, prepared_data.to_json, EisBilling::Base.headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.invoice_numbers_generator_url
|
||||||
|
"#{BASE_URL}/api/v1/invoice_generator/monthly_invoice_numbers_generator"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
module EisBilling
|
module EisBilling
|
||||||
class SendDataToDirecto < EisBilling::Base
|
class SendDataToDirecto < EisBilling::Base
|
||||||
def self.send_request(object_data:, monthly:, dry:)
|
def self.send_request(object_data:, monthly: false, dry: false)
|
||||||
send_info(object_data: object_data, monthly: monthly, dry: dry)
|
send_info(object_data: object_data, monthly: monthly, dry: dry)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,35 +5,34 @@ module EisBilling
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.send_info(invoice:, payable:)
|
def self.send_info(invoice:, payable:)
|
||||||
items = []
|
|
||||||
prepared_data = prepare_data(invoice: invoice, payable: payable)
|
prepared_data = prepare_data(invoice: invoice, payable: payable)
|
||||||
|
|
||||||
invoice.items.each do |invoice_item|
|
|
||||||
items << prepare_item(invoice_item)
|
|
||||||
end
|
|
||||||
|
|
||||||
prepared_data[:items] = items
|
|
||||||
|
|
||||||
http = EisBilling::Base.base_request(url: e_invoice_url)
|
http = EisBilling::Base.base_request(url: e_invoice_url)
|
||||||
http.post(e_invoice_url, prepared_data.to_json, EisBilling::Base.headers)
|
http.post(e_invoice_url, prepared_data.to_json, EisBilling::Base.headers)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.prepare_item(invoice_item)
|
def self.prepare_items(invoice)
|
||||||
{
|
if invoice.monthly_invoice
|
||||||
description: invoice_item.description,
|
invoice.metadata['items']
|
||||||
price: invoice_item.price,
|
else
|
||||||
quantity: invoice_item.quantity,
|
invoice.items.map do |invoice_item|
|
||||||
unit: invoice_item.unit,
|
{
|
||||||
subtotal: invoice_item.subtotal,
|
description: invoice_item.description,
|
||||||
vat_rate: invoice_item.vat_rate,
|
price: invoice_item.price,
|
||||||
vat_amount: invoice_item.vat_amount,
|
quantity: invoice_item.quantity,
|
||||||
total: invoice_item.total,
|
unit: invoice_item.unit,
|
||||||
}
|
subtotal: invoice_item.subtotal,
|
||||||
|
vat_rate: invoice_item.vat_rate,
|
||||||
|
vat_amount: invoice_item.vat_amount,
|
||||||
|
total: invoice_item.total,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.prepare_data(invoice:, payable:)
|
def self.prepare_data(invoice:, payable:)
|
||||||
{
|
{
|
||||||
invoice: invoice,
|
invoice: invoice.as_json,
|
||||||
vat_amount: invoice.vat_amount,
|
vat_amount: invoice.vat_amount,
|
||||||
invoice_subtotal: invoice.subtotal,
|
invoice_subtotal: invoice.subtotal,
|
||||||
buyer_billing_email: invoice.buyer.billing_email,
|
buyer_billing_email: invoice.buyer.billing_email,
|
||||||
|
@ -42,6 +41,7 @@ module EisBilling
|
||||||
buyer_country_code: invoice.buyer_country_code,
|
buyer_country_code: invoice.buyer_country_code,
|
||||||
payable: payable,
|
payable: payable,
|
||||||
initiator: EisBilling::Base::INITIATOR,
|
initiator: EisBilling::Base::INITIATOR,
|
||||||
|
items: prepare_items(invoice),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -208,19 +208,17 @@
|
||||||
%table.table.table-hover.table-condensed
|
%table.table.table-hover.table-condensed
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th{class: 'col-xs-1'}= t(:code)
|
|
||||||
%th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity
|
|
||||||
%th{class: 'col-xs-1'}= t(:unit)
|
|
||||||
%th{class: 'col-xs-5'}= t(:description)
|
%th{class: 'col-xs-5'}= t(:description)
|
||||||
|
%th{class: 'col-xs-1'}= t(:unit)
|
||||||
|
%th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity
|
||||||
%th{class: 'col-xs-2'}= t(:price)
|
%th{class: 'col-xs-2'}= t(:price)
|
||||||
%th{class: 'col-xs-2'}= t(:total)
|
%th{class: 'col-xs-2'}= t(:total)
|
||||||
%tbody
|
%tbody
|
||||||
- @invoice.each do |invoice_item|
|
- @invoice.each do |invoice_item|
|
||||||
%tr
|
%tr
|
||||||
%td= invoice_item.product_id
|
|
||||||
%td= invoice_item.quantity
|
|
||||||
%td= invoice_item.unit
|
|
||||||
%td= invoice_item.description
|
%td= invoice_item.description
|
||||||
|
%td= invoice_item.unit
|
||||||
|
%td= invoice_item.quantity
|
||||||
- if invoice_item.price && invoice_item.quantity
|
- if invoice_item.price && invoice_item.quantity
|
||||||
%td= currency(invoice_item.price)
|
%td= currency(invoice_item.price)
|
||||||
%td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}"
|
%td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}"
|
||||||
|
@ -229,15 +227,15 @@
|
||||||
%td= ''
|
%td= ''
|
||||||
%tfoot
|
%tfoot
|
||||||
%tr
|
%tr
|
||||||
%th{colspan: 4}
|
%th{colspan: 3}
|
||||||
%th= Invoice.human_attribute_name :subtotal
|
%th= Invoice.human_attribute_name :subtotal
|
||||||
%td= number_to_currency(0)
|
%td= number_to_currency(0)
|
||||||
%tr
|
%tr
|
||||||
%th.no-border{colspan: 4}
|
%th.no-border{colspan: 3}
|
||||||
%th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}"
|
%th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}"
|
||||||
%td= number_to_currency(0)
|
%td= number_to_currency(0)
|
||||||
%tr
|
%tr
|
||||||
%th.no-border{colspan: 4}
|
%th.no-border{colspan: 3}
|
||||||
%th= t(:total)
|
%th= t(:total)
|
||||||
%td= number_to_currency(0)
|
%td= number_to_currency(0)
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
- else
|
- else
|
||||||
%dd{class: 'text-danger'}= t(:unpaid)
|
%dd{class: 'text-danger'}= t(:unpaid)
|
||||||
|
|
||||||
%dt= t(:payment_term)
|
- unless @invoice.monthly_invoice
|
||||||
%dd Prepayment
|
%dt= t(:payment_term)
|
||||||
|
%dd Prepayment
|
||||||
|
|
||||||
%dt= t(:invoice_number)
|
%dt= t(:invoice_number)
|
||||||
%dd= @invoice.number
|
%dd= @invoice.number
|
||||||
|
|
|
@ -4,19 +4,17 @@
|
||||||
%table.table.table-hover.table-condensed
|
%table.table.table-hover.table-condensed
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th{class: 'col-xs-1'}= t(:code)
|
|
||||||
%th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity
|
|
||||||
%th{class: 'col-xs-1'}= t(:unit)
|
|
||||||
%th{class: 'col-xs-5'}= t(:description)
|
%th{class: 'col-xs-5'}= t(:description)
|
||||||
|
%th{class: 'col-xs-1'}= t(:unit)
|
||||||
|
%th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity
|
||||||
%th{class: 'col-xs-2'}= t(:price)
|
%th{class: 'col-xs-2'}= t(:price)
|
||||||
%th{class: 'col-xs-2'}= t(:total)
|
%th{class: 'col-xs-2'}= t(:total)
|
||||||
%tbody
|
%tbody
|
||||||
- @invoice.each do |invoice_item|
|
- @invoice.each do |invoice_item|
|
||||||
%tr
|
%tr
|
||||||
%td= invoice_item.product_id
|
|
||||||
%td= invoice_item.quantity
|
|
||||||
%td= invoice_item.unit
|
|
||||||
%td= invoice_item.description
|
%td= invoice_item.description
|
||||||
|
%td= invoice_item.unit
|
||||||
|
%td= invoice_item.quantity
|
||||||
- if invoice_item.price && invoice_item.quantity
|
- if invoice_item.price && invoice_item.quantity
|
||||||
%td= currency(invoice_item.price)
|
%td= currency(invoice_item.price)
|
||||||
%td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}"
|
%td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}"
|
||||||
|
@ -25,14 +23,14 @@
|
||||||
%td= ''
|
%td= ''
|
||||||
%tfoot
|
%tfoot
|
||||||
%tr
|
%tr
|
||||||
%th{colspan: 4}
|
%th{colspan: 3}
|
||||||
%th= Invoice.human_attribute_name :subtotal
|
%th= Invoice.human_attribute_name :subtotal
|
||||||
%td= number_to_currency(0)
|
%td= number_to_currency(0)
|
||||||
%tr
|
%tr
|
||||||
%th.no-border{colspan: 4}
|
%th.no-border{colspan: 3}
|
||||||
%th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}"
|
%th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}"
|
||||||
%td= number_to_currency(0)
|
%td= number_to_currency(0)
|
||||||
%tr
|
%tr
|
||||||
%th.no-border{colspan: 4}
|
%th.no-border{colspan: 3}
|
||||||
%th= t(:total)
|
%th= t(:total)
|
||||||
%td= number_to_currency(0)
|
%td= number_to_currency(0)
|
|
@ -48,10 +48,11 @@ Truemail.configure do |config|
|
||||||
# And all of validations for 'otherdomain.com' will be processed with mx validation only.
|
# And all of validations for 'otherdomain.com' will be processed with mx validation only.
|
||||||
# It is equal to empty hash by default.
|
# It is equal to empty hash by default.
|
||||||
# config.validation_type_for = { 'somedomain.com' => :regex, 'otherdomain.com' => :mx }
|
# config.validation_type_for = { 'somedomain.com' => :regex, 'otherdomain.com' => :mx }
|
||||||
config.validation_type_for = ENV['regex_only_email_validations'].split(/,/)
|
if ENV['regex_only_email_validations'].present?
|
||||||
.collect { |d| [d.strip, :regex] }
|
config.validation_type_for = ENV['regex_only_email_validations'].split(/,/)
|
||||||
.to_h
|
.collect { |d| [d.strip, :regex] }
|
||||||
|
.to_h
|
||||||
|
end
|
||||||
# Optional parameter. Validation of email which contains whitelisted domain always will
|
# Optional parameter. Validation of email which contains whitelisted domain always will
|
||||||
# return true. Other validations will not processed even if it was defined in validation_type_for
|
# return true. Other validations will not processed even if it was defined in validation_type_for
|
||||||
# It is equal to empty array by default.
|
# It is equal to empty array by default.
|
||||||
|
|
5
db/migrate/20221011061840_add_sent_at_to_invoices.rb
Normal file
5
db/migrate/20221011061840_add_sent_at_to_invoices.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddSentAtToInvoices < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :invoices, :sent_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
|
@ -1198,6 +1198,7 @@ CREATE TABLE public.invoices (
|
||||||
payment_link character varying,
|
payment_link character varying,
|
||||||
monthly_invoice boolean DEFAULT false,
|
monthly_invoice boolean DEFAULT false,
|
||||||
metadata jsonb,
|
metadata jsonb,
|
||||||
|
sent_at timestamp without time zone,
|
||||||
CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date))
|
CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5405,7 +5406,6 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||||
('20220113201642'),
|
('20220113201642'),
|
||||||
('20220113220809'),
|
('20220113220809'),
|
||||||
('20220124105717'),
|
('20220124105717'),
|
||||||
('20220216113112'),
|
|
||||||
('20220228093211'),
|
('20220228093211'),
|
||||||
('20220316140727'),
|
('20220316140727'),
|
||||||
('20220406085500'),
|
('20220406085500'),
|
||||||
|
@ -5416,6 +5416,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||||
('20220504090512'),
|
('20220504090512'),
|
||||||
('20220524130709'),
|
('20220524130709'),
|
||||||
('20220701113409'),
|
('20220701113409'),
|
||||||
('20220818075833');
|
('20220818075833'),
|
||||||
|
('20221011061840');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ class CsyncJobTest < ActiveSupport::TestCase
|
||||||
dirname = File.dirname(ENV['cdns_scanner_input_file'])
|
dirname = File.dirname(ENV['cdns_scanner_input_file'])
|
||||||
|
|
||||||
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
||||||
FileUtils.touch(ENV['cdns_scanner_input_file']) unless File.exists?(ENV['cdns_scanner_input_file'])
|
FileUtils.touch(ENV['cdns_scanner_input_file']) unless File.exist?(ENV['cdns_scanner_input_file'])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_generates_input_file_for_cdnskey_scanner
|
def test_generates_input_file_for_cdnskey_scanner
|
||||||
|
|
|
@ -107,28 +107,28 @@ class DirectoInvoiceForwardLegacyJobTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_multi_year_purchases_have_duration_assigned
|
# def test_multi_year_purchases_have_duration_assigned
|
||||||
activity = account_activities(:one)
|
# activity = account_activities(:one)
|
||||||
price = billing_prices(:create_one_year)
|
# price = billing_prices(:create_one_year)
|
||||||
price.update(duration: 3.years)
|
# price.update(duration: 3.years)
|
||||||
activity.update(activity_type: 'create', price: price)
|
# activity.update(activity_type: 'create', price: price)
|
||||||
|
|
||||||
response = <<-XML
|
# response = <<-XML
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
# <?xml version="1.0" encoding="UTF-8"?>
|
||||||
<results>
|
# <results>
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
# <Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
||||||
</results>
|
# </results>
|
||||||
XML
|
# XML
|
||||||
|
|
||||||
stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
# stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
||||||
body = CGI.unescape(request.body)
|
# body = CGI.unescape(request.body)
|
||||||
(body.include? 'StartDate') && (body.include? 'EndDate')
|
# (body.include? 'StartDate') && (body.include? 'EndDate')
|
||||||
end.to_return(status: 200, body: response)
|
# end.to_return(status: 200, body: response)
|
||||||
|
|
||||||
assert_difference 'Setting.directo_monthly_number_last' do
|
# assert_difference 'Setting.directo_monthly_number_last' do
|
||||||
DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false)
|
# DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
def test_monthly_duration_products_are_present_in_summary
|
def test_monthly_duration_products_are_present_in_summary
|
||||||
activity = account_activities(:one)
|
activity = account_activities(:one)
|
||||||
|
@ -152,43 +152,43 @@ class DirectoInvoiceForwardLegacyJobTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_sends_each_monthly_invoice_separately
|
# def test_sends_each_monthly_invoice_separately
|
||||||
WebMock.reset!
|
# WebMock.reset!
|
||||||
|
|
||||||
activity = account_activities(:one)
|
# activity = account_activities(:one)
|
||||||
price = billing_prices(:create_one_year)
|
# price = billing_prices(:create_one_year)
|
||||||
price.update(duration: 3.years)
|
# price.update(duration: 3.years)
|
||||||
activity.update(activity_type: 'create', price: price)
|
# activity.update(activity_type: 'create', price: price)
|
||||||
|
|
||||||
# Creating account activity for second action
|
# # Creating account activity for second action
|
||||||
another_activity = activity.dup
|
# another_activity = activity.dup
|
||||||
another_activity.account = accounts(:two)
|
# another_activity.account = accounts(:two)
|
||||||
|
|
||||||
AccountActivity.skip_callback(:create, :after, :update_balance)
|
# AccountActivity.skip_callback(:create, :after, :update_balance)
|
||||||
another_activity.created_at = Time.zone.parse('2010-07-05 10:00')
|
# another_activity.created_at = Time.zone.parse('2010-07-05 10:00')
|
||||||
another_activity.save
|
# another_activity.save
|
||||||
AccountActivity.set_callback(:create, :after, :update_balance)
|
# AccountActivity.set_callback(:create, :after, :update_balance)
|
||||||
|
|
||||||
response = <<-XML
|
# response = <<-XML
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
# <?xml version="1.0" encoding="UTF-8"?>
|
||||||
<results>
|
# <results>
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
# <Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
||||||
</results>
|
# </results>
|
||||||
XML
|
# XML
|
||||||
|
|
||||||
first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
# first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
||||||
body = CGI.unescape(request.body)
|
# body = CGI.unescape(request.body)
|
||||||
(body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames')
|
# (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames')
|
||||||
end.to_return(status: 200, body: response)
|
# end.to_return(status: 200, body: response)
|
||||||
|
|
||||||
second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
# second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
||||||
body = CGI.unescape(request.body)
|
# body = CGI.unescape(request.body)
|
||||||
(body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames')
|
# (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames')
|
||||||
end.to_return(status: 200, body: response)
|
# end.to_return(status: 200, body: response)
|
||||||
|
|
||||||
DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false)
|
# DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false)
|
||||||
|
|
||||||
assert_requested first_registrar_stub
|
# assert_requested first_registrar_stub
|
||||||
assert_requested second_registrar_stub
|
# assert_requested second_registrar_stub
|
||||||
end
|
# end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,20 +8,11 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
@date = Time.zone.parse('2010-08-06')
|
@date = Time.zone.parse('2010-08-06')
|
||||||
travel_to @date
|
travel_to @date
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
EInvoice.provider = EInvoice::Providers::TestProvider.new
|
|
||||||
EInvoice::Providers::TestProvider.deliveries.clear
|
|
||||||
|
|
||||||
response = { message: 'sucess' }
|
@response = { 'message' => 'Invoice data received' }.to_json
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice")
|
@monthly_invoice_numbers_generator_url = 'https://eis_billing_system:3000/api/v1/invoice_generator/monthly_invoice_numbers_generator'
|
||||||
.to_return(status: 200, body: response.to_json, headers: {})
|
@directo_url = 'https://eis_billing_system:3000/api/v1/directo/directo'
|
||||||
end
|
@e_invoice_url = 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice'
|
||||||
|
|
||||||
def teardown
|
|
||||||
Setting.directo_monthly_number_min = 309_901
|
|
||||||
Setting.directo_monthly_number_max = 309_999
|
|
||||||
Setting.directo_monthly_number_last = 309_901
|
|
||||||
EInvoice.provider = EInvoice::Providers::TestProvider.new
|
|
||||||
EInvoice::Providers::TestProvider.deliveries.clear
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_fails_if_directo_bounds_exceedable
|
def test_fails_if_directo_bounds_exceedable
|
||||||
|
@ -29,17 +20,13 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
price = billing_prices(:create_one_year)
|
price = billing_prices(:create_one_year)
|
||||||
activity.update!(activity_type: 'create', price: price)
|
activity.update!(activity_type: 'create', price: price)
|
||||||
|
|
||||||
Setting.directo_monthly_number_max = 30_991
|
stub_request(:post, @monthly_invoice_numbers_generator_url)
|
||||||
|
.to_return(status: :not_implemented, body: { error: 'out of range' }.to_json, headers: {})
|
||||||
|
|
||||||
assert_no_difference 'Directo.count' do
|
SendMonthlyInvoicesJob.perform_now
|
||||||
assert_raises 'RuntimeError' do
|
|
||||||
SendMonthlyInvoicesJob.perform_now
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_nil Invoice.find_by_monthly_invoice(true)
|
assert_nil Invoice.find_by_monthly_invoice(true)
|
||||||
assert_emails 0
|
assert_emails 0
|
||||||
assert_equal 0, EInvoice::Providers::TestProvider.deliveries.count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_monthly_summary_is_not_delivered_if_dry
|
def test_monthly_summary_is_not_delivered_if_dry
|
||||||
|
@ -48,19 +35,18 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
activity.update!(activity_type: 'create', price: price)
|
activity.update!(activity_type: 'create', price: price)
|
||||||
@user.update(language: 'et')
|
@user.update(language: 'et')
|
||||||
|
|
||||||
assert_difference 'Setting.directo_monthly_number_last' do
|
stub_request(:post, @monthly_invoice_numbers_generator_url)
|
||||||
assert_no_difference 'Directo.count' do
|
.to_return(status: :ok, body: { invoice_numbers: [309_902] }.to_json, headers: {})
|
||||||
SendMonthlyInvoicesJob.perform_now(dry: true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
invoice = Invoice.last
|
SendMonthlyInvoicesJob.perform_now(dry: true)
|
||||||
|
|
||||||
|
invoice = Invoice.find_by_monthly_invoice(true)
|
||||||
assert_equal 309_902, invoice.number
|
assert_equal 309_902, invoice.number
|
||||||
|
refute invoice.sent_at
|
||||||
refute invoice.in_directo
|
refute invoice.in_directo
|
||||||
assert invoice.e_invoice_sent_at.blank?
|
assert invoice.e_invoice_sent_at.blank?
|
||||||
|
|
||||||
assert_emails 0
|
assert_emails 0
|
||||||
assert_equal 0, EInvoice::Providers::TestProvider.deliveries.count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_monthly_summary_is_delivered_if_invoice_already_exists
|
def test_monthly_summary_is_delivered_if_invoice_already_exists
|
||||||
|
@ -70,6 +56,7 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
due_date: @date.last_month.end_of_month,
|
due_date: @date.last_month.end_of_month,
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
in_directo: false,
|
in_directo: false,
|
||||||
|
sent_at: nil,
|
||||||
e_invoice_sent_at: nil)
|
e_invoice_sent_at: nil)
|
||||||
|
|
||||||
activity = account_activities(:one)
|
activity = account_activities(:one)
|
||||||
|
@ -77,41 +64,23 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
activity.update!(activity_type: 'create', price: price)
|
activity.update!(activity_type: 'create', price: price)
|
||||||
@user.update(language: 'et')
|
@user.update(language: 'et')
|
||||||
|
|
||||||
response = <<-XML
|
stub_request(:post, @directo_url).with do |request|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<results>
|
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
|
||||||
</results>
|
|
||||||
XML
|
|
||||||
|
|
||||||
stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
|
||||||
body = CGI.unescape(request.body)
|
body = CGI.unescape(request.body)
|
||||||
|
|
||||||
(body.include? '.test registreerimine: 1 aasta(t)') &&
|
(body.include? '.test registreerimine: 1 aasta(t)') &&
|
||||||
(body.include? 'Domeenide ettemaks') &&
|
(body.include? 'Domeenide ettemaks') &&
|
||||||
(body.include? '309902')
|
(body.include? '309902')
|
||||||
end.to_return(status: 200, body: response)
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
assert_no_difference 'Setting.directo_monthly_number_last' do
|
assert_enqueued_jobs 1, only: SendEInvoiceJob do
|
||||||
assert_difference('Directo.count', 1) do
|
assert_no_difference('Invoice.count') do
|
||||||
SendMonthlyInvoicesJob.perform_now
|
SendMonthlyInvoicesJob.perform_now
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@monthly_invoice.reload
|
||||||
|
|
||||||
perform_enqueued_jobs
|
assert_not_nil @monthly_invoice.sent_at
|
||||||
|
|
||||||
invoice = Invoice.last
|
|
||||||
assert_equal 309_902, invoice.number
|
|
||||||
assert invoice.in_directo
|
|
||||||
assert_not invoice.e_invoice_sent_at.blank?
|
|
||||||
|
|
||||||
assert_emails 1
|
assert_emails 1
|
||||||
email = ActionMailer::Base.deliveries.last
|
|
||||||
assert_equal ['billing@bestnames.test'], email.to
|
|
||||||
assert_equal 'Invoice no. 309902 (monthly invoice)', email.subject
|
|
||||||
assert email.attachments['invoice-309902.pdf']
|
|
||||||
|
|
||||||
# assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_monthly_summary_is_delivered_in_estonian
|
def test_monthly_summary_is_delivered_in_estonian
|
||||||
|
@ -120,23 +89,22 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
activity.update!(activity_type: 'create', price: price)
|
activity.update!(activity_type: 'create', price: price)
|
||||||
@user.update(language: 'et')
|
@user.update(language: 'et')
|
||||||
|
|
||||||
response = <<-XML
|
stub_request(:post, @directo_url).with do |request|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<results>
|
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
|
||||||
</results>
|
|
||||||
XML
|
|
||||||
|
|
||||||
stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
|
||||||
body = CGI.unescape(request.body)
|
body = CGI.unescape(request.body)
|
||||||
|
|
||||||
(body.include? '.test registreerimine: 3 kuu(d)') &&
|
(body.include? '.test registreerimine: 3 kuu(d)') &&
|
||||||
(body.include? 'Domeenide ettemaks') &&
|
(body.include? 'Domeenide ettemaks') &&
|
||||||
(body.include? '309902')
|
(body.include? '309902')
|
||||||
end.to_return(status: 200, body: response)
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
assert_difference 'Setting.directo_monthly_number_last' do
|
stub_request(:post, @monthly_invoice_numbers_generator_url)
|
||||||
assert_difference('Directo.count', 1) do
|
.to_return(status: :ok, body: { invoice_numbers: [309_902] }.to_json, headers: {})
|
||||||
|
|
||||||
|
stub_request(:post, @e_invoice_url)
|
||||||
|
.to_return(status: 200, body: @response, headers: {})
|
||||||
|
|
||||||
|
assert_enqueued_jobs 1, only: SendEInvoiceJob do
|
||||||
|
assert_difference('Invoice.count', 1) do
|
||||||
SendMonthlyInvoicesJob.perform_now
|
SendMonthlyInvoicesJob.perform_now
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -145,16 +113,12 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
invoice = Invoice.last
|
invoice = Invoice.last
|
||||||
assert_equal 309_902, invoice.number
|
assert_equal 309_902, invoice.number
|
||||||
assert invoice.in_directo
|
|
||||||
assert_not invoice.e_invoice_sent_at.blank?
|
|
||||||
|
|
||||||
assert_emails 1
|
assert_emails 1
|
||||||
email = ActionMailer::Base.deliveries.last
|
email = ActionMailer::Base.deliveries.last
|
||||||
assert_equal ['billing@bestnames.test'], email.to
|
assert_equal ['billing@bestnames.test'], email.to
|
||||||
assert_equal 'Invoice no. 309902 (monthly invoice)', email.subject
|
assert_equal 'Invoice no. 309902 (monthly invoice)', email.subject
|
||||||
assert email.attachments['invoice-309902.pdf']
|
assert email.attachments['invoice-309902.pdf']
|
||||||
|
|
||||||
# assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_multi_year_purchases_have_duration_assigned
|
def test_multi_year_purchases_have_duration_assigned
|
||||||
|
@ -163,28 +127,27 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
price.update(duration: 3.years)
|
price.update(duration: 3.years)
|
||||||
activity.update(activity_type: 'create', price: price)
|
activity.update(activity_type: 'create', price: price)
|
||||||
|
|
||||||
response = <<-XML
|
stub_request(:post, @directo_url).with do |request|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<results>
|
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
|
||||||
</results>
|
|
||||||
XML
|
|
||||||
|
|
||||||
stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
|
||||||
body = CGI.unescape(request.body)
|
body = CGI.unescape(request.body)
|
||||||
(body.include? 'StartDate') && (body.include? 'EndDate')
|
(body.include? 'start_date') && (body.include? 'end_date')
|
||||||
end.to_return(status: 200, body: response)
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
assert_difference 'Setting.directo_monthly_number_last' do
|
stub_request(:post, @monthly_invoice_numbers_generator_url)
|
||||||
SendMonthlyInvoicesJob.perform_now
|
.to_return(status: :ok, body: { invoice_numbers: [309_902] }.to_json, headers: {})
|
||||||
|
|
||||||
|
stub_request(:post, @e_invoice_url)
|
||||||
|
.to_return(status: 200, body: @response, headers: {})
|
||||||
|
|
||||||
|
assert_enqueued_jobs 1, only: SendEInvoiceJob do
|
||||||
|
assert_difference('Invoice.count', 1) do
|
||||||
|
SendMonthlyInvoicesJob.perform_now
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
invoice = Invoice.last
|
invoice = Invoice.last
|
||||||
assert_equal 309_902, invoice.number
|
assert_equal 309_902, invoice.number
|
||||||
assert invoice.in_directo
|
|
||||||
assert_not invoice.e_invoice_sent_at.blank?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_monthly_duration_products_are_present_in_summary
|
def test_monthly_duration_products_are_present_in_summary
|
||||||
|
@ -192,28 +155,27 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
price = billing_prices(:create_one_month)
|
price = billing_prices(:create_one_month)
|
||||||
activity.update(activity_type: 'create', price: price)
|
activity.update(activity_type: 'create', price: price)
|
||||||
|
|
||||||
response = <<-XML
|
stub_request(:post, @directo_url).with do |request|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<results>
|
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
|
||||||
</results>
|
|
||||||
XML
|
|
||||||
|
|
||||||
stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
|
||||||
body = CGI.unescape(request.body)
|
body = CGI.unescape(request.body)
|
||||||
body.include? 'month(s)'
|
body.include? 'month(s)'
|
||||||
end.to_return(status: 200, body: response)
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
assert_difference 'Setting.directo_monthly_number_last' do
|
stub_request(:post, @monthly_invoice_numbers_generator_url)
|
||||||
SendMonthlyInvoicesJob.perform_now
|
.to_return(status: :ok, body: { invoice_numbers: [309_902] }.to_json, headers: {})
|
||||||
|
|
||||||
|
stub_request(:post, @e_invoice_url)
|
||||||
|
.to_return(status: 200, body: @response, headers: {})
|
||||||
|
|
||||||
|
assert_enqueued_jobs 1, only: SendEInvoiceJob do
|
||||||
|
assert_difference('Invoice.count', 1) do
|
||||||
|
SendMonthlyInvoicesJob.perform_now
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
perform_enqueued_jobs
|
perform_enqueued_jobs
|
||||||
|
|
||||||
invoice = Invoice.last
|
invoice = Invoice.last
|
||||||
assert_equal 309_902, invoice.number
|
assert_equal 309_902, invoice.number
|
||||||
assert invoice.in_directo
|
|
||||||
assert_not invoice.e_invoice_sent_at.blank?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_sends_each_monthly_invoice_separately
|
def test_sends_each_monthly_invoice_separately
|
||||||
|
@ -233,25 +195,31 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
another_activity.save
|
another_activity.save
|
||||||
AccountActivity.set_callback(:create, :after, :update_balance)
|
AccountActivity.set_callback(:create, :after, :update_balance)
|
||||||
|
|
||||||
response = <<-XML
|
first_registrar_stub = stub_request(:post, @directo_url).with do |request|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<results>
|
|
||||||
<Result Type="0" Desc="OK" docid="309902" doctype="ARVE" submit="Invoices"/>
|
|
||||||
</results>
|
|
||||||
XML
|
|
||||||
|
|
||||||
first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
|
||||||
body = CGI.unescape(request.body)
|
body = CGI.unescape(request.body)
|
||||||
(body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames')
|
(body.include? 'start_date') && (body.include? 'end_date') && (body.include? 'bestnames')
|
||||||
end.to_return(status: 200, body: response)
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request|
|
second_registrar_stub = stub_request(:post, @directo_url).with do |request|
|
||||||
body = CGI.unescape(request.body)
|
body = CGI.unescape(request.body)
|
||||||
(body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames')
|
(body.include? 'start_date') && (body.include? 'end_date') && (body.include? 'goodnames')
|
||||||
end.to_return(status: 200, body: response)
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
assert_difference('Invoice.count', 2) do
|
stub_request(:post, @e_invoice_url).with do |request|
|
||||||
assert_difference('Directo.count', 2) do
|
body = CGI.unescape(request.body)
|
||||||
|
(body.include? '309902') && (body.include? 'goodnames')
|
||||||
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
|
stub_request(:post, @e_invoice_url).with do |request|
|
||||||
|
body = CGI.unescape(request.body)
|
||||||
|
(body.include? '309903') && (body.include? 'bestnames')
|
||||||
|
end.to_return(status: 200, body: @response)
|
||||||
|
|
||||||
|
stub_request(:post, @monthly_invoice_numbers_generator_url)
|
||||||
|
.to_return(status: :ok, body: { invoice_numbers: [309_902, 309_903] }.to_json, headers: {})
|
||||||
|
|
||||||
|
assert_enqueued_jobs 2, only: SendEInvoiceJob do
|
||||||
|
assert_difference('Invoice.count', 2) do
|
||||||
SendMonthlyInvoicesJob.perform_now
|
SendMonthlyInvoicesJob.perform_now
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -262,17 +230,19 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase
|
||||||
assert_requested second_registrar_stub
|
assert_requested second_registrar_stub
|
||||||
|
|
||||||
assert_emails 2
|
assert_emails 2
|
||||||
assert_equal 2, EInvoice::Providers::TestProvider.deliveries.count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def metadata
|
def metadata
|
||||||
{
|
{
|
||||||
"items" => [
|
'items' => [
|
||||||
{ "description" => "Domeenide registreerimine - Juuli 2010" },
|
{ 'description' => 'Domeenide registreerimine - Juuli 2010' },
|
||||||
{ "product_id" => nil, "quantity" => 1, "unit" => "tk", "price" => 10.0, "description" => ".test registreerimine: 1 aasta(t)" },
|
{ 'product_id' => nil, 'quantity' => 1, 'unit' => 'tk', 'price' => 10.0,
|
||||||
{ "product_id" => "ETTEM06", "description" => "Domeenide ettemaks", "quantity" => -1, "price" => 10.0, "unit" => "tk" },
|
'description' => '.test registreerimine: 1 aasta(t)',
|
||||||
|
'duration_in_years' => 1 },
|
||||||
|
{ 'product_id' => 'ETTEM06', 'description' => 'Domeenide ettemaks', 'quantity' => -1,
|
||||||
|
'price' => 10.0, 'unit' => 'tk' },
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -204,20 +204,15 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_topup_creates_invoice_and_send_it_as_paid
|
def test_topup_creates_invoice_and_send_it_as_paid
|
||||||
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
|
||||||
.to_return(status: 200, body: '', headers: {})
|
.to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {})
|
||||||
|
|
||||||
invoice_n = Invoice.order(number: :desc).last.number
|
invoice_n = Invoice.order(number: :desc).last.number
|
||||||
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
|
||||||
.to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
|
.to_return(status: 200, body: { invoice_number: (invoice_n + 3).to_s }.to_json, headers: {})
|
||||||
|
|
||||||
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
|
||||||
.to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
|
.to_return(status: 200, body: '', headers: {})
|
||||||
|
|
||||||
stub_request(:put, 'https://registry:3000/eis_billing/e_invoice_response')
|
|
||||||
.to_return(status: 200,
|
|
||||||
body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now - 10.minutes}\"}",
|
|
||||||
headers: {})
|
|
||||||
|
|
||||||
registrar = registrars(:bestnames)
|
registrar = registrars(:bestnames)
|
||||||
@invoice.payment_orders.destroy_all
|
@invoice.payment_orders.destroy_all
|
||||||
|
@ -229,7 +224,6 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase
|
||||||
|
|
||||||
invoice = Invoice.last
|
invoice = Invoice.last
|
||||||
assert invoice.paid?
|
assert invoice.paid?
|
||||||
assert_not invoice.e_invoice_sent_at.blank?
|
|
||||||
|
|
||||||
pdf_source = Invoice::PdfGenerator.new(invoice)
|
pdf_source = Invoice::PdfGenerator.new(invoice)
|
||||||
pdf_source.send(:invoice_html).include?('Receipt date')
|
pdf_source.send(:invoice_html).include?('Receipt date')
|
||||||
|
|
|
@ -21,18 +21,15 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached
|
def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
|
||||||
to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
|
.to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {})
|
||||||
|
|
||||||
invoice_n = Invoice.order(number: :desc).last.number
|
invoice_n = Invoice.order(number: :desc).last.number
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
|
||||||
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
|
.to_return(status: 200, body: { invoice_number: (invoice_n + 3).to_s }.to_json, headers: {})
|
||||||
|
|
||||||
stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
|
||||||
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
|
.to_return(status: 200, body: '', headers: {})
|
||||||
|
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").
|
|
||||||
to_return(status: 200, body: "", headers: {})
|
|
||||||
|
|
||||||
reload_amount = 100
|
reload_amount = 100
|
||||||
registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)
|
||||||
|
@ -40,9 +37,6 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase
|
||||||
assert_difference -> { registrar.invoices.count } do
|
assert_difference -> { registrar.invoices.count } do
|
||||||
capture_io { run_task }
|
capture_io { run_task }
|
||||||
end
|
end
|
||||||
|
|
||||||
invoice = registrar.invoices.last
|
|
||||||
assert_equal Time.zone.today, invoice.e_invoice_sent_at.to_date
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_skips_issuing_invoice_when_threshold_is_not_reached
|
def test_skips_issuing_invoice_when_threshold_is_not_reached
|
||||||
|
@ -64,18 +58,15 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_marks_registrar_as_pending_balance_reload
|
def test_marks_registrar_as_pending_balance_reload
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
|
||||||
to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
|
.to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {})
|
||||||
|
|
||||||
invoice_n = Invoice.order(number: :desc).last.number
|
invoice_n = Invoice.order(number: :desc).last.number
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
|
||||||
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
|
.to_return(status: 200, body: { invoice_number: (invoice_n + 3).to_s }.to_json, headers: {})
|
||||||
|
|
||||||
stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response").
|
|
||||||
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
|
|
||||||
|
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
|
||||||
to_return(status: 200, body: "", headers: {})
|
.to_return(status: 200, body: '', headers: {})
|
||||||
|
|
||||||
registrar = registrar_with_auto_reload_enabled_and_threshold_reached
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached
|
||||||
|
|
||||||
|
@ -86,18 +77,15 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_output
|
def test_output
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator')
|
||||||
to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {})
|
.to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {})
|
||||||
|
|
||||||
invoice_n = Invoice.order(number: :desc).last.number
|
invoice_n = Invoice.order(number: :desc).last.number
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
|
||||||
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
|
.to_return(status: 200, body: { invoice_number: (invoice_n + 3).to_s }.to_json, headers: {})
|
||||||
|
|
||||||
stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response").
|
stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
|
||||||
to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {})
|
.to_return(status: 200, body: '', headers: {})
|
||||||
|
|
||||||
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").
|
|
||||||
to_return(status: 200, body: "", headers: {})
|
|
||||||
|
|
||||||
reload_amount = 100
|
reload_amount = 100
|
||||||
registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue