1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-01 12:24:28 +01:00

Merge branch 'dev' into us78

This commit is contained in:
Sylvain 2019-01-09 16:28:36 +01:00
commit 5e8172af35
6 changed files with 65 additions and 57 deletions

View File

@ -7,7 +7,7 @@ Metrics/CyclomaticComplexity:
Metrics/PerceivedComplexity: Metrics/PerceivedComplexity:
Max: 9 Max: 9
Metrics/AbcSize: Metrics/AbcSize:
Max: 42 Max: 45
Style/BracesAroundHashParameters: Style/BracesAroundHashParameters:
EnforcedStyle: context_dependent EnforcedStyle: context_dependent
Style/RegexpLiteral: Style/RegexpLiteral:

View File

@ -1,7 +1,11 @@
# frozen_string_literal: true
# Avoir is a special type of Invoice, which it inherits. It is used to
# refund an user, based on a previous invoice, or to credit an user's wallet.
class Avoir < Invoice class Avoir < Invoice
belongs_to :invoice belongs_to :invoice
validates :avoir_mode, inclusion: {in: %w[stripe cheque transfer none cash wallet] } validates :avoir_mode, inclusion: { in: %w[stripe cheque transfer none cash wallet] }
attr_accessor :invoice_items_ids attr_accessor :invoice_items_ids

View File

@ -1,3 +1,5 @@
# Invoice correspond to a single purchase made by an user. This purchase may
# include reservation(s) and/or a subscription
class Invoice < ActiveRecord::Base class Invoice < ActiveRecord::Base
include NotifyWith::NotificationAttachedObject include NotifyWith::NotificationAttachedObject
require 'fileutils' require 'fileutils'
@ -13,21 +15,20 @@ class Invoice < ActiveRecord::Base
has_one :avoir, class_name: 'Invoice', foreign_key: :invoice_id, dependent: :destroy has_one :avoir, class_name: 'Invoice', foreign_key: :invoice_id, dependent: :destroy
after_create :update_reference after_create :update_reference
after_commit :generate_and_send_invoice, on: [:create], :if => :persisted? after_commit :generate_and_send_invoice, on: [:create], if: :persisted?
def file def file
dir = "invoices/#{user.id}" dir = "invoices/#{user.id}"
# create directories if they doesn't exists (invoice & user_id) # create directories if they doesn't exists (invoice & user_id)
FileUtils::mkdir_p dir FileUtils.mkdir_p dir
"#{dir}/#{self.filename}" "#{dir}/#{filename}"
end end
def filename def filename
"#{ENV['INVOICE_PREFIX']}-#{self.id}_#{self.created_at.strftime('%d%m%Y')}.pdf" "#{ENV['INVOICE_PREFIX']}-#{id}_#{created_at.strftime('%d%m%Y')}.pdf"
end end
def generate_reference def generate_reference
pattern = Setting.find_by(name: 'invoice_reference').value pattern = Setting.find_by(name: 'invoice_reference').value
@ -62,14 +63,14 @@ class Invoice < ActiveRecord::Base
reference.gsub!(/DD(?![^\[]*\])/, Time.now.strftime('%-d')) reference.gsub!(/DD(?![^\[]*\])/, Time.now.strftime('%-d'))
# information about online selling (X[text]) # information about online selling (X[text])
if self.stp_invoice_id if stp_invoice_id
reference.gsub!(/X\[([^\]]+)\]/, '\1') reference.gsub!(/X\[([^\]]+)\]/, '\1')
else else
reference.gsub!(/X\[([^\]]+)\]/, ''.to_s) reference.gsub!(/X\[([^\]]+)\]/, ''.to_s)
end end
# information about wallet (W[text]) # information about wallet (W[text])
#reference.gsub!(/W\[([^\]]+)\]/, ''.to_s) # reference.gsub!(/W\[([^\]]+)\]/, ''.to_s)
# remove information about refunds (R[text]) # remove information about refunds (R[text])
reference.gsub!(/R\[([^\]]+)\]/, ''.to_s) reference.gsub!(/R\[([^\]]+)\]/, ''.to_s)
@ -83,7 +84,7 @@ class Invoice < ActiveRecord::Base
end end
def order_number def order_number
pattern = Setting.find_by({name: 'invoice_order-nb'}).value pattern = Setting.find_by(name: 'invoice_order-nb').value
# global invoice number (nn..nn) # global invoice number (nn..nn)
reference = pattern.gsub(/n+(?![^\[]*\])/) do |match| reference = pattern.gsub(/n+(?![^\[]*\])/) do |match|
@ -103,34 +104,35 @@ class Invoice < ActiveRecord::Base
end end
# full year (YYYY) # full year (YYYY)
reference.gsub!(/YYYY(?![^\[]*\])/, self.created_at.strftime('%Y')) reference.gsub!(/YYYY(?![^\[]*\])/, created_at.strftime('%Y'))
# year without century (YY) # year without century (YY)
reference.gsub!(/YY(?![^\[]*\])/, self.created_at.strftime('%y')) reference.gsub!(/YY(?![^\[]*\])/, created_at.strftime('%y'))
# abreviated month name (MMM) # abbreviated month name (MMM)
reference.gsub!(/MMM(?![^\[]*\])/, self.created_at.strftime('%^b')) reference.gsub!(/MMM(?![^\[]*\])/, created_at.strftime('%^b'))
# month of the year, zero-padded (MM) # month of the year, zero-padded (MM)
reference.gsub!(/MM(?![^\[]*\])/, self.created_at.strftime('%m')) reference.gsub!(/MM(?![^\[]*\])/, created_at.strftime('%m'))
# month of the year, non zero-padded (M) # month of the year, non zero-padded (M)
reference.gsub!(/M(?![^\[]*\])/, self.created_at.strftime('%-m')) reference.gsub!(/M(?![^\[]*\])/, created_at.strftime('%-m'))
# day of the month, zero-padded (DD) # day of the month, zero-padded (DD)
reference.gsub!(/DD(?![^\[]*\])/, self.created_at.strftime('%d')) reference.gsub!(/DD(?![^\[]*\])/, created_at.strftime('%d'))
# day of the month, non zero-padded (DD) # day of the month, non zero-padded (DD)
reference.gsub!(/DD(?![^\[]*\])/, self.created_at.strftime('%-d')) reference.gsub!(/DD(?![^\[]*\])/, created_at.strftime('%-d'))
reference reference
end end
# for debug & used by rake task "fablab:regenerate_invoices" # for debug & used by rake task "fablab:regenerate_invoices"
def regenerate_invoice_pdf def regenerate_invoice_pdf
pdf = ::PDF::Invoice.new(self).render pdf = ::PDF::Invoice.new(self, nil).render
File.binwrite(file, pdf) File.binwrite(file, pdf)
end end
def build_avoir(attrs = {}) def build_avoir(attrs = {})
raise Exception if has_avoir === true or prevent_refund? raise Exception if refunded? === true || prevent_refund?
avoir = Avoir.new(self.dup.attributes)
avoir = Avoir.new(dup.attributes)
avoir.type = 'Avoir' avoir.type = 'Avoir'
avoir.attributes = attrs avoir.attributes = attrs
avoir.reference = nil avoir.reference = nil
@ -142,16 +144,16 @@ class Invoice < ActiveRecord::Base
paid_items = 0 paid_items = 0
refund_items = 0 refund_items = 0
invoice_items.each do |ii| invoice_items.each do |ii|
paid_items += 1 unless ii.amount == 0 paid_items += 1 unless ii.amount.zero?
if attrs[:invoice_items_ids].include? ii.id # list of items to refund (partial refunds) next unless attrs[:invoice_items_ids].include? ii.id # list of items to refund (partial refunds)
raise Exception if ii.invoice_item # cannot refund an item that was already refunded raise Exception if ii.invoice_item # cannot refund an item that was already refunded
refund_items += 1 unless ii.amount == 0
refund_items += 1 unless ii.amount.zero?
avoir_ii = avoir.invoice_items.build(ii.dup.attributes) avoir_ii = avoir.invoice_items.build(ii.dup.attributes)
avoir_ii.created_at = avoir.avoir_date avoir_ii.created_at = avoir.avoir_date
avoir_ii.invoice_item_id = ii.id avoir_ii.invoice_item_id = ii.id
avoir.total += avoir_ii.amount avoir.total += avoir_ii.amount
end end
end
# handle coupon # handle coupon
unless avoir.coupon_id.nil? unless avoir.coupon_id.nil?
discount = avoir.total discount = avoir.total
@ -167,9 +169,9 @@ class Invoice < ActiveRecord::Base
avoir avoir
end end
def is_subscription_invoice? def subscription_invoice?
invoice_items.each do |ii| invoice_items.each do |ii|
return true if ii.subscription and !ii.subscription.expired? return true if ii.subscription && !ii.subscription.expired?
end end
false false
end end
@ -178,7 +180,7 @@ class Invoice < ActiveRecord::Base
# Test if the current invoice has been refund, totally or partially. # Test if the current invoice has been refund, totally or partially.
# @return {Boolean|'partial'}, true means fully refund, false means not refunded # @return {Boolean|'partial'}, true means fully refund, false means not refunded
## ##
def has_avoir def refunded?
if avoir if avoir
invoice_items.each do |item| invoice_items.each do |item|
return 'partial' unless item.invoice_item return 'partial' unless item.invoice_item
@ -195,7 +197,7 @@ class Invoice < ActiveRecord::Base
# @return {Boolean} # @return {Boolean}
## ##
def prevent_refund? def prevent_refund?
if invoiced_type == 'Reservation' and invoiced.reservable_type == 'Training' if invoiced_type == 'Reservation' && invoiced.reservable_type == 'Training'
user.trainings.include?(invoiced.reservable_id) user.trainings.include?(invoiced.reservable_id)
else else
false false
@ -204,13 +206,15 @@ class Invoice < ActiveRecord::Base
# get amount total paid # get amount total paid
def amount_paid def amount_paid
total - (wallet_amount ? wallet_amount : 0) total - (wallet_amount || 0)
end end
private private
def generate_and_send_invoice def generate_and_send_invoice
unless Rails.env.test? unless Rails.env.test?
puts "Creating an InvoiceWorker job to generate the following invoice: id(#{id}), invoiced_id(#{invoiced_id}), invoiced_type(#{invoiced_type}), user_id(#{user_id})" puts "Creating an InvoiceWorker job to generate the following invoice: id(#{id}), invoiced_id(#{invoiced_id}), " \
"invoiced_type(#{invoiced_type}), user_id(#{user_id})"
end end
InvoiceWorker.perform_async(id, user&.subscription&.expired_at) InvoiceWorker.perform_async(id, user&.subscription&.expired_at)
end end
@ -243,11 +247,11 @@ class Invoice < ActiveRecord::Base
start = DateTime.current.beginning_of_year start = DateTime.current.beginning_of_year
ending = DateTime.current.end_of_year ending = DateTime.current.end_of_year
else else
return self.id return id
end
if defined? start and defined? ending
Invoice.where('created_at >= :start_date AND created_at < :end_date', {start_date: start, end_date: ending}).length
end end
return Invoice.count unless defined? start && defined? ending
Invoice.where('created_at >= :start_date AND created_at < :end_date', start_date: start, end_date: ending).length
end end
end end

View File

@ -3,9 +3,9 @@ json.array!(@invoices) do |invoice|
json.total (invoice.total / 100.00) json.total (invoice.total / 100.00)
json.url invoice_url(invoice, format: :json) json.url invoice_url(invoice, format: :json)
json.name invoice.user.profile.full_name json.name invoice.user.profile.full_name
json.has_avoir invoice.has_avoir json.has_avoir invoice.refunded?
json.is_avoir invoice.is_a?(Avoir) json.is_avoir invoice.is_a?(Avoir)
json.is_subscription_invoice invoice.is_subscription_invoice? json.is_subscription_invoice invoice.subscription_invoice?
json.stripe invoice.stp_invoice_id? json.stripe invoice.stp_invoice_id?
json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at
json.prevent_refund invoice.prevent_refund? json.prevent_refund invoice.prevent_refund?

View File

@ -6,9 +6,9 @@ json.array!(@invoices) do |invoice|
json.total (invoice.total / 100.00) json.total (invoice.total / 100.00)
json.url invoice_url(invoice, format: :json) json.url invoice_url(invoice, format: :json)
json.name invoice.user.profile.full_name json.name invoice.user.profile.full_name
json.has_avoir invoice.has_avoir json.has_avoir invoice.refunded?
json.is_avoir invoice.is_a?(Avoir) json.is_avoir invoice.is_a?(Avoir)
json.is_subscription_invoice invoice.is_subscription_invoice? json.is_subscription_invoice invoice.subscription_invoice?
json.stripe invoice.stp_invoice_id? json.stripe invoice.stp_invoice_id?
json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at
json.prevent_refund invoice.prevent_refund? json.prevent_refund invoice.prevent_refund?

View File

@ -1,9 +1,9 @@
json.extract! @invoice, :id, :created_at, :reference, :invoiced_type, :user_id, :avoir_date, :description json.extract! @invoice, :id, :created_at, :reference, :invoiced_type, :user_id, :avoir_date, :description
json.total (@invoice.total / 100.00) json.total (@invoice.total / 100.00)
json.name @invoice.user.profile.full_name json.name @invoice.user.profile.full_name
json.has_avoir @invoice.has_avoir json.has_avoir @invoice.refunded?
json.is_avoir @invoice.is_a?(Avoir) json.is_avoir @invoice.is_a?(Avoir)
json.is_subscription_invoice @invoice.is_subscription_invoice? json.is_subscription_invoice @invoice.subscription_invoice?
json.stripe @invoice.stp_invoice_id? json.stripe @invoice.stp_invoice_id?
json.date @invoice.is_a?(Avoir) ? @invoice.avoir_date : @invoice.created_at json.date @invoice.is_a?(Avoir) ? @invoice.avoir_date : @invoice.created_at
json.items @invoice.invoice_items do |item| json.items @invoice.invoice_items do |item|