mirror of
https://github.com/internetee/registry.git
synced 2025-06-06 20:55:44 +02:00
parent
19f9a4eb71
commit
62c38d1f99
29 changed files with 660 additions and 16 deletions
1
Gemfile
1
Gemfile
|
@ -90,6 +90,7 @@ gem 'active_model-errors_details' # Backport from Rails 5, https://github.com/ra
|
||||||
gem 'airbrake'
|
gem 'airbrake'
|
||||||
|
|
||||||
gem 'company_register', github: 'internetee/company_register', branch: :master
|
gem 'company_register', github: 'internetee/company_register', branch: :master
|
||||||
|
gem 'e_invoice', github: 'internetee/e_invoice', branch: :master
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
# deploy
|
# deploy
|
||||||
|
|
11
Gemfile.lock
11
Gemfile.lock
|
@ -15,6 +15,16 @@ GIT
|
||||||
data_migrate (1.3.0)
|
data_migrate (1.3.0)
|
||||||
rails (>= 4.1.0)
|
rails (>= 4.1.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/internetee/e_invoice.git
|
||||||
|
revision: 7817bbefd4ed0b140ed781172bd64a856b622273
|
||||||
|
branch: master
|
||||||
|
specs:
|
||||||
|
e_invoice (0.1.0)
|
||||||
|
builder (~> 3.2)
|
||||||
|
nokogiri
|
||||||
|
savon
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/internetee/epp-xml.git
|
remote: https://github.com/internetee/epp-xml.git
|
||||||
revision: 5dd542e67ef26d58365f30e553254d6db809277d
|
revision: 5dd542e67ef26d58365f30e553254d6db809277d
|
||||||
|
@ -456,6 +466,7 @@ DEPENDENCIES
|
||||||
database_cleaner
|
database_cleaner
|
||||||
devise (~> 4.0)
|
devise (~> 4.0)
|
||||||
digidoc_client!
|
digidoc_client!
|
||||||
|
e_invoice!
|
||||||
epp (= 1.5.0)!
|
epp (= 1.5.0)!
|
||||||
epp-xml (= 1.1.0)!
|
epp-xml (= 1.1.0)!
|
||||||
factory_bot_rails
|
factory_bot_rails
|
||||||
|
|
|
@ -2,6 +2,7 @@ class Registrar
|
||||||
class AccountController < BaseController
|
class AccountController < BaseController
|
||||||
skip_authorization_check
|
skip_authorization_check
|
||||||
helper_method :iban_max_length
|
helper_method :iban_max_length
|
||||||
|
helper_method :balance_auto_reload_setting
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
|
@ -25,5 +26,9 @@ class Registrar
|
||||||
def iban_max_length
|
def iban_max_length
|
||||||
Iban.max_length
|
Iban.max_length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def balance_auto_reload_setting
|
||||||
|
current_registrar_user.registrar.settings['balance_auto_reload']
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -0,0 +1,52 @@
|
||||||
|
class Registrar
|
||||||
|
module Settings
|
||||||
|
class BalanceAutoReloadController < BaseController
|
||||||
|
before_action :authorize
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@type = if current_registrar.settings['balance_auto_reload']
|
||||||
|
type_params = current_registrar.settings['balance_auto_reload']['type']
|
||||||
|
.except('name')
|
||||||
|
BalanceAutoReloadTypes::Threshold.new(type_params)
|
||||||
|
else
|
||||||
|
BalanceAutoReloadTypes::Threshold.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
type = BalanceAutoReloadTypes::Threshold.new(type_params)
|
||||||
|
current_registrar.update!(settings: { balance_auto_reload: { type: type } })
|
||||||
|
|
||||||
|
redirect_to registrar_account_path, notice: t('.saved')
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
current_registrar.settings.delete('balance_auto_reload')
|
||||||
|
current_registrar.save!
|
||||||
|
|
||||||
|
redirect_to registrar_account_path, notice: t('.disabled')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def type_params
|
||||||
|
permitted_params = params.require(:type).permit(:amount, :threshold)
|
||||||
|
normalize_params(permitted_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize_params(params)
|
||||||
|
params[:amount] = params[:amount].to_f
|
||||||
|
params[:threshold] = params[:threshold].to_f
|
||||||
|
params
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize
|
||||||
|
authorize!(:manage, :balance_auto_reload)
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_registrar
|
||||||
|
current_registrar_user.registrar
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -72,6 +72,7 @@ class Ability
|
||||||
can(:manage, Invoice) { |i| i.buyer_id == @user.registrar_id }
|
can(:manage, Invoice) { |i| i.buyer_id == @user.registrar_id }
|
||||||
can :manage, :deposit
|
can :manage, :deposit
|
||||||
can :read, AccountActivity
|
can :read, AccountActivity
|
||||||
|
can :manage, :balance_auto_reload
|
||||||
end
|
end
|
||||||
|
|
||||||
def customer_service # Admin/admin_user dynamic role
|
def customer_service # Admin/admin_user dynamic role
|
||||||
|
|
25
app/models/balance_auto_reload_types/threshold.rb
Normal file
25
app/models/balance_auto_reload_types/threshold.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module BalanceAutoReloadTypes
|
||||||
|
class Threshold
|
||||||
|
include ActiveModel::Model
|
||||||
|
|
||||||
|
attr_accessor :amount
|
||||||
|
attr_accessor :threshold
|
||||||
|
|
||||||
|
validates :amount, numericality: { greater_than_or_equal_to: :min_amount }
|
||||||
|
validates :threshold, numericality: { greater_than_or_equal_to: 0 }
|
||||||
|
|
||||||
|
def min_amount
|
||||||
|
Setting.minimum_deposit
|
||||||
|
end
|
||||||
|
|
||||||
|
def as_json(options)
|
||||||
|
{ name: name }.merge(super)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def name
|
||||||
|
self.class.name.demodulize.underscore
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -79,13 +79,23 @@ class BankTransaction < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_activity(registrar, invoice)
|
def create_activity(registrar, invoice)
|
||||||
create_account_activity(
|
ActiveRecord::Base.transaction do
|
||||||
account: registrar.cash_account,
|
create_account_activity!(account: registrar.cash_account,
|
||||||
invoice: invoice,
|
invoice: invoice,
|
||||||
sum: invoice.subtotal,
|
sum: invoice.subtotal,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
description: description,
|
description: description,
|
||||||
activity_type: AccountActivity::ADD_CREDIT
|
activity_type: AccountActivity::ADD_CREDIT)
|
||||||
)
|
reset_pending_registrar_balance_reload
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def reset_pending_registrar_balance_reload
|
||||||
|
return unless registrar.settings['balance_auto_reload']
|
||||||
|
|
||||||
|
registrar.settings['balance_auto_reload'].delete('pending')
|
||||||
|
registrar.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -98,6 +98,11 @@ class Invoice < ActiveRecord::Base
|
||||||
generator.as_pdf
|
generator.as_pdf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_e_invoice
|
||||||
|
generator = Invoice::EInvoiceGenerator.new(self)
|
||||||
|
generator.generate
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def apply_default_buyer_vat_no
|
def apply_default_buyer_vat_no
|
||||||
|
|
77
app/models/invoice/e_invoice_generator.rb
Normal file
77
app/models/invoice/e_invoice_generator.rb
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
class Invoice
|
||||||
|
class EInvoiceGenerator
|
||||||
|
attr_reader :invoice
|
||||||
|
|
||||||
|
def initialize(invoice)
|
||||||
|
@invoice = invoice
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate
|
||||||
|
seller = EInvoice::Seller.new
|
||||||
|
seller.name = invoice.seller_name
|
||||||
|
seller.registration_number = invoice.seller_reg_no
|
||||||
|
seller.vat_number = invoice.seller_vat_no
|
||||||
|
|
||||||
|
seller_legal_address = EInvoice::Address.new
|
||||||
|
seller_legal_address.line1 = invoice.seller_street
|
||||||
|
seller_legal_address.line2 = invoice.seller_state
|
||||||
|
seller_legal_address.postal_code = invoice.seller_zip
|
||||||
|
seller_legal_address.city = invoice.seller_city
|
||||||
|
seller_legal_address.country = invoice.seller_country
|
||||||
|
seller.legal_address = seller_legal_address
|
||||||
|
|
||||||
|
buyer = EInvoice::Buyer.new
|
||||||
|
buyer.name = invoice.buyer_name
|
||||||
|
buyer.registration_number = invoice.buyer_reg_no
|
||||||
|
buyer.vat_number = invoice.buyer_vat_no
|
||||||
|
buyer.email = invoice.buyer.billing_email
|
||||||
|
|
||||||
|
buyer_bank_account = EInvoice::BankAccount.new
|
||||||
|
buyer_bank_account.number = invoice.buyer.e_invoice_iban
|
||||||
|
buyer.bank_account = buyer_bank_account
|
||||||
|
|
||||||
|
buyer_legal_address = EInvoice::Address.new
|
||||||
|
buyer_legal_address.line1 = invoice.buyer_street
|
||||||
|
buyer_legal_address.line2 = invoice.buyer_state
|
||||||
|
buyer_legal_address.postal_code = invoice.buyer_zip
|
||||||
|
buyer_legal_address.city = invoice.buyer_city
|
||||||
|
buyer_legal_address.country = invoice.buyer_country
|
||||||
|
buyer.legal_address = buyer_legal_address
|
||||||
|
|
||||||
|
e_invoice_invoice_items = []
|
||||||
|
invoice.each do |invoice_item|
|
||||||
|
e_invoice_invoice_item = EInvoice::InvoiceItem.new.tap do |i|
|
||||||
|
i.description = invoice_item.description
|
||||||
|
i.price = invoice_item.price
|
||||||
|
i.quantity = invoice_item.quantity
|
||||||
|
i.unit = invoice_item.unit
|
||||||
|
i.subtotal = invoice_item.subtotal
|
||||||
|
i.vat_rate = invoice_item.vat_rate
|
||||||
|
i.vat_amount = invoice_item.vat_amount
|
||||||
|
i.total = invoice_item.total
|
||||||
|
end
|
||||||
|
e_invoice_invoice_items << e_invoice_invoice_item
|
||||||
|
end
|
||||||
|
|
||||||
|
e_invoice_invoice = EInvoice::Invoice.new.tap do |i|
|
||||||
|
i.seller = seller
|
||||||
|
i.buyer = buyer
|
||||||
|
i.items = e_invoice_invoice_items
|
||||||
|
i.number = invoice.number
|
||||||
|
i.date = invoice.issue_date
|
||||||
|
i.recipient_id_code = invoice.buyer_reg_no
|
||||||
|
i.reference_number = invoice.reference_no
|
||||||
|
i.due_date = invoice.due_date
|
||||||
|
i.beneficiary_name = invoice.seller_name
|
||||||
|
i.beneficiary_account_number = invoice.seller_iban
|
||||||
|
i.payer_name = invoice.buyer_name
|
||||||
|
i.subtotal = invoice.subtotal
|
||||||
|
i.vat_amount = invoice.vat_amount
|
||||||
|
i.total = invoice.total
|
||||||
|
i.currency = invoice.currency
|
||||||
|
end
|
||||||
|
|
||||||
|
EInvoice::EInvoice.new(date: Time.zone.today, invoice: e_invoice_invoice)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -165,6 +165,10 @@ class Registrar < ActiveRecord::Base
|
||||||
notifications.create!(text: text)
|
notifications.create!(text: text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def e_invoice_iban
|
||||||
|
iban
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_defaults
|
def set_defaults
|
||||||
|
|
30
app/views/registrar/account/_balance_auto_reload.html.erb
Normal file
30
app/views/registrar/account/_balance_auto_reload.html.erb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<div class="panel panel-default balance-auto-reload">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<%= t '.header' %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<% if setting %>
|
||||||
|
<span class="label label-success"><%= t '.enabled' %></span>
|
||||||
|
<%= t '.enabled_state_details', amount: number_to_currency(setting['type']['amount']),
|
||||||
|
threshold: number_to_currency(setting['type']['threshold']) %>
|
||||||
|
<% else %>
|
||||||
|
<span class="text-muted"><%= t '.disabled' %></span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-footer text-right">
|
||||||
|
<% if !setting %>
|
||||||
|
<%= link_to t('.enable_btn'), edit_registrar_settings_balance_auto_reload_path,
|
||||||
|
class: 'btn btn-default btn-sm' %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to t('.disable_btn'), registrar_settings_balance_auto_reload_path,
|
||||||
|
method: :delete, class: 'btn btn-default btn-sm' %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if setting %>
|
||||||
|
<%= link_to t('.edit_btn'), edit_registrar_settings_balance_auto_reload_path,
|
||||||
|
class: 'btn btn-default btn-sm' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -12,4 +12,12 @@
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<%= render 'linked_users', linked_users: current_registrar_user.linked_users %>
|
<%= render 'linked_users', linked_users: current_registrar_user.linked_users %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% if can?(:manage, :balance_auto_reload) %>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<%= render 'balance_auto_reload', setting: balance_auto_reload_setting %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -0,0 +1 @@
|
||||||
|
<%= render 'registrar/settings/balance_auto_reload/form/types/threshold', type: @type %>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><%= link_to t('registrar.account.show.header'), registrar_account_path %></li>
|
||||||
|
<li><%= t '.header' %></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<h1><%= t '.header' %></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= render 'form' %>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<p><%= t '.description' %></p>
|
||||||
|
|
||||||
|
<%= form_for type, as: :type, url: registrar_settings_balance_auto_reload_path, method: :patch,
|
||||||
|
html: { class: 'form-horizontal' } do |f| %>
|
||||||
|
<%= render 'form_errors', target: type %>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<%= f.label :amount, class: 'col-md-2 control-label' %>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="input-group">
|
||||||
|
<%= f.money_field :amount, required: true, autofocus: true, class: 'form-control' %>
|
||||||
|
<div class="input-group-addon"><%= Money::default_currency.symbol %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<span class="help-block"><%= t '.amount_hint', min_amount: f.object.min_amount %></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<%= f.label :threshold, class: 'col-md-2 control-label' %>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="input-group">
|
||||||
|
<%= f.money_field :threshold, required: true, class: 'form-control' %>
|
||||||
|
<div class="input-group-addon"><%= Money::default_currency.symbol %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-offset-3 col-md-2">
|
||||||
|
<%= f.submit t('.submit_btn'), class: 'btn btn-success' %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -135,6 +135,10 @@ payments_every_pay_seller_account: 'EUR3D1'
|
||||||
payments_every_pay_api_user: 'api_user'
|
payments_every_pay_api_user: 'api_user'
|
||||||
payments_every_pay_api_key: 'api_key'
|
payments_every_pay_api_key: 'api_key'
|
||||||
|
|
||||||
|
e_invoice_provider_name: 'omniva'
|
||||||
|
e_invoice_provider_password:
|
||||||
|
e_invoice_provider_test_mode: 'false'
|
||||||
|
|
||||||
user_session_timeout: '3600' # 1 hour
|
user_session_timeout: '3600' # 1 hour
|
||||||
secure_session_cookies: 'false' # true|false
|
secure_session_cookies: 'false' # true|false
|
||||||
same_site_session_cookies: 'false' # false|strict|lax
|
same_site_session_cookies: 'false' # false|strict|lax
|
||||||
|
|
3
config/initializers/e_invoice.rb
Normal file
3
config/initializers/e_invoice.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
provider_config = { password: ENV['e_invoice_provider_password'],
|
||||||
|
test_mode: ENV['e_invoice_provider_test_mode'] == 'true' }
|
||||||
|
EInvoice.provider = EInvoice::Providers::OmnivaProvider.new(provider_config)
|
|
@ -21,3 +21,12 @@ en:
|
||||||
linked_users:
|
linked_users:
|
||||||
header: Linked users
|
header: Linked users
|
||||||
switch_btn: Switch
|
switch_btn: Switch
|
||||||
|
|
||||||
|
balance_auto_reload:
|
||||||
|
header: Balance Auto-Reload
|
||||||
|
enabled: Enabled
|
||||||
|
enabled_state_details: Reload %{amount} when your balance drops to %{threshold}
|
||||||
|
disabled: Disabled
|
||||||
|
enable_btn: Enable
|
||||||
|
disable_btn: Disable
|
||||||
|
edit_btn: Edit
|
19
config/locales/registrar/settings/balance_auto_reload.en.yml
Normal file
19
config/locales/registrar/settings/balance_auto_reload.en.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
en:
|
||||||
|
registrar:
|
||||||
|
settings:
|
||||||
|
balance_auto_reload:
|
||||||
|
edit:
|
||||||
|
header: Balance Auto-Reload
|
||||||
|
|
||||||
|
form:
|
||||||
|
types:
|
||||||
|
threshold:
|
||||||
|
description: Automatically reload your balance when it drops to a minimum threshold
|
||||||
|
amount_hint: must be greater than or equal to %{min_amount}
|
||||||
|
submit_btn: Save
|
||||||
|
|
||||||
|
update:
|
||||||
|
saved: Balance Auto-Reload setting has been updated
|
||||||
|
|
||||||
|
destroy:
|
||||||
|
disabled: Balance Auto-Reload setting has been disabled
|
|
@ -115,6 +115,10 @@ Rails.application.routes.draw do
|
||||||
put 'pay/return/:bank' => 'payments#back'
|
put 'pay/return/:bank' => 'payments#back'
|
||||||
post 'pay/callback/:bank' => 'payments#callback', as: 'response_payment_with'
|
post 'pay/callback/:bank' => 'payments#callback', as: 'response_payment_with'
|
||||||
get 'pay/go/:bank' => 'payments#pay', as: 'payment_with'
|
get 'pay/go/:bank' => 'payments#pay', as: 'payment_with'
|
||||||
|
|
||||||
|
namespace :settings do
|
||||||
|
resource :balance_auto_reload, controller: :balance_auto_reload, only: %i[edit update destroy]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :registrar do
|
scope :registrar do
|
||||||
|
|
5
db/migrate/20190426174225_add_registrars_settings.rb
Normal file
5
db/migrate/20190426174225_add_registrars_settings.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddRegistrarsSettings < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :registrars, :settings, :jsonb, null: false, default: '{}'
|
||||||
|
end
|
||||||
|
end
|
|
@ -2201,7 +2201,8 @@ CREATE TABLE public.registrars (
|
||||||
test_registrar boolean DEFAULT false,
|
test_registrar boolean DEFAULT false,
|
||||||
language character varying NOT NULL,
|
language character varying NOT NULL,
|
||||||
vat_rate numeric(4,3),
|
vat_rate numeric(4,3),
|
||||||
iban character varying
|
iban character varying,
|
||||||
|
settings jsonb DEFAULT '{}'::jsonb NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -4963,6 +4964,8 @@ INSERT INTO schema_migrations (version) VALUES ('20190328151838');
|
||||||
|
|
||||||
INSERT INTO schema_migrations (version) VALUES ('20190415120246');
|
INSERT INTO schema_migrations (version) VALUES ('20190415120246');
|
||||||
|
|
||||||
|
INSERT INTO schema_migrations (version) VALUES ('20190426174225');
|
||||||
|
|
||||||
INSERT INTO schema_migrations (version) VALUES ('20190510090240');
|
INSERT INTO schema_migrations (version) VALUES ('20190510090240');
|
||||||
|
|
||||||
INSERT INTO schema_migrations (version) VALUES ('20190510102549');
|
INSERT INTO schema_migrations (version) VALUES ('20190510102549');
|
||||||
|
|
35
lib/tasks/registrars/reload_balance.rake
Normal file
35
lib/tasks/registrars/reload_balance.rake
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
namespace :registrars do
|
||||||
|
desc 'Reloads balance of registrars'
|
||||||
|
|
||||||
|
task reload_balance: :environment do
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
invoiced_registrar_count = 0
|
||||||
|
|
||||||
|
Registrar.transaction do
|
||||||
|
Registrar.all.each do |registrar|
|
||||||
|
balance_auto_reload_setting = registrar.settings['balance_auto_reload']
|
||||||
|
next unless balance_auto_reload_setting
|
||||||
|
|
||||||
|
reload_pending = balance_auto_reload_setting['pending']
|
||||||
|
threshold_reached = registrar.balance <= balance_auto_reload_setting['type']['threshold']
|
||||||
|
reload_amount = balance_auto_reload_setting['type']['amount']
|
||||||
|
|
||||||
|
next if reload_pending || !threshold_reached
|
||||||
|
|
||||||
|
Registrar.transaction do
|
||||||
|
invoice = registrar.issue_prepayment_invoice(reload_amount)
|
||||||
|
e_invoice = invoice.to_e_invoice
|
||||||
|
e_invoice.deliver
|
||||||
|
|
||||||
|
registrar.settings['balance_auto_reload']['pending'] = true
|
||||||
|
registrar.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
puts %(Registrar "#{registrar}" got #{number_to_currency(reload_amount, unit: 'EUR')})
|
||||||
|
invoiced_registrar_count += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Invoiced total: #{invoiced_registrar_count}"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class RegistrarAreaSettingsBalanceAutoReloadIntegrationTest < ActionDispatch::IntegrationTest
|
||||||
|
include Devise::Test::IntegrationHelpers
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@registrar = registrars(:bestnames)
|
||||||
|
sign_in users(:api_bestnames)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_updates_balance_auto_reload_setting
|
||||||
|
amount = 100
|
||||||
|
threshold = 10
|
||||||
|
assert_nil @registrar.settings['balance_auto_reload']
|
||||||
|
|
||||||
|
patch registrar_settings_balance_auto_reload_path, { type: { amount: amount,
|
||||||
|
threshold: threshold } }
|
||||||
|
@registrar.reload
|
||||||
|
|
||||||
|
assert_equal amount, @registrar.settings['balance_auto_reload']['type']['amount']
|
||||||
|
assert_equal threshold, @registrar.settings['balance_auto_reload']['type']['threshold']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_disables_balance_auto_reload_setting
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { amount: 'any', threshold: 'any' } })
|
||||||
|
|
||||||
|
delete registrar_settings_balance_auto_reload_path
|
||||||
|
@registrar.reload
|
||||||
|
|
||||||
|
assert_nil @registrar.settings['balance_auto_reload']
|
||||||
|
end
|
||||||
|
end
|
62
test/models/balance_auto_reload_types/threshold_test.rb
Normal file
62
test/models/balance_auto_reload_types/threshold_test.rb
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class BalanceAutoReloadTypes::ThresholdTest < ActiveSupport::TestCase
|
||||||
|
setup do
|
||||||
|
@original_min_reload_amount = Setting.minimum_deposit
|
||||||
|
end
|
||||||
|
|
||||||
|
teardown do
|
||||||
|
Setting.minimum_deposit = @original_min_reload_amount
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_valid_fixture_is_valid
|
||||||
|
assert valid_type.valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_invalid_without_amount
|
||||||
|
type = valid_type
|
||||||
|
type.amount = nil
|
||||||
|
assert type.invalid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_invalid_when_amount_is_smaller_than_required_minimum
|
||||||
|
type = valid_type
|
||||||
|
Setting.minimum_deposit = 0.02
|
||||||
|
|
||||||
|
type.amount = 0.01
|
||||||
|
|
||||||
|
assert type.invalid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_valid_when_amount_equals_allowed_minimum
|
||||||
|
type = valid_type
|
||||||
|
Setting.minimum_deposit = 0.02
|
||||||
|
|
||||||
|
type.amount = 0.02
|
||||||
|
|
||||||
|
assert type.valid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_invalid_without_threshold
|
||||||
|
type = valid_type
|
||||||
|
type.threshold = nil
|
||||||
|
assert type.invalid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_invalid_when_threshold_is_less_than_zero
|
||||||
|
type = valid_type
|
||||||
|
type.threshold = -1
|
||||||
|
assert type.invalid?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_serializes_to_json
|
||||||
|
type = BalanceAutoReloadTypes::Threshold.new(amount: 100, threshold: 10)
|
||||||
|
assert_equal ({ name: 'threshold', amount: 100, threshold: 10 }).to_json, type.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def valid_type
|
||||||
|
BalanceAutoReloadTypes::Threshold.new(amount: Setting.minimum_deposit, threshold: 0)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +1,13 @@
|
||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class BankTransactionTest < ActiveSupport::TestCase
|
class BankTransactionTest < ActiveSupport::TestCase
|
||||||
def test_matches_against_invoice_reference_number
|
setup do
|
||||||
invoices(:one).update!(account_activity: nil, number: '2222', total: 10, reference_no: '1111')
|
@registrar = registrars(:bestnames)
|
||||||
|
@invoice = invoices(:one)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_matches_against_invoice_number_and_reference_number
|
||||||
|
create_payable_invoice(number: '2222', total: 10, reference_no: '1111')
|
||||||
transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111')
|
transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111')
|
||||||
|
|
||||||
assert_difference 'AccountActivity.count' do
|
assert_difference 'AccountActivity.count' do
|
||||||
|
@ -10,8 +15,19 @@ class BankTransactionTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_resets_pending_registrar_balance_reload
|
||||||
|
registrar = registrar_with_pending_balance_auto_reload
|
||||||
|
create_payable_invoice(number: '2222', total: 10, reference_no: '1111')
|
||||||
|
transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111')
|
||||||
|
|
||||||
|
transaction.autobind_invoice
|
||||||
|
registrar.reload
|
||||||
|
|
||||||
|
assert_nil registrar.settings['balance_auto_reload']['pending']
|
||||||
|
end
|
||||||
|
|
||||||
def test_does_not_match_against_registrar_reference_number
|
def test_does_not_match_against_registrar_reference_number
|
||||||
registrars(:bestnames).update!(reference_no: '1111')
|
@registrar.update!(reference_no: '1111')
|
||||||
transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111')
|
transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111')
|
||||||
|
|
||||||
assert_no_difference 'AccountActivity.count' do
|
assert_no_difference 'AccountActivity.count' do
|
||||||
|
@ -20,7 +36,7 @@ class BankTransactionTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_underpayment_is_not_matched_with_invoice
|
def test_underpayment_is_not_matched_with_invoice
|
||||||
invoices(:one).update!(account_activity: nil, number: '2222', total: 10)
|
create_payable_invoice(number: '2222', total: 10)
|
||||||
transaction = BankTransaction.new(sum: 9)
|
transaction = BankTransaction.new(sum: 9)
|
||||||
|
|
||||||
assert_no_difference 'AccountActivity.count' do
|
assert_no_difference 'AccountActivity.count' do
|
||||||
|
@ -30,7 +46,7 @@ class BankTransactionTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_overpayment_is_not_matched_with_invoice
|
def test_overpayment_is_not_matched_with_invoice
|
||||||
invoices(:one).update!(account_activity: nil, number: '2222', total: 10)
|
create_payable_invoice(number: '2222', total: 10)
|
||||||
transaction = BankTransaction.new(sum: 11)
|
transaction = BankTransaction.new(sum: 11)
|
||||||
|
|
||||||
assert_no_difference 'AccountActivity.count' do
|
assert_no_difference 'AccountActivity.count' do
|
||||||
|
@ -40,7 +56,7 @@ class BankTransactionTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cancelled_invoice_is_not_matched
|
def test_cancelled_invoice_is_not_matched
|
||||||
invoices(:one).update!(account_activity: nil, number: '2222', total: 10, cancelled_at: '2010-07-05')
|
@invoice.update!(account_activity: nil, number: '2222', total: 10, cancelled_at: '2010-07-05')
|
||||||
transaction = BankTransaction.new(sum: 10)
|
transaction = BankTransaction.new(sum: 10)
|
||||||
|
|
||||||
assert_no_difference 'AccountActivity.count' do
|
assert_no_difference 'AccountActivity.count' do
|
||||||
|
@ -48,4 +64,17 @@ class BankTransactionTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
assert transaction.errors.full_messages.include?('Cannot bind cancelled invoice')
|
assert transaction.errors.full_messages.include?('Cannot bind cancelled invoice')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_payable_invoice(attributes)
|
||||||
|
payable_attributes = { account_activity: nil }
|
||||||
|
@invoice.update!(payable_attributes.merge(attributes))
|
||||||
|
@invoice
|
||||||
|
end
|
||||||
|
|
||||||
|
def registrar_with_pending_balance_auto_reload
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { pending: true } })
|
||||||
|
@registrar
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -176,6 +176,12 @@ class RegistrarTest < ActiveSupport::TestCase
|
||||||
assert_equal vat_country, registrar.vat_country
|
assert_equal vat_country, registrar.vat_country
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_returns_iban_for_e_invoice_delivery_channel
|
||||||
|
iban = 'GB33BUKB20201555555555'
|
||||||
|
registrar = Registrar.new(iban: iban)
|
||||||
|
assert_equal iban, registrar.e_invoice_iban
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def valid_registrar
|
def valid_registrar
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class RegistrarAreaSettingsBalanceAutoReloadTest < ApplicationSystemTestCase
|
||||||
|
setup do
|
||||||
|
@registrar = registrars(:bestnames)
|
||||||
|
@user = users(:api_bestnames)
|
||||||
|
sign_in @user
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_enables_balance_auto_reload
|
||||||
|
amount = 100
|
||||||
|
threshold = 10
|
||||||
|
assert_nil @registrar.settings['balance_auto_reload']
|
||||||
|
|
||||||
|
visit registrar_account_path
|
||||||
|
click_on 'Enable'
|
||||||
|
fill_in 'Amount', with: amount
|
||||||
|
fill_in 'Threshold', with: threshold
|
||||||
|
click_button 'Save'
|
||||||
|
|
||||||
|
assert_current_path registrar_account_path
|
||||||
|
assert_text 'Balance Auto-Reload setting has been updated'
|
||||||
|
|
||||||
|
# Using `number_to_currency` leads to `expected to find text "Reload 100,00 € when your balance
|
||||||
|
# drops to 10,00 €" in "...Reload 100,00 € when your balance drops to 10,00 €...`
|
||||||
|
assert_text 'Reload 100,00 € when your balance drops to 10,00 €'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_disables_balance_auto_reload
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { type: {} } })
|
||||||
|
|
||||||
|
visit registrar_account_path
|
||||||
|
click_on 'Disable'
|
||||||
|
|
||||||
|
assert_current_path registrar_account_path
|
||||||
|
assert_text 'Balance Auto-Reload setting has been disabled'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_edits_balance_auto_reload
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { type: { name: 'threshold',
|
||||||
|
amount: 100,
|
||||||
|
threshold: 10 } } })
|
||||||
|
|
||||||
|
visit registrar_account_path
|
||||||
|
within '.balance-auto-reload' do
|
||||||
|
click_on 'Edit'
|
||||||
|
end
|
||||||
|
fill_in 'Amount', with: '101'
|
||||||
|
fill_in 'Threshold', with: '11'
|
||||||
|
click_button 'Save'
|
||||||
|
|
||||||
|
assert_current_path registrar_account_path
|
||||||
|
assert_text 'Balance Auto-Reload setting has been updated'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_form_is_pre_populated_when_editing
|
||||||
|
amount = 100
|
||||||
|
threshold = 10
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { type: { name: 'threshold',
|
||||||
|
amount: amount,
|
||||||
|
threshold: threshold } } })
|
||||||
|
|
||||||
|
visit edit_registrar_settings_balance_auto_reload_path
|
||||||
|
|
||||||
|
assert_field 'Amount', with: amount
|
||||||
|
assert_field 'Threshold', with: threshold
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_user_of_epp_role_cannot_edit_balance_auto_reload_setting
|
||||||
|
@user.update!(roles: [ApiUser::EPP])
|
||||||
|
visit registrar_account_path
|
||||||
|
assert_no_text 'Balance Auto-Reload'
|
||||||
|
end
|
||||||
|
end
|
79
test/tasks/registrars/reload_balance_test.rb
Normal file
79
test/tasks/registrars/reload_balance_test.rb
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class ReloadBalanceTaskTest < ActiveSupport::TestCase
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@registrar = registrars(:bestnames)
|
||||||
|
EInvoice.provider = EInvoice::Providers::TestProvider.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached
|
||||||
|
reload_amount = 100
|
||||||
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)
|
||||||
|
|
||||||
|
assert_difference -> { registrar.invoices.count } do
|
||||||
|
capture_io { run_task }
|
||||||
|
end
|
||||||
|
|
||||||
|
invoice = registrar.invoices.last
|
||||||
|
assert_equal reload_amount, invoice.subtotal
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_skips_issuing_invoice_when_threshold_is_not_reached
|
||||||
|
registrar = registrar_with_auto_reload_enabled_and_threshold_not_reached
|
||||||
|
|
||||||
|
assert_no_difference -> { registrar.invoices.count } do
|
||||||
|
capture_io { run_task }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_skips_issuing_invoice_when_balance_reload_is_pending
|
||||||
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached
|
||||||
|
registrar.settings['balance_auto_reload']['pending'] = true
|
||||||
|
registrar.save!
|
||||||
|
|
||||||
|
assert_no_difference -> { registrar.invoices.count } do
|
||||||
|
capture_io { run_task }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_marks_registrar_as_pending_balance_reload
|
||||||
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached
|
||||||
|
|
||||||
|
capture_io { run_task }
|
||||||
|
registrar.reload
|
||||||
|
|
||||||
|
assert registrar.settings['balance_auto_reload']['pending']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_output
|
||||||
|
reload_amount = 100
|
||||||
|
registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount)
|
||||||
|
assert_equal 'Best Names', registrar.name
|
||||||
|
|
||||||
|
assert_output %(Registrar "Best Names" got #{number_to_currency(reload_amount, unit: 'EUR')}\nInvoiced total: 1\n) do
|
||||||
|
run_task
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount = 100)
|
||||||
|
auto_reload_type = BalanceAutoReloadTypes::Threshold.new(amount: reload_amount, threshold: 10)
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { type: auto_reload_type } })
|
||||||
|
@registrar.accounts.first.update!(balance: 10)
|
||||||
|
@registrar
|
||||||
|
end
|
||||||
|
|
||||||
|
def registrar_with_auto_reload_enabled_and_threshold_not_reached
|
||||||
|
auto_reload_type = BalanceAutoReloadTypes::Threshold.new(amount: 100, threshold: 10)
|
||||||
|
@registrar.update!(settings: { balance_auto_reload: { type: auto_reload_type } })
|
||||||
|
@registrar.accounts.first.update!(balance: 11)
|
||||||
|
@registrar
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_task
|
||||||
|
Rake::Task['registrars:reload_balance'].execute
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue