From e954c212c71f09c4fc685735ec235ff6a1f30b39 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Thu, 3 Mar 2016 15:52:42 +0200 Subject: [PATCH] Story#105855968 - Prepare xml for Directo --- Gemfile | 1 + Gemfile.lock | 10 +++ app/models/counter.rb | 4 ++ app/models/directo.rb | 89 +++++++++++++++++++------ app/models/domain.rb | 1 + app/models/pricelist.rb | 10 +++ config/initializers/initial_settings.rb | 2 +- 7 files changed, 96 insertions(+), 21 deletions(-) diff --git a/Gemfile b/Gemfile index d29fa223b..d0218726e 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ source 'https://rubygems.org' # core gem 'rails', '4.2.4' # when update, all initializers eis_custom files needs check/update +gem 'rails-i18n', github: 'svenfuchs/rails-i18n', branch: 'rails-4-x' gem 'iso8601', '0.8.6' # for dates and times gem 'hashie-forbidden_attributes', '0.1.1' gem 'SyslogLogger', '2.0', require: 'syslog/logger' diff --git a/Gemfile.lock b/Gemfile.lock index 45eb09943..c1119a9fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,6 +45,15 @@ GIT bundler (~> 1.2) thor (~> 0.18) +GIT + remote: https://github.com/svenfuchs/rails-i18n.git + revision: 4913b54a5d7026066ceb12a4523476a1411e86bb + branch: rails-4-x + specs: + rails-i18n (4.0.8) + i18n (~> 0.7) + railties (~> 4.0) + GEM remote: https://rubygems.org/ specs: @@ -626,6 +635,7 @@ DEPENDENCIES que_mailer! railroady (= 1.3.0) rails (= 4.2.4) + rails-i18n! rails-settings-cached (= 0.4.1) rake ransack (= 1.5.1) diff --git a/app/models/counter.rb b/app/models/counter.rb index 01bec95e6..7d1c2b926 100644 --- a/app/models/counter.rb +++ b/app/models/counter.rb @@ -10,6 +10,10 @@ class Counter @value.to_s end + def now + @value + end + # pre-increment ".+" when x not present def next(x = 1) @value += x diff --git a/app/models/directo.rb b/app/models/directo.rb index 5cd480bf5..efd508e41 100644 --- a/app/models/directo.rb +++ b/app/models/directo.rb @@ -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 @@ -49,36 +50,84 @@ class Directo < ActiveRecord::Base def self.send_monthly_invoices - product_ids = {"ee" => "01EE", "com.ee" => "02COM", "pri.ee" => "03PRI", "fie.ee"=>"04FIE", "med.ee" => "05MED"} + I18n.locale = :et month = Time.now - 1.month invoices_until = month.end_of_month - # pochemu registrar has_many :accounts + date_format = "%Y-%m-%d" - activity_scope = AccountActivity.where(activity_type: [CREATE, RENEW]) - Registrar.joins(:account).find_each do |registrar| + Registrar.find_each do |registrar| next unless registrar.cash_account - counter = Counter.new - builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| - activity_scope.where(account_id: registrar.cash_account) + 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) - xml.invoices{ - xml.invoice("Number"=>"13980", - "InvoiceDate"=>invoices_until.strftime("%Y-%m-%d"), - "PaymentTerm"=>"E", - "CustomerCode"=>registrar.directo_handle, - "Language"=>"", - "Currency"=>"EUR", - "SalesAgent"=>Setting.directo_sales_agent){ - xml.line("RN" => counter.next, "RR"=>1, "ProductName"=> "Domeenide registreerimine - Juuli 2015") - activity_scope.where(account_id: registrar.account_ids).each do |activity| - xml.line("RN"=>counter.next, "RR"=>"2", "ProductID"=>"01EE", "Quantity"=>"1911", "Unit"=>"tk", "ProductName"=>".ee registreerimine: 1 aasta", "UnitPriceWoVAT"=>"9.00") - end + # adding domains items + registrar_activities.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]).each do |activity| + pricelist = load_activity_pricelist(activity) + next unless pricelist + + 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? + builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| + xml.invoices{ + xml.invoice("Number" =>"13980", + "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 + puts builder.to_xml end end 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 =begin diff --git a/app/models/domain.rb b/app/models/domain.rb index 1b7121c1a..1beea0840 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -452,6 +452,7 @@ 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' diff --git a/app/models/pricelist.rb b/app/models/pricelist.rb index 17420dfa1..d38e4290d 100644 --- a/app/models/pricelist.rb +++ b/app/models/pricelist.rb @@ -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) diff --git a/config/initializers/initial_settings.rb b/config/initializers/initial_settings.rb index 1b25ddeb3..6590d2922 100644 --- a/config/initializers/initial_settings.rb +++ b/config/initializers/initial_settings.rb @@ -5,7 +5,7 @@ rescue ActiveRecord::NoDatabaseError => e Rails.logger.info "Init settings didn't find database: #{e}" end -if con.present? && con.table_exists?('settings') +if false && con.present? && con.table_exists?('settings') Setting.save_default(:admin_contacts_min_count, 1) Setting.save_default(:admin_contacts_max_count, 10) Setting.save_default(:tech_contacts_min_count, 1)