diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 28a06007a8..da67a9d77c 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -1,15 +1,8 @@ class DirectoInvoiceForwardJob < ApplicationJob - def perform(monthly: false, dry: false) - data = nil + def perform(dry: false) + data = collect_receipts_data - if monthly - @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) + EisBilling::SendDataToDirecto.send_request(object_data: data, monthly: false, dry: dry) end def collect_receipts_data @@ -38,47 +31,4 @@ def valid_invoice_conditions?(invoice) true 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 diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb index 02cad898c0..7fb7a4d271 100644 --- a/app/jobs/send_e_invoice_job.rb +++ b/app/jobs/send_e_invoice_job.rb @@ -3,11 +3,10 @@ class SendEInvoiceJob < ApplicationJob def perform(invoice_id, payable: true) 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) send_invoice_to_eis_billing(invoice: invoice, payable: payable) - invoice.update(e_invoice_sent_at: Time.zone.now) rescue StandardError => e log_error(invoice: invoice, error: e) raise e diff --git a/app/jobs/send_monthly_invoices_job.rb b/app/jobs/send_monthly_invoices_job.rb index af37b156ee..2c6e348312 100644 --- a/app/jobs/send_monthly_invoices_job.rb +++ b/app/jobs/send_monthly_invoices_job.rb @@ -1,147 +1,67 @@ class SendMonthlyInvoicesJob < ApplicationJob # rubocop:disable Metrics/ClassLength queue_as :default + discard_on StandardError - def perform(dry: false) + def perform(dry: false, months_ago: 1) @dry = dry - @month = Time.zone.now - 1.month - @directo_client = new_directo_client - @min_directo_num = Setting.directo_monthly_number_min.presence.try(:to_i) - @max_directo_num = Setting.directo_monthly_number_max.presence.try(:to_i) + @month = Time.zone.now - months_ago.month + @directo_data = [] send_monthly_invoices 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 def send_monthly_invoices - Registrar.with_cash_accounts.find_each do |registrar| - summary = registrar.monthly_summary(month: @month) - next if summary.nil? - - invoice = registrar.monthly_invoice(month: @month) || create_invoice(summary, registrar) - next if invoice.nil? || @dry - - send_email_to_registrar(invoice: invoice, registrar: registrar) - 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 + invoices = find_or_init_monthly_invoices + assign_invoice_numbers(invoices) + return if invoices.empty? || @dry + + invoices.each do |inv| + inv.send_to_registrar! unless inv.sent? + send_e_invoice(inv.id) + @directo_data << inv.as_monthly_directo_json unless inv.in_directo end - end - - # rubocop:enable Metrics/MethodLength - - def send_email_to_registrar(invoice:, registrar:) - InvoiceMailer.invoice_email(invoice: invoice, - recipient: registrar.billing_email) - .deliver_now - end - - def send_e_invoice(invoice_id) - SendEInvoiceLegacyJob.set(wait: 1.minute).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}") + return if @directo_data.empty? - 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') + EisBilling::SendDataToDirecto.send_request(object_data: @directo_data, + monthly: true) 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) + def assign_invoice_numbers(invoices) + invoice_without_numbers = invoices.select { |i| i.number.nil? } + return if invoice_without_numbers.empty? - 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) + result = EisBilling::GetMonthlyInvoiceNumbers.send_request(invoice_without_numbers.size) + response = JSON.parse(result.body) + handle_assign_numbers_response_errors(response) - false - end + numbers = response['invoice_numbers'] + invoice_without_numbers.each_with_index do |inv, index| + inv.number = numbers[index] + next if inv.save - 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) + Rails.logger.info 'There was an error creating monthly ' \ + "invoice #{inv.number}: #{inv.errors.full_messages.first}" end end + # rubocop:enable Metrics/MethodLength - 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! + def find_or_init_monthly_invoices(invoices: []) + Registrar.with_cash_accounts.find_each do |registrar| + invoice = registrar.find_or_init_monthly_invoice(month: @month) + invoices << invoice unless invoice.nil? + end + invoices 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 + def send_e_invoice(invoice_id) + SendEInvoiceJob.set(wait: 30.seconds).perform_later(invoice_id, payable: false) end private - # rubocop:disable Metrics/MethodLength - def normalize(summary, lines: []) - sum = summary.dup - 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 + def handle_assign_numbers_response_errors(response) + raise 'INVOICE NUMBER LIMIT REACHED, COULD NOT GENERATE INVOICE' if response['code'] == '403' + raise 'PROBLEM WITH TOKEN' if response['error'] == 'out of range' end end diff --git a/app/models/concerns/invoice/book_keeping.rb b/app/models/concerns/invoice/book_keeping.rb index 03998cc50a..895b763cf8 100644 --- a/app/models/concerns/invoice/book_keeping.rb +++ b/app/models/concerns/invoice/book_keeping.rb @@ -4,6 +4,7 @@ module Invoice::BookKeeping def as_directo_json invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) invoice['customer'] = compose_directo_customer + invoice['date'] = issue_date.strftime('%Y-%m-%d') invoice['issue_date'] = issue_date.strftime('%Y-%m-%d') invoice['transaction_date'] = account_activity .bank_transaction&.paid_at&.strftime('%Y-%m-%d') @@ -13,6 +14,60 @@ def as_directo_json invoice 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 [{ 'product_id': Setting.directo_receipt_product_name, 'description': order, 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision( diff --git a/app/models/concerns/registrar/book_keeping.rb b/app/models/concerns/registrar/book_keeping.rb index fc1defe9a3..86eede7795 100644 --- a/app/models/concerns/registrar/book_keeping.rb +++ b/app/models/concerns/registrar/book_keeping.rb @@ -13,83 +13,64 @@ module Registrar::BookKeeping # rubocop:disable Metrics/ModuleLength end def monthly_summary(month:) - activities = monthly_activites(month) - return unless activities.any? + invoice_lines = prepare_invoice_lines(month: month) + return unless invoice_lines invoice = { - 'number': 1, 'customer': compose_directo_customer, - 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency, - 'date': month.end_of_month.strftime('%Y-%m-%d') + 'date': month.end_of_month.strftime('%Y-%m-%d'), + 'description': title_for_summary(month), }.as_json - invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) + invoice['invoice_lines'] = invoice_lines invoice end - def prepare_invoice_lines(month:, activities:) - lines = [] + def prepare_invoice_lines(month:, lines: []) + activities = monthly_activities(month) + return if activities.empty? - lines << { 'description': title_for_summary(month) } activities.each do |activity| - fetch_invoice_lines(activity, lines) + lines << new_monthly_invoice_line(activity) 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.as_json 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) 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.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) + def monthly_activities(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 monthly_invoice(month:) - invoices.where(monthly_invoice: true, issue_date: month.end_of_month.to_date, - cancelled_at: nil).first - end - - def new_monthly_invoice_line(activity:, duration: nil) + def new_monthly_invoice_line(activity) price = load_price(activity) - line = { + duration = price.duration.in_years.to_i + { 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], 'quantity': 1, '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 - - 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 def description_in_language(price:, yearly:) @@ -115,14 +96,6 @@ def prepayment_for_all(lines) } 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) @pricelists ||= {} return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 80d6cf5d20..64366b9979 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -33,13 +33,13 @@ class Invoice < ApplicationRecord # rubocop:enable Style/MultilineBlockLayout validates :due_date, :currency, :seller_name, :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 :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 @@ -69,6 +69,17 @@ def set_invoice_number self.number = JSON.parse(result.body)['invoice_number'].to_i 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 I18n.t('invoice_no', no: number) end @@ -120,19 +131,6 @@ def as_pdf generator.as_pdf 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 [ number, diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 5d6d7538f1..cc97f11e18 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -62,7 +62,7 @@ def init_monthly_invoice(summary) issue_date: summary['date'].to_date, due_date: summary['date'].to_date, currency: 'EUR', - description: I18n.t('invoice.monthly_invoice_description'), + description: summary['description'], seller_name: Setting.registry_juridical_name, seller_reg_no: Setting.registry_reg_no, seller_iban: Setting.registry_iban, @@ -88,11 +88,11 @@ def init_monthly_invoice(summary) buyer_zip: address_zip, buyer_phone: phone, buyer_url: website, - buyer_email: email, + buyer_email: billing_email, reference_no: reference_no, vat_rate: calculate_vat_rate, monthly_invoice: true, - metadata: { items: summary['invoice_lines'] }, + metadata: { items: remove_line_duplicates(summary['invoice_lines']) }, total: 0 ) end @@ -128,7 +128,7 @@ def issue_prepayment_invoice(amount, description = nil, payable: true) buyer_zip: address_zip, buyer_phone: phone, buyer_url: website, - buyer_email: email, + buyer_email: billing_email, reference_no: reference_no, vat_rate: calculate_vat_rate, items_attributes: [ @@ -312,4 +312,16 @@ def vat_liable_in_foreign_country? def calculate_vat_rate ::Invoice::VatRateCalculator.new(registrar: self).calculate 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 diff --git a/app/services/eis_billing/get_monthly_invoice_numbers.rb b/app/services/eis_billing/get_monthly_invoice_numbers.rb new file mode 100644 index 0000000000..7c038d281e --- /dev/null +++ b/app/services/eis_billing/get_monthly_invoice_numbers.rb @@ -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 diff --git a/app/services/eis_billing/send_data_to_directo.rb b/app/services/eis_billing/send_data_to_directo.rb index 266475b318..2e064070fa 100644 --- a/app/services/eis_billing/send_data_to_directo.rb +++ b/app/services/eis_billing/send_data_to_directo.rb @@ -1,6 +1,6 @@ module EisBilling 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) end diff --git a/app/services/eis_billing/send_e_invoice.rb b/app/services/eis_billing/send_e_invoice.rb index e2a9cfaf64..ec638c9c13 100644 --- a/app/services/eis_billing/send_e_invoice.rb +++ b/app/services/eis_billing/send_e_invoice.rb @@ -5,35 +5,34 @@ def self.send_request(invoice:, payable:) end def self.send_info(invoice:, payable:) - items = [] 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.post(e_invoice_url, prepared_data.to_json, EisBilling::Base.headers) end - def self.prepare_item(invoice_item) - { - description: invoice_item.description, - price: invoice_item.price, - quantity: invoice_item.quantity, - unit: invoice_item.unit, - subtotal: invoice_item.subtotal, - vat_rate: invoice_item.vat_rate, - vat_amount: invoice_item.vat_amount, - total: invoice_item.total, - } + def self.prepare_items(invoice) + if invoice.monthly_invoice + invoice.metadata['items'] + else + invoice.items.map do |invoice_item| + { + description: invoice_item.description, + price: invoice_item.price, + quantity: invoice_item.quantity, + 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 def self.prepare_data(invoice:, payable:) { - invoice: invoice, + invoice: invoice.as_json, vat_amount: invoice.vat_amount, invoice_subtotal: invoice.subtotal, buyer_billing_email: invoice.buyer.billing_email, @@ -42,6 +41,7 @@ def self.prepare_data(invoice:, payable:) buyer_country_code: invoice.buyer_country_code, payable: payable, initiator: EisBilling::Base::INITIATOR, + items: prepare_items(invoice), } end diff --git a/app/views/invoice/monthly_pdf.haml b/app/views/invoice/monthly_pdf.haml index c7e179d037..13cf256adc 100644 --- a/app/views/invoice/monthly_pdf.haml +++ b/app/views/invoice/monthly_pdf.haml @@ -208,19 +208,17 @@ %table.table.table-hover.table-condensed %thead %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-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(:total) %tbody - @invoice.each do |invoice_item| %tr - %td= invoice_item.product_id - %td= invoice_item.quantity - %td= invoice_item.unit %td= invoice_item.description + %td= invoice_item.unit + %td= invoice_item.quantity - if invoice_item.price && invoice_item.quantity %td= currency(invoice_item.price) %td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}" @@ -229,15 +227,15 @@ %td= '' %tfoot %tr - %th{colspan: 4} + %th{colspan: 3} %th= Invoice.human_attribute_name :subtotal %td= number_to_currency(0) %tr - %th.no-border{colspan: 4} + %th.no-border{colspan: 3} %th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}" %td= number_to_currency(0) %tr - %th.no-border{colspan: 4} + %th.no-border{colspan: 3} %th= t(:total) %td= number_to_currency(0) diff --git a/app/views/registrar/invoices/partials/_details.haml b/app/views/registrar/invoices/partials/_details.haml index acc0e65892..150869dfa6 100644 --- a/app/views/registrar/invoices/partials/_details.haml +++ b/app/views/registrar/invoices/partials/_details.haml @@ -24,8 +24,9 @@ - else %dd{class: 'text-danger'}= t(:unpaid) - %dt= t(:payment_term) - %dd Prepayment + - unless @invoice.monthly_invoice + %dt= t(:payment_term) + %dd Prepayment %dt= t(:invoice_number) %dd= @invoice.number diff --git a/app/views/registrar/invoices/partials/_monthly_invoice_items.haml b/app/views/registrar/invoices/partials/_monthly_invoice_items.haml index 787218ea37..0aadfc9cdf 100644 --- a/app/views/registrar/invoices/partials/_monthly_invoice_items.haml +++ b/app/views/registrar/invoices/partials/_monthly_invoice_items.haml @@ -4,19 +4,17 @@ %table.table.table-hover.table-condensed %thead %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-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(:total) %tbody - @invoice.each do |invoice_item| %tr - %td= invoice_item.product_id - %td= invoice_item.quantity - %td= invoice_item.unit %td= invoice_item.description + %td= invoice_item.unit + %td= invoice_item.quantity - if invoice_item.price && invoice_item.quantity %td= currency(invoice_item.price) %td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}" @@ -25,14 +23,14 @@ %td= '' %tfoot %tr - %th{colspan: 4} + %th{colspan: 3} %th= Invoice.human_attribute_name :subtotal %td= number_to_currency(0) %tr - %th.no-border{colspan: 4} + %th.no-border{colspan: 3} %th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}" %td= number_to_currency(0) %tr - %th.no-border{colspan: 4} + %th.no-border{colspan: 3} %th= t(:total) %td= number_to_currency(0) \ No newline at end of file diff --git a/config/initializers/truemail.rb b/config/initializers/truemail.rb index 7a6a2256ca..fbb2fbc40f 100644 --- a/config/initializers/truemail.rb +++ b/config/initializers/truemail.rb @@ -48,10 +48,11 @@ # And all of validations for 'otherdomain.com' will be processed with mx validation only. # It is equal to empty hash by default. # config.validation_type_for = { 'somedomain.com' => :regex, 'otherdomain.com' => :mx } - config.validation_type_for = ENV['regex_only_email_validations'].split(/,/) - .collect { |d| [d.strip, :regex] } - .to_h - + if ENV['regex_only_email_validations'].present? + config.validation_type_for = ENV['regex_only_email_validations'].split(/,/) + .collect { |d| [d.strip, :regex] } + .to_h + end # 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 # It is equal to empty array by default. diff --git a/db/migrate/20221011061840_add_sent_at_to_invoices.rb b/db/migrate/20221011061840_add_sent_at_to_invoices.rb new file mode 100644 index 0000000000..fdd3b037c0 --- /dev/null +++ b/db/migrate/20221011061840_add_sent_at_to_invoices.rb @@ -0,0 +1,5 @@ +class AddSentAtToInvoices < ActiveRecord::Migration[6.1] + def change + add_column :invoices, :sent_at, :datetime + end +end diff --git a/db/structure.sql b/db/structure.sql index ace0f0198d..0e37313efd 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1198,6 +1198,7 @@ CREATE TABLE public.invoices ( payment_link character varying, monthly_invoice boolean DEFAULT false, metadata jsonb, + sent_at timestamp without time zone, 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'), ('20220113220809'), ('20220124105717'), -('20220216113112'), ('20220228093211'), ('20220316140727'), ('20220406085500'), @@ -5416,6 +5416,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220504090512'), ('20220524130709'), ('20220701113409'), -('20220818075833'); +('20220818075833'), +('20221011061840'); diff --git a/test/jobs/csync_job_test.rb b/test/jobs/csync_job_test.rb index 2c1ed49368..0d022b36d2 100644 --- a/test/jobs/csync_job_test.rb +++ b/test/jobs/csync_job_test.rb @@ -9,7 +9,7 @@ class CsyncJobTest < ActiveSupport::TestCase dirname = File.dirname(ENV['cdns_scanner_input_file']) 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 def test_generates_input_file_for_cdnskey_scanner diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index 5e72b84f8f..51ac40405c 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -107,28 +107,28 @@ def test_monthly_summary_is_delivered_in_english 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 - DirectoInvoiceForwardLegacyJob.perform_now(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 + # DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) + # end + # end def test_monthly_duration_products_are_present_in_summary activity = account_activities(:one) @@ -152,43 +152,43 @@ def test_monthly_duration_products_are_present_in_summary end end - def test_sends_each_monthly_invoice_separately - WebMock.reset! - - activity = account_activities(:one) - price = billing_prices(:create_one_year) - price.update(duration: 3.years) - activity.update(activity_type: 'create', price: price) - - # Creating account activity for second action - another_activity = activity.dup - another_activity.account = accounts(:two) - - AccountActivity.skip_callback(:create, :after, :update_balance) - another_activity.created_at = Time.zone.parse('2010-07-05 10:00') - another_activity.save - AccountActivity.set_callback(:create, :after, :update_balance) - - response = <<-XML - - - - - XML - - first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| - body = CGI.unescape(request.body) - (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames') - end.to_return(status: 200, body: response) - - second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| - body = CGI.unescape(request.body) - (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames') - end.to_return(status: 200, body: response) - - DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) - - assert_requested first_registrar_stub - assert_requested second_registrar_stub - end + # def test_sends_each_monthly_invoice_separately + # WebMock.reset! + + # activity = account_activities(:one) + # price = billing_prices(:create_one_year) + # price.update(duration: 3.years) + # activity.update(activity_type: 'create', price: price) + + # # Creating account activity for second action + # another_activity = activity.dup + # another_activity.account = accounts(:two) + + # AccountActivity.skip_callback(:create, :after, :update_balance) + # another_activity.created_at = Time.zone.parse('2010-07-05 10:00') + # another_activity.save + # AccountActivity.set_callback(:create, :after, :update_balance) + + # response = <<-XML + # + # + # + # + # XML + + # first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| + # body = CGI.unescape(request.body) + # (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames') + # end.to_return(status: 200, body: response) + + # second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| + # body = CGI.unescape(request.body) + # (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames') + # end.to_return(status: 200, body: response) + + # DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) + + # assert_requested first_registrar_stub + # assert_requested second_registrar_stub + # end end diff --git a/test/jobs/send_monthly_invoices_job_test.rb b/test/jobs/send_monthly_invoices_job_test.rb index 9fc5137ef0..92b2af6be4 100644 --- a/test/jobs/send_monthly_invoices_job_test.rb +++ b/test/jobs/send_monthly_invoices_job_test.rb @@ -8,20 +8,11 @@ class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase @date = Time.zone.parse('2010-08-06') travel_to @date ActionMailer::Base.deliveries.clear - EInvoice.provider = EInvoice::Providers::TestProvider.new - EInvoice::Providers::TestProvider.deliveries.clear - response = { message: 'sucess' } - stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice") - .to_return(status: 200, body: response.to_json, headers: {}) - end - - 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 + @response = { 'message' => 'Invoice data received' }.to_json + @monthly_invoice_numbers_generator_url = 'https://eis_billing_system:3000/api/v1/invoice_generator/monthly_invoice_numbers_generator' + @directo_url = 'https://eis_billing_system:3000/api/v1/directo/directo' + @e_invoice_url = 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice' end def test_fails_if_directo_bounds_exceedable @@ -29,17 +20,13 @@ def test_fails_if_directo_bounds_exceedable price = billing_prices(:create_one_year) 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 - assert_raises 'RuntimeError' do - SendMonthlyInvoicesJob.perform_now - end - end + SendMonthlyInvoicesJob.perform_now assert_nil Invoice.find_by_monthly_invoice(true) assert_emails 0 - assert_equal 0, EInvoice::Providers::TestProvider.deliveries.count end def test_monthly_summary_is_not_delivered_if_dry @@ -48,19 +35,18 @@ def test_monthly_summary_is_not_delivered_if_dry activity.update!(activity_type: 'create', price: price) @user.update(language: 'et') - assert_difference 'Setting.directo_monthly_number_last' do - assert_no_difference 'Directo.count' do - SendMonthlyInvoicesJob.perform_now(dry: true) - end - end + stub_request(:post, @monthly_invoice_numbers_generator_url) + .to_return(status: :ok, body: { invoice_numbers: [309_902] }.to_json, headers: {}) - invoice = Invoice.last + SendMonthlyInvoicesJob.perform_now(dry: true) + + invoice = Invoice.find_by_monthly_invoice(true) assert_equal 309_902, invoice.number + refute invoice.sent_at refute invoice.in_directo assert invoice.e_invoice_sent_at.blank? assert_emails 0 - assert_equal 0, EInvoice::Providers::TestProvider.deliveries.count end def test_monthly_summary_is_delivered_if_invoice_already_exists @@ -70,6 +56,7 @@ def test_monthly_summary_is_delivered_if_invoice_already_exists due_date: @date.last_month.end_of_month, metadata: metadata, in_directo: false, + sent_at: nil, e_invoice_sent_at: nil) activity = account_activities(:one) @@ -77,41 +64,23 @@ def test_monthly_summary_is_delivered_if_invoice_already_exists activity.update!(activity_type: 'create', price: price) @user.update(language: 'et') - response = <<-XML - - - - - XML - - stub_request(:post, ENV['directo_invoice_url']).with do |request| + stub_request(:post, @directo_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) + end.to_return(status: 200, body: @response) - assert_no_difference 'Setting.directo_monthly_number_last' do - assert_difference('Directo.count', 1) do + assert_enqueued_jobs 1, only: SendEInvoiceJob do + assert_no_difference('Invoice.count') do SendMonthlyInvoicesJob.perform_now end end + @monthly_invoice.reload - perform_enqueued_jobs - - invoice = Invoice.last - assert_equal 309_902, invoice.number - assert invoice.in_directo - assert_not invoice.e_invoice_sent_at.blank? - + assert_not_nil @monthly_invoice.sent_at 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 def test_monthly_summary_is_delivered_in_estonian @@ -120,23 +89,22 @@ def test_monthly_summary_is_delivered_in_estonian activity.update!(activity_type: 'create', price: price) @user.update(language: 'et') - response = <<-XML - - - - - XML - - stub_request(:post, ENV['directo_invoice_url']).with do |request| + stub_request(:post, @directo_url).with do |request| body = CGI.unescape(request.body) (body.include? '.test registreerimine: 3 kuu(d)') && (body.include? 'Domeenide ettemaks') && (body.include? '309902') - end.to_return(status: 200, body: response) + end.to_return(status: 200, body: @response) + + stub_request(:post, @monthly_invoice_numbers_generator_url) + .to_return(status: :ok, body: { invoice_numbers: [309_902] }.to_json, headers: {}) - assert_difference 'Setting.directo_monthly_number_last' do - assert_difference('Directo.count', 1) do + 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 @@ -145,16 +113,12 @@ def test_monthly_summary_is_delivered_in_estonian invoice = Invoice.last assert_equal 309_902, invoice.number - assert invoice.in_directo - assert_not invoice.e_invoice_sent_at.blank? 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 def test_multi_year_purchases_have_duration_assigned @@ -163,28 +127,27 @@ def test_multi_year_purchases_have_duration_assigned 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| + stub_request(:post, @directo_url).with do |request| body = CGI.unescape(request.body) - (body.include? 'StartDate') && (body.include? 'EndDate') - end.to_return(status: 200, body: response) + (body.include? 'start_date') && (body.include? 'end_date') + end.to_return(status: 200, body: @response) + + stub_request(:post, @monthly_invoice_numbers_generator_url) + .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_difference 'Setting.directo_monthly_number_last' do - SendMonthlyInvoicesJob.perform_now + assert_enqueued_jobs 1, only: SendEInvoiceJob do + assert_difference('Invoice.count', 1) do + SendMonthlyInvoicesJob.perform_now + end end perform_enqueued_jobs invoice = Invoice.last assert_equal 309_902, invoice.number - assert invoice.in_directo - assert_not invoice.e_invoice_sent_at.blank? end def test_monthly_duration_products_are_present_in_summary @@ -192,28 +155,27 @@ def test_monthly_duration_products_are_present_in_summary 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| + stub_request(:post, @directo_url).with do |request| body = CGI.unescape(request.body) body.include? 'month(s)' - end.to_return(status: 200, body: response) + end.to_return(status: 200, body: @response) + + stub_request(:post, @monthly_invoice_numbers_generator_url) + .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_difference 'Setting.directo_monthly_number_last' do - SendMonthlyInvoicesJob.perform_now + assert_enqueued_jobs 1, only: SendEInvoiceJob do + assert_difference('Invoice.count', 1) do + SendMonthlyInvoicesJob.perform_now + end end perform_enqueued_jobs invoice = Invoice.last assert_equal 309_902, invoice.number - assert invoice.in_directo - assert_not invoice.e_invoice_sent_at.blank? end def test_sends_each_monthly_invoice_separately @@ -233,25 +195,31 @@ def test_sends_each_monthly_invoice_separately another_activity.save AccountActivity.set_callback(:create, :after, :update_balance) - response = <<-XML - - - - - XML + first_registrar_stub = stub_request(:post, @directo_url).with do |request| + body = CGI.unescape(request.body) + (body.include? 'start_date') && (body.include? 'end_date') && (body.include? 'bestnames') + end.to_return(status: 200, body: @response) + + second_registrar_stub = stub_request(:post, @directo_url).with do |request| + body = CGI.unescape(request.body) + (body.include? 'start_date') && (body.include? 'end_date') && (body.include? 'goodnames') + end.to_return(status: 200, body: @response) - first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| + stub_request(:post, @e_invoice_url).with do |request| body = CGI.unescape(request.body) - (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames') - end.to_return(status: 200, body: response) + (body.include? '309902') && (body.include? 'goodnames') + end.to_return(status: 200, body: @response) - second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| + stub_request(:post, @e_invoice_url).with do |request| body = CGI.unescape(request.body) - (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames') - end.to_return(status: 200, body: response) + (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_difference('Invoice.count', 2) do - assert_difference('Directo.count', 2) do + assert_enqueued_jobs 2, only: SendEInvoiceJob do + assert_difference('Invoice.count', 2) do SendMonthlyInvoicesJob.perform_now end end @@ -262,17 +230,19 @@ def test_sends_each_monthly_invoice_separately assert_requested second_registrar_stub assert_emails 2 - assert_equal 2, EInvoice::Providers::TestProvider.deliveries.count end private def metadata { - "items" => [ - { "description" => "Domeenide registreerimine - Juuli 2010" }, - { "product_id" => nil, "quantity" => 1, "unit" => "tk", "price" => 10.0, "description" => ".test registreerimine: 1 aasta(t)" }, - { "product_id" => "ETTEM06", "description" => "Domeenide ettemaks", "quantity" => -1, "price" => 10.0, "unit" => "tk" }, + 'items' => [ + { 'description' => 'Domeenide registreerimine - Juuli 2010' }, + { 'product_id' => nil, 'quantity' => 1, 'unit' => 'tk', 'price' => 10.0, + 'description' => '.test registreerimine: 1 aasta(t)', + 'duration_in_years' => 1 }, + { 'product_id' => 'ETTEM06', 'description' => 'Domeenide ettemaks', 'quantity' => -1, + 'price' => 10.0, 'unit' => 'tk' }, ], } end diff --git a/test/tasks/invoices/process_payments_test.rb b/test/tasks/invoices/process_payments_test.rb index 1ed65dc123..7f0efbe7cf 100644 --- a/test/tasks/invoices/process_payments_test.rb +++ b/test/tasks/invoices/process_payments_test.rb @@ -204,20 +204,15 @@ def test_topup_creates_invoice_with_total_of_transactioned_amount end def test_topup_creates_invoice_and_send_it_as_paid - stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice') - .to_return(status: 200, body: '', headers: {}) + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator') + .to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {}) invoice_n = Invoice.order(number: :desc).last.number 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: {}) - - 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: { 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') + .to_return(status: 200, body: '', headers: {}) registrar = registrars(:bestnames) @invoice.payment_orders.destroy_all @@ -229,7 +224,6 @@ def test_topup_creates_invoice_and_send_it_as_paid invoice = Invoice.last assert invoice.paid? - assert_not invoice.e_invoice_sent_at.blank? pdf_source = Invoice::PdfGenerator.new(invoice) pdf_source.send(:invoice_html).include?('Receipt date') diff --git a/test/tasks/registrars/reload_balance_test.rb b/test/tasks/registrars/reload_balance_test.rb index 934c6f6d06..113fcde304 100644 --- a/test/tasks/registrars/reload_balance_test.rb +++ b/test/tasks/registrars/reload_balance_test.rb @@ -21,18 +21,15 @@ def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached end 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"). - to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator') + .to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {}) invoice_n = Invoice.order(number: :desc).last.number - 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: {}) + 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).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"). - 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 registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) @@ -40,9 +37,6 @@ def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached assert_difference -> { registrar.invoices.count } do capture_io { run_task } end - - invoice = registrar.invoices.last - assert_equal Time.zone.today, invoice.e_invoice_sent_at.to_date end def test_skips_issuing_invoice_when_threshold_is_not_reached @@ -64,18 +58,15 @@ def test_skips_issuing_invoice_when_balance_reload_is_pending end def test_marks_registrar_as_pending_balance_reload - 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: {}) + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator') + .to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {}) invoice_n = Invoice.order(number: :desc).last.number - 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: {}) - - 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/invoice_generator/invoice_number_generator') + .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/e_invoice/e_invoice"). - 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: {}) registrar = registrar_with_auto_reload_enabled_and_threshold_reached @@ -86,18 +77,15 @@ def test_marks_registrar_as_pending_balance_reload end def test_output - 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: {}) + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator') + .to_return(status: 200, body: { everypay_link: 'http://link.test' }.to_json, headers: {}) invoice_n = Invoice.order(number: :desc).last.number - 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: {}) - - 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/invoice_generator/invoice_number_generator') + .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/e_invoice/e_invoice"). - 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 registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)