mirror of
https://github.com/internetee/registry.git
synced 2025-07-21 10:16:01 +02:00
Move registrar directo logic to concern, touch up translations
This commit is contained in:
parent
035bb14d9f
commit
3f92640ad2
8 changed files with 156 additions and 147 deletions
|
@ -1,121 +0,0 @@
|
||||||
module BookKeeping
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI',
|
|
||||||
'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze
|
|
||||||
|
|
||||||
def monthly_summary(month:)
|
|
||||||
activities = monthly_activites(month)
|
|
||||||
return unless activities.any?
|
|
||||||
|
|
||||||
inv = {
|
|
||||||
'number': 1,
|
|
||||||
'customer_code': accounting_customer_code,
|
|
||||||
'language': language, 'currency': activities.first.currency,
|
|
||||||
'date': month.end_of_month.strftime('%Y-%m-%d')
|
|
||||||
}.as_json
|
|
||||||
|
|
||||||
inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities)
|
|
||||||
|
|
||||||
inv
|
|
||||||
end
|
|
||||||
|
|
||||||
def prepare_invoice_lines(month:, activities:)
|
|
||||||
lines = []
|
|
||||||
|
|
||||||
lines << { 'description': title_for_summary(month) }
|
|
||||||
activities.each do |activity|
|
|
||||||
fetch_invoice_lines(activity, lines)
|
|
||||||
end
|
|
||||||
lines << prepayment_for_all(lines)
|
|
||||||
|
|
||||||
lines.as_json
|
|
||||||
end
|
|
||||||
|
|
||||||
def title_for_summary(date)
|
|
||||||
if language == 'en'
|
|
||||||
I18n.with_locale('en') do
|
|
||||||
"Domains registrations - #{I18n.l(date, format: '%B %Y')}"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
I18n.with_locale('et') do
|
|
||||||
"Domeenide registreerimine - #{I18n.l(date, format: '%B %Y')}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_invoice_lines(activity, lines)
|
|
||||||
price = load_price(activity)
|
|
||||||
if price.duration.include? 'year'
|
|
||||||
price.duration.to_i.times do |duration|
|
|
||||||
lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json
|
|
||||||
end
|
|
||||||
else
|
|
||||||
lines << new_monthly_invoice_line(activity: activity).as_json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def monthly_activites(month)
|
|
||||||
AccountActivity.where(account_id: account_ids)
|
|
||||||
.where(created_at: month.beginning_of_month..month.end_of_month)
|
|
||||||
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_monthly_invoice_line(activity:, duration: nil)
|
|
||||||
price = load_price(activity)
|
|
||||||
line = {
|
|
||||||
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
|
|
||||||
'quantity': 1,
|
|
||||||
'unit': language == 'en' ? 'pc' : 'tk',
|
|
||||||
}
|
|
||||||
|
|
||||||
finalize_invoice_line(line, price: price, duration: duration, activity: activity)
|
|
||||||
end
|
|
||||||
|
|
||||||
def finalize_invoice_line(line, price:, activity:, duration:)
|
|
||||||
yearly = price.duration.include?('year')
|
|
||||||
|
|
||||||
line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount
|
|
||||||
line['description'] = description_in_language(price: price, yearly: yearly)
|
|
||||||
|
|
||||||
if duration.present?
|
|
||||||
add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1
|
|
||||||
end
|
|
||||||
|
|
||||||
line
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_product_timeframe(line:, activity:, duration:)
|
|
||||||
create_time = activity.created_at
|
|
||||||
line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d')
|
|
||||||
line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d')
|
|
||||||
end
|
|
||||||
|
|
||||||
def description_in_language(price:, yearly:)
|
|
||||||
timeframe_string = yearly ? 'yearly' : 'monthly'
|
|
||||||
locale_string = ".registrars.invoice_#{timeframe_string}_product_description"
|
|
||||||
|
|
||||||
I18n.with_locale(language == 'en' ? 'en' : 'et') do
|
|
||||||
I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def prepayment_for_all(lines)
|
|
||||||
total = 0
|
|
||||||
lines.each { |l| total += l['quantity'].to_f * l['price'].to_f }
|
|
||||||
{
|
|
||||||
'product_id': Setting.directo_receipt_product_name,
|
|
||||||
'description': language == 'en' ? 'Domains prepayment' : 'Domeenide ettemaks',
|
|
||||||
'quantity': -1,
|
|
||||||
'price': total,
|
|
||||||
'unit': language == 'en' ? 'pc' : 'tk',
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_price(account_activity)
|
|
||||||
@pricelists ||= {}
|
|
||||||
return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
|
|
||||||
|
|
||||||
@pricelists[account_activity.price_id] = account_activity.price
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -70,18 +70,18 @@ class DirectoInvoiceForwardJob < Que::Job
|
||||||
end
|
end
|
||||||
|
|
||||||
def sync_with_directo
|
def sync_with_directo
|
||||||
|
assign_monthly_numbers if @month
|
||||||
Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}")
|
Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}")
|
||||||
return if @dry
|
return if @dry
|
||||||
|
|
||||||
assign_monthly_numbers if @month
|
|
||||||
res = @client.invoices.deliver(ssl_verify: false)
|
res = @client.invoices.deliver(ssl_verify: false)
|
||||||
update_invoice_directo_state(res.body, @client.invoices.as_xml) if res.code == '200'
|
process_directo_response(res.body, @client.invoices.as_xml)
|
||||||
rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
|
rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
|
||||||
EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
|
EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
|
||||||
Rails.logger.info('[Directo] Failed to communicate via API')
|
Rails.logger.info('[Directo] Failed to communicate via API')
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_invoice_directo_state(xml, req)
|
def process_directo_response(xml, req)
|
||||||
Rails.logger.info "[Directo] - Responded with body: #{xml}"
|
Rails.logger.info "[Directo] - Responded with body: #{xml}"
|
||||||
Nokogiri::XML(xml).css('Result').each do |res|
|
Nokogiri::XML(xml).css('Result').each do |res|
|
||||||
if @month
|
if @month
|
||||||
|
|
25
app/models/concerns/invoice/book_keeping.rb
Normal file
25
app/models/concerns/invoice/book_keeping.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module Concerns
|
||||||
|
module Invoice
|
||||||
|
module BookKeeping
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def as_directo_json
|
||||||
|
inv = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self))
|
||||||
|
inv['customer_code'] = buyer.accounting_customer_code
|
||||||
|
inv['issue_date'] = issue_date.strftime('%Y-%m-%d')
|
||||||
|
inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d')
|
||||||
|
inv['language'] = buyer.language == 'en' ? 'ENG' : ''
|
||||||
|
inv['invoice_lines'] = compose_directo_product
|
||||||
|
|
||||||
|
inv
|
||||||
|
end
|
||||||
|
|
||||||
|
def compose_directo_product
|
||||||
|
[{ 'product_id': Setting.directo_receipt_product_name, 'description': order,
|
||||||
|
'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision(
|
||||||
|
subtotal, precision: 2, separator: '.'
|
||||||
|
) }].as_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
120
app/models/concerns/registrar/book_keeping.rb
Normal file
120
app/models/concerns/registrar/book_keeping.rb
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
module Concerns
|
||||||
|
module Registrar
|
||||||
|
module BookKeeping
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI',
|
||||||
|
'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze
|
||||||
|
|
||||||
|
def monthly_summary(month:)
|
||||||
|
activities = monthly_activites(month)
|
||||||
|
return unless activities.any?
|
||||||
|
|
||||||
|
inv = {
|
||||||
|
'number': 1,
|
||||||
|
'customer_code': accounting_customer_code,
|
||||||
|
'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency,
|
||||||
|
'date': month.end_of_month.strftime('%Y-%m-%d')
|
||||||
|
}.as_json
|
||||||
|
|
||||||
|
inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities)
|
||||||
|
|
||||||
|
inv
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepare_invoice_lines(month:, activities:)
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
lines << { 'description': title_for_summary(month) }
|
||||||
|
activities.each do |activity|
|
||||||
|
fetch_invoice_lines(activity, lines)
|
||||||
|
end
|
||||||
|
lines << prepayment_for_all(lines)
|
||||||
|
|
||||||
|
lines.as_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def title_for_summary(date)
|
||||||
|
I18n.with_locale(language == 'en' ? 'en' : 'et') do
|
||||||
|
I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_invoice_lines(activity, lines)
|
||||||
|
price = load_price(activity)
|
||||||
|
if price.duration.include? 'year'
|
||||||
|
price.duration.to_i.times do |duration|
|
||||||
|
lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json
|
||||||
|
end
|
||||||
|
else
|
||||||
|
lines << new_monthly_invoice_line(activity: activity).as_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def monthly_activites(month)
|
||||||
|
AccountActivity.where(account_id: account_ids)
|
||||||
|
.where(created_at: month.beginning_of_month..month.end_of_month)
|
||||||
|
.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_monthly_invoice_line(activity:, duration: nil)
|
||||||
|
price = load_price(activity)
|
||||||
|
line = {
|
||||||
|
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
|
||||||
|
'quantity': 1,
|
||||||
|
'unit': language == 'en' ? 'pc' : 'tk',
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize_invoice_line(line, price: price, duration: duration, activity: activity)
|
||||||
|
end
|
||||||
|
|
||||||
|
def finalize_invoice_line(line, price:, activity:, duration:)
|
||||||
|
yearly = price.duration.include?('year')
|
||||||
|
|
||||||
|
line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount
|
||||||
|
line['description'] = description_in_language(price: price, yearly: yearly)
|
||||||
|
|
||||||
|
if duration.present?
|
||||||
|
add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1
|
||||||
|
end
|
||||||
|
|
||||||
|
line
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_product_timeframe(line:, activity:, duration:)
|
||||||
|
create_time = activity.created_at
|
||||||
|
line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d')
|
||||||
|
line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d')
|
||||||
|
end
|
||||||
|
|
||||||
|
def description_in_language(price:, yearly:)
|
||||||
|
timeframe_string = yearly ? 'yearly' : 'monthly'
|
||||||
|
locale_string = "registrar.invoice_#{timeframe_string}_product_description"
|
||||||
|
|
||||||
|
I18n.with_locale(language == 'en' ? 'en' : 'et') do
|
||||||
|
I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepayment_for_all(lines)
|
||||||
|
total = 0
|
||||||
|
en = language == 'en'
|
||||||
|
lines.each { |l| total += l['quantity'].to_f * l['price'].to_f }
|
||||||
|
{
|
||||||
|
'product_id': Setting.directo_receipt_product_name,
|
||||||
|
'description': en ? 'Domains prepayment' : 'Domeenide ettemaks',
|
||||||
|
'quantity': -1,
|
||||||
|
'price': total,
|
||||||
|
'unit': en ? 'pc' : 'tk',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_price(account_activity)
|
||||||
|
@pricelists ||= {}
|
||||||
|
return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id
|
||||||
|
|
||||||
|
@pricelists[account_activity.price_id] = account_activity.price
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,6 +2,7 @@ class Invoice < ApplicationRecord
|
||||||
include Versions
|
include Versions
|
||||||
include Concerns::Invoice::Cancellable
|
include Concerns::Invoice::Cancellable
|
||||||
include Concerns::Invoice::Payable
|
include Concerns::Invoice::Payable
|
||||||
|
include Concerns::Invoice::BookKeeping
|
||||||
|
|
||||||
belongs_to :buyer, class_name: 'Registrar'
|
belongs_to :buyer, class_name: 'Registrar'
|
||||||
has_one :account_activity
|
has_one :account_activity
|
||||||
|
@ -102,24 +103,6 @@ class Invoice < ApplicationRecord
|
||||||
generator.generate
|
generator.generate
|
||||||
end
|
end
|
||||||
|
|
||||||
def as_directo_json
|
|
||||||
inv = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self))
|
|
||||||
inv['customer_code'] = buyer.accounting_customer_code
|
|
||||||
inv['issue_date'] = issue_date.strftime('%Y-%m-%d')
|
|
||||||
inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d')
|
|
||||||
inv['language'] = buyer.language
|
|
||||||
inv['invoice_lines'] = compose_directo_product
|
|
||||||
|
|
||||||
inv
|
|
||||||
end
|
|
||||||
|
|
||||||
def compose_directo_product
|
|
||||||
[{ 'product_id': Setting.directo_receipt_product_name, 'description': order,
|
|
||||||
'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision(
|
|
||||||
subtotal, precision: 2, separator: '.'
|
|
||||||
) }].as_json
|
|
||||||
end
|
|
||||||
|
|
||||||
def do_not_send_e_invoice?
|
def do_not_send_e_invoice?
|
||||||
e_invoice_sent? || cancelled? || paid?
|
e_invoice_sent? || cancelled? || paid?
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Registrar < ApplicationRecord
|
class Registrar < ApplicationRecord
|
||||||
include Versions # version/registrar_version.rb
|
include Versions # version/registrar_version.rb
|
||||||
include BookKeeping
|
include Concerns::Registrar::BookKeeping
|
||||||
|
|
||||||
has_many :domains, dependent: :restrict_with_error
|
has_many :domains, dependent: :restrict_with_error
|
||||||
has_many :contacts, dependent: :restrict_with_error
|
has_many :contacts, dependent: :restrict_with_error
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
en:
|
en:
|
||||||
registrars:
|
registrar:
|
||||||
invoice_yearly_product_description: '%{tld} registration: %{length} year(s)'
|
invoice_yearly_product_description: '%{tld} registration: %{length} year(s)'
|
||||||
invoice_monthly_product_description: '%{tld} registration: %{length} month(s)'
|
invoice_monthly_product_description: '%{tld} registration: %{length} month(s)'
|
||||||
|
monthly_summary_title: 'Domain registrations - %{date}'
|
||||||
activerecord:
|
activerecord:
|
||||||
errors:
|
errors:
|
||||||
models:
|
models:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
et:
|
et:
|
||||||
registrars:
|
registrar:
|
||||||
invoice_yearly_product_description: '%{tld} registration: %{length} year(s)'
|
invoice_yearly_product_description: '%{tld} registreerimine: %{length} aasta(t)'
|
||||||
invoice_monthly_product_description: '%{tld} registration: %{length} month(s)'
|
invoice_monthly_product_description: '%{tld} registreerimine: %{length} kuu(d)'
|
||||||
|
monthly_summary_title: 'Domeenide registreerimine - %{date}'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue