Make sure that Directo monthly invoice number frame is not exceeded

This commit is contained in:
Karl Erik Õunapuu 2020-02-19 11:53:15 +02:00
parent d5662f42b8
commit 98683f3bcc
3 changed files with 60 additions and 33 deletions

View file

@ -9,7 +9,7 @@ GIT
GIT
remote: https://github.com/internetee/directo.git
revision: 6ac71939da589fcceb5ef3989ba982134679ec97
revision: 41f4b49da2d4155a76ab57f1cb07bb1d0ba9cdef
branch: directo-api
specs:
directo (0.1.0)

View file

@ -11,7 +11,7 @@ module BookKeeping
'customer_code': accounting_customer_code,
'language': language,
'currency': activities.first.currency,
'date': month.end_of_month.strftime('%Y-%m-%d'),
'date': month.end_of_month.strftime('%Y-%m-%d')
}.as_json
lines = []
@ -43,12 +43,13 @@ module BookKeeping
end
def new_montly_invoice_line(activity:, duration: nil)
price = DirectoInvoiceForwardJob.load_price(activity)
price = load_price(activity)
yearly = price.duration.include?('year')
line = {
'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym],
'quantity': 1,
'price': yearly ? (price.price.amount / price.duration.to_i) : price.amount,
'unit': language == 'en' ? 'pc' : 'tk'
}
line['description'] = description_in_language(price: price, yearly: yearly)
@ -59,8 +60,9 @@ module BookKeeping
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')
start_date = (create_time + (duration - 1).year).end_of_month
end_date = (create_time + (duration - 1).year + 1).end_of_month
line['period'] = start_date..end_date
end
def description_in_language(price:, yearly:)
@ -84,9 +86,10 @@ module BookKeeping
lines.each { |l| total += l['quantity'].to_f * l['price'].to_f }
{
'product_id': Setting.directo_receipt_product_name,
'description': 'Domeenide ettemaks',
'description': language == 'en' ? 'Domains prepayment' : 'Domeenide ettemaks',
'quantity': -1,
'price': total
'price': total,
'unit': language == 'en' ? 'pc' : 'tk'
}
end

View file

@ -1,6 +1,7 @@
class DirectoInvoiceForwardJob < Que::Job
def run(monthly: false, dry: false)
@dry = dry
@monthly = monthly
api_url = ENV['directo_invoice_url']
sales_agent = Setting.directo_sales_agent
payment_term = Setting.directo_receipt_payment_term
@ -26,7 +27,7 @@ class DirectoInvoiceForwardJob < Que::Job
end
def send_monthly_invoices
month = Time.now - 1.month
month = Time.now
Registrar.where.not(test_registrar: true).find_each do |registrar|
next unless registrar.cash_account
@ -35,10 +36,25 @@ class DirectoInvoiceForwardJob < Que::Job
@client.invoices.add_with_schema(invoice: invoice, schema: 'summary')
end
# TODO: Invoice number
assign_montly_numbers
sync_with_directo
end
def assign_montly_numbers
if directo_counter_exceedable?(@client.invoices.count)
raise 'Directo Counter is going to be out of period!'
end
min_directo = Setting.directo_monthly_number_min.presence.try(:to_i)
directo_number = [Setting.directo_monthly_number_last.presence.try(:to_i),
min_directo].compact.max || 0
@client.invoices.each do |inv|
directo_number += 1
inv.number = directo_number
end
end
def valid_invoice_conditions?(invoice)
if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? ||
invoice.account_activity.bank_transaction.sum.nil? ||
@ -57,45 +73,53 @@ class DirectoInvoiceForwardJob < Que::Job
return if @dry
res = @client.invoices.deliver(ssl_verify: false)
update_invoice_directo_state(res.body) if res.code == '200'
update_invoice_directo_state(res.body, @client.invoices.as_xml) if res.code == '200'
rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
Rails.logger.info("[Directo] Failed. Responded with code: #{res.code}, body: #{res.body}")
Rails.logger.info('[Directo] Failed to communicate via API')
end
def update_invoice_directo_state(xml)
def update_invoice_directo_state(xml, req)
Rails.logger.info "[Directo] - Responded with body: #{xml}"
Nokogiri::XML(xml).css('Result').each do |res|
if @monthly
mark_invoice_as_sent(res: res, req: req)
else
inv = Invoice.find_by(number: res.attributes['docid'].value.to_i)
mark_invoice_as_sent(invoice: inv, data: res)
mark_invoice_as_sent(invoice: inv, res: res, req: req)
end
end
end
def mark_invoice_as_sent(invoice:, data:)
invoice.directo_records.create!(response: data.as_json.to_h, invoice_number: invoice.number)
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.invoice = invoice
invoice.update_columns(in_directo: true)
Rails.logger.info("[DIRECTO] Invoice #{invoice.number} was pushed and return is #{data.as_json.to_h.inspect}")
else
update_directo_number(num: directo_record.invoice_number)
end
def self.load_price(account_activity)
@pricelists ||= {}
if @pricelists.key? account_activity.price_id
return @pricelists[account_activity.price_id]
directo_record.save!
end
@pricelists[account_activity.price_id] = account_activity.price
def update_directo_number(num:)
return unless num.to_i > Setting.directo_monthly_number_last
Setting.directo_monthly_number_last = num
end
def last_directo_monthly_number
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
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
last_directo
if max_directo && max_directo < (last_directo + invoice_count)
true
else
false
end
end
end