mirror of
https://github.com/internetee/registry.git
synced 2025-07-23 03:06:14 +02:00
Merge branch 'story/105855968-directo' into staging
# Conflicts: # Gemfile # Gemfile.lock
This commit is contained in:
commit
7d8cc9839f
15 changed files with 444 additions and 229 deletions
|
@ -57,7 +57,7 @@ class Admin::RegistrarsController < AdminController
|
|||
def registrar_params
|
||||
params.require(:registrar).permit(
|
||||
:name, :reg_no, :vat_no, :street, :city, :state, :zip, :billing_address,
|
||||
:country_code, :email, :phone, :billing_email, :code
|
||||
:country_code, :email, :phone, :billing_email, :code, :exclude_in_monthly_directo
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@ class BankTransaction < ActiveRecord::Base
|
|||
include Versions
|
||||
belongs_to :bank_statement
|
||||
has_one :account_activity
|
||||
has_many :directo_records, as: :item, class_name: 'Directo'# Deprecated
|
||||
|
||||
scope :unbinded, lambda {
|
||||
where('id NOT IN (SELECT bank_transaction_id FROM account_activities where bank_transaction_id IS NOT NULL)')
|
||||
|
|
24
app/models/counter.rb
Normal file
24
app/models/counter.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
class Counter
|
||||
def initialize value = 0
|
||||
@value = value
|
||||
end
|
||||
attr_accessor :value
|
||||
def method_missing *args, &blk
|
||||
@value.send(*args, &blk)
|
||||
end
|
||||
def to_s
|
||||
@value.to_s
|
||||
end
|
||||
|
||||
def now
|
||||
@value
|
||||
end
|
||||
|
||||
# pre-increment ".+" when x not present
|
||||
def next(x = 1)
|
||||
@value += x
|
||||
end
|
||||
def prev(x = 1)
|
||||
@value -= x
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
class Directo < ActiveRecord::Base
|
||||
DOMAIN_TO_PRODUCT = {"ee" => "01EE", "com.ee" => "02COM", "pri.ee" => "03PRI", "fie.ee"=>"04FIE", "med.ee" => "05MED"}.freeze
|
||||
belongs_to :item, polymorphic: true
|
||||
|
||||
def self.send_receipts
|
||||
|
@ -52,9 +53,119 @@ class Directo < ActiveRecord::Base
|
|||
def self.dump_result_to_db mappers, xml
|
||||
Nokogiri::XML(xml).css("Result").each do |res|
|
||||
obj = mappers[res.attributes["docid"].value.to_i]
|
||||
obj.directo_records.create!(response: res.as_json.to_h)
|
||||
obj.directo_records.create!(response: res.as_json.to_h, invoice_number: obj.number)
|
||||
obj.update_columns(in_directo: true)
|
||||
Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.send_monthly_invoices
|
||||
I18n.locale = :et
|
||||
month = Time.now - 1.month
|
||||
invoices_until = month.end_of_month
|
||||
date_format = "%Y-%m-%d"
|
||||
invoice_counter= Counter.new
|
||||
|
||||
min_directo = Setting.invoice_number_min.presence.try(:to_i)
|
||||
max_directo = Setting.directo_monthly_number_max.presence.try(:to_i)
|
||||
last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i), min_directo].compact.max || 0
|
||||
if max_directo && max_directo <= last_directo
|
||||
raise "Directo counter is out of period"
|
||||
end
|
||||
|
||||
Registrar.where.not(exclude_in_monthly_directo: true).find_each do |registrar|
|
||||
unless registrar.cash_account
|
||||
Rails.logger.info("[DIRECTO] Monthly invoice for registrar #{registrar.id} has been skipped as it doesn't has cash_account")
|
||||
next
|
||||
end
|
||||
counter = Counter.new(1)
|
||||
items = {}
|
||||
registrar_activities = AccountActivity.where(account_id: registrar.account_ids).where("created_at BETWEEN ? AND ?",month.beginning_of_month, month.end_of_month)
|
||||
|
||||
# adding domains items
|
||||
registrar_activities.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]).each do |activity|
|
||||
pricelist = load_activity_pricelist(activity)
|
||||
unless pricelist
|
||||
Rails.logger.error("[DIRECTO] Skipping activity #{activity.id} as pricelist not found")
|
||||
next
|
||||
end
|
||||
|
||||
pricelist.years_amount.times do |i|
|
||||
year = i+1
|
||||
hash = {
|
||||
"ProductID" => DOMAIN_TO_PRODUCT[pricelist.category],
|
||||
"Unit" => "tk",
|
||||
"ProductName" => ".#{pricelist.category} registreerimine: #{pricelist.years_amount} aasta",
|
||||
"UnitPriceWoVAT" => pricelist.price_decimal/pricelist.years_amount
|
||||
}
|
||||
hash["StartDate"] = (activity.created_at + year.year).strftime(date_format) if year > 1
|
||||
hash["EndDate"] = (activity.created_at + year.year + 1).strftime(date_format) if year > 1
|
||||
|
||||
if items.has_key?(hash)
|
||||
items[hash]["Quantity"] += 1
|
||||
else
|
||||
items[hash] = {"RN"=>counter.next, "RR" => counter.now - i, "Quantity"=> 1}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#adding prepaiments
|
||||
registrar_activities.where(activity_type: [AccountActivity::ADD_CREDIT]).each do |activity|
|
||||
hash = {"ProductID" => Setting.directo_receipt_product_name, "Unit" => "tk", "ProductName" => "Domeenide ettemaks", "UnitPriceWoVAT"=>activity.sum}
|
||||
items[hash] = {"RN"=>counter.next, "RR" => counter.now, "Quantity"=> -1}
|
||||
end
|
||||
|
||||
# generating XML
|
||||
if items.any?
|
||||
directo_next = last_directo + 1
|
||||
invoice_counter.next
|
||||
|
||||
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
||||
xml.invoices{
|
||||
xml.invoice("Number" =>directo_next,
|
||||
"InvoiceDate" =>invoices_until.strftime(date_format),
|
||||
"PaymentTerm" =>"E",
|
||||
"CustomerCode"=>registrar.directo_handle,
|
||||
"Language" =>"",
|
||||
"Currency" =>registrar_activities.first.currency,
|
||||
"SalesAgent" =>Setting.directo_sales_agent){
|
||||
xml.line("RN" => 1, "RR"=>1, "ProductName"=> "Domeenide registreerimine - #{I18n.l(invoices_until, format: "%B %Y").titleize}")
|
||||
items.each do |line, val|
|
||||
xml.line(val.merge(line))
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
data = builder.to_xml.gsub("\n",'')
|
||||
response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false).to_s
|
||||
Setting.directo_monthly_number_last = directo_next
|
||||
Nokogiri::XML(response).css("Result").each do |res|
|
||||
Directo.create!(response: res.as_json.to_h, invoice_number: directo_next)
|
||||
Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}")
|
||||
end
|
||||
else
|
||||
Rails.logger.info("[DIRECTO] Registrar #{registrar.id} has nothing to be sent to Directo")
|
||||
end
|
||||
|
||||
end
|
||||
STDOUT << "#{Time.zone.now.utc} - Directo invoices sending finished. #{invoice_counter.now} are sent\n"
|
||||
end
|
||||
|
||||
|
||||
def self.load_activity_pricelist activity
|
||||
@pricelists ||= {}
|
||||
return @pricelists[activity.log_pricelist_id] if @pricelists.has_key?(activity.log_pricelist_id)
|
||||
|
||||
pricelist = Pricelist.find_by(id: activity.log_pricelist_id) || PricelistVersion.find_by(item_id: activity.log_pricelist_id).try(:reify)
|
||||
unless pricelist
|
||||
@pricelists[activity.log_pricelist_id] = nil
|
||||
Rails.logger.info("[DIRECTO] AccountActivity #{activity.id} cannot be sent as pricelist wasn't found #{activity.log_pricelist_id}")
|
||||
return
|
||||
end
|
||||
|
||||
@pricelists[activity.log_pricelist_id] = pricelist.version_at(activity.created_at) || pricelist
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -456,19 +456,14 @@ class Domain < ActiveRecord::Base
|
|||
period_i ||= period
|
||||
unit ||= period_unit
|
||||
|
||||
# TODO: test if name.scan(/\.(.+)\z/).first.first is faster
|
||||
zone = name.split('.').drop(1).join('.')
|
||||
|
||||
p = period_i / 365 if unit == 'd'
|
||||
p = period_i / 12 if unit == 'm'
|
||||
p = period_i if unit == 'y'
|
||||
|
||||
if p > 1
|
||||
p = "#{p}years"
|
||||
else
|
||||
p = "#{p}year"
|
||||
end
|
||||
|
||||
Pricelist.pricelist_for(zone, operation, p)
|
||||
Pricelist.pricelist_for(zone, operation, "#{p}year".pluralize(p))
|
||||
end
|
||||
|
||||
### VALIDATIONS ###
|
||||
|
|
|
@ -8,6 +8,8 @@ class Pricelist < ActiveRecord::Base
|
|||
)
|
||||
}
|
||||
|
||||
scope :valid_at, ->(time){ where("valid_from IS NULL OR valid_from <= ?", time).where("valid_to IS NULL OR valid_to >= ?", time) }
|
||||
|
||||
monetize :price_cents
|
||||
|
||||
validates :price_cents, :price_currency, :price,
|
||||
|
@ -27,6 +29,14 @@ class Pricelist < ActiveRecord::Base
|
|||
"#{operation_category} #{category}"
|
||||
end
|
||||
|
||||
def years_amount
|
||||
duration.to_i
|
||||
end
|
||||
|
||||
def price_decimal
|
||||
price_cents / BigDecimal.new('100')
|
||||
end
|
||||
|
||||
class << self
|
||||
def pricelist_for(zone, operation, period)
|
||||
lists = valid.where(category: zone, operation_category: operation, duration: period)
|
||||
|
|
|
@ -82,6 +82,11 @@
|
|||
= f.label :code
|
||||
.col-md-7
|
||||
= f.text_field(:code, class: 'form-control', disabled: !f.object.new_record?)
|
||||
.form-group
|
||||
.col-md-4.control-label
|
||||
= f.label :exclude_in_monthly_directo
|
||||
.col-md-7
|
||||
= f.check_box :exclude_in_monthly_directo, class: 'form-control'
|
||||
|
||||
%hr
|
||||
.row
|
||||
|
|
|
@ -69,6 +69,9 @@
|
|||
%tbody
|
||||
= render 'setting_row', var: :invoice_number_min
|
||||
= render 'setting_row', var: :invoice_number_max
|
||||
= render 'setting_row', var: :directo_monthly_number_min
|
||||
= render 'setting_row', var: :directo_monthly_number_max
|
||||
= render 'setting_row', var: :directo_monthly_number_last
|
||||
= render 'setting_row', var: :days_to_keep_invoices_active
|
||||
= render 'setting_row', var: :days_to_keep_overdue_invoices_active
|
||||
= render 'setting_row', var: :minimum_deposit
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue