venue_management/app/models/venue_management_bill.rb

259 lines
9.7 KiB
Ruby

require 'orbit_form_helper'
class VenueManagementBill
include Mongoid::Document
include Mongoid::Timestamps
require 'mongoid/enum'
include Mongoid::Enum
BILLTYPE = {'venue_fee'=>["usage_fee", "royalties", "admin_fee", "land_rent"],'utility_bill'=>['electricity','water'],'tax'=>['house_tax','land_tax'],'prejudgment_interest'=>["usage_fee", "royalties", "admin_fee", "land_rent",'electricity','water','house_tax','land_tax','other'],'other'=>['penalty','other']}
NOTFIELDKEY = ['float','fields','clear','no_margin','unit','display_title','display_unit','option_select']
CACULATIONBASISTYPE = {'revenue'=>{'revenue'=>{},'level_0'=>{'fields'=>['field_value','percent']},'level_1'=>{'fields'=>['field_value','percent']},'level_2'=>{'fields'=>['field_value','percent']},'level_3'=>{'fields'=>['field_value','percent']},'level_4'=>{'fields'=>['field_value','percent']},'level_5'=>{'fields'=>['field_value','percent']}},
'degree'=>{'current_degree'=>{'float'=>'left'},'consumption'=>{'float'=>'left','clear'=>true,'no_margin'=>true},'level_0'=>{'fields'=>['field_value','dollar/degree']},'level_1'=>{'fields'=>['field_value','dollar/degree']},'level_2'=>{'fields'=>['field_value','dollar/degree']},'level_3'=>{'fields'=>['field_value','dollar/degree']},'add_and_subtract'=>{'unit'=>'add_and_subtract_hint'}},
'actual_bill'=>{'bill_amount'=>{}},
'fixed'=>{'amount'=>{}},
'taxable_present_value'=>{'present_value'=>{},'taxable_area'=>{'unit'=>'㎡'},'taxable_tax'=>{}},
'announced_land_values'=>{'land_values'=>{},'taxable_area'=>{'unit'=>'㎡'},'taxable_tax'=>{}},
'interest'=>{'bills_payable'=>{},'delay_in_days'=>{},'delay_in_days_level_1'=>{'day'=>{},'_interest'=>{'display_title'=>'front','unit'=>'%'},'interest_type'=>{'display_title'=>'none','option_select'=>['annual_interest','double_dividend','daily_interest'],'type'=>'radio'}},'delay_in_days_level_2'=>{'day'=>{},'_interest'=>{'display_title'=>'front','unit'=>'%'},'interest_type'=>{'display_title'=>'none','option_select'=>['annual_interest','double_dividend','daily_interest'],'type'=>'radio'}},'delay_in_days_level_3'=>{'day'=>{},'_interest'=>{'display_title'=>'front','unit'=>'%'},'interest_type'=>{'display_title'=>'none','option_select'=>['annual_interest','double_dividend','daily_interest'],'type'=>'radio'}},'add_and_subtract'=>{'unit'=>'add_and_subtract_hint'}},
'other'=>{'amount'=>{}}}
CACILATYIONFORMULA = {'revenue'=>"
i = find_insert_index(field_values,revenue)
field_values = field_values.slice(0,i)
percents = percents.slice(0,i)
field_values.push(revenue)
percents.push(0)
result = -inner_product(field_values,percents)
f=field_values.shift(1)
field_values.push(f[0])
result += inner_product(field_values,percents)
result = result / 100
if(result < 0){
result = 0
}",
"degree"=>"
i = find_insert_index(field_values,consumption)
field_values = field_values.slice(0,i)
dollardegrees = dollardegrees.slice(0,i)
field_values.push(consumption)
dollardegrees.push(0)
result = -inner_product(field_values,dollardegrees)
f=field_values.shift(1)
field_values.push(f[0])
result += inner_product(field_values,dollardegrees)
result += add_and_subtract
if(result < 0){
result = 0
}
",
"actual_bill"=>"
result = bill_amount
if(result < 0){
result = 0
}
",
"fixed"=>"
result = amount
if(result < 0){
result = 0
}
",
"taxable_present_value"=>"
result = taxable_tax
if(result < 0){
result = 0
}",
"announced_land_values"=>"
result = taxable_tax
if(result < 0){
result = 0
}",
"other"=>"
result = amount
if(result < 0){
result = 0
}",
'interest'=>"
i = find_insert_index(days,delay_in_days)
ref = JSON.parse(\"{\\\"annual_interest\\\": #{1/365.0},\\\"double_dividend\\\": #{1/2.0},\\\"daily_interest\\\": #{1/1.0}}\")
if(days[i-1] < delay_in_days && interest_types[i-1] != undefined ){
if(interest_types[i-1] == 'double_dividend'){
result = _interests[i - 1] * (delay_in_days * ref[interest_types[i-1]]).ceil()
}else{
result = _interests[i - 1] * (delay_in_days * ref[interest_types[i-1]])
}
}else{
if(i != 1 && days[i-2] < delay_in_days && interest_types[i-2] != undefined ){
if(interest_types[i-2] == 'double_dividend'){
result = _interests[i - 2] * (delay_in_days * ref[interest_types[i-2]]).ceil()
}else{
result = _interests[i - 2] * (delay_in_days * ref[interest_types[i-2]])
}
}else{
result = 0
}
}
result = result / 100
result = result * bills_payable
result += add_and_subtract
if(result < 0){
result = 0
}
",
'old_interest'=>"
i = find_insert_index(days,delay_in_days)
days = days.slice(0,i)
_interests = _interests.slice(0,i)
days.push(delay_in_days)
_interests.push(0)
result = inner_product_to_array(days,_interests)
result = array_multiply_scalar(result,-1)
f=days.shift(1)
days.push(f[0])
result2 = inner_product_to_array(days,_interests)
result = array_add(result,result2)
result = inner_product_to_array(result,interest_types,JSON.parse(\"{\\\"annual_interest\\\": #{1/365.0},\\\"double_dividend\\\": #{1/2.0},\\\"daily_interest\\\": #{1/1.0}}\"))
result = sum(result)
result = result / 100
result = result * bills_payable
result += add_and_subtract
if(result < 0)
result = 0
"
}
CACULATIONBASIS = {'revenue'=>"revenue",
"degree"=>"consumption",
"actual_bill" => "bill_amount",
"fixed"=>"amount",
"taxable_present_value"=>"present_value",
"announced_land_values"=>"land_values",
'interest'=>'bills_payable',
"other"=>"amount"
}
field :accounting_month, type: Date, default: Time.now
field :bill_typeA, type: String, default: ""
field :bill_typeB, type: String, default: ""
field :bill_other, type: String, default: "", localize: true
field :caculation_basis_type, type: String, default: ""
field :caculation_basis, type: String, default: ""
field :reason, type: String, default: "", localize: true
field :amount, type: Integer, default: 0
field :deadline, type: Date, default: Time.now
field :received_date, type: Date, default: Time.now
field :pay_method, type: String, default: "", localize: true
field :note, type: String, default: "", localize: true
field :revenue
field :bill_amount
field :level_0
field :level_1
field :level_2
field :level_3
field :level_4
field :level_5
field :delay_in_days_level_1
field :delay_in_days_level_2
field :delay_in_days_level_3
field :current_degree
field :consumption
field :tax_excluded, type: Boolean, default: false
field :total_amount
field :actual_amount
field :tax
field :present_value
field :taxable_area
field :land_values
field :taxable_tax
field :add_and_subtract
field :bills_payable
field :delay_in_days
belongs_to :venue_management_main
include VenueLinkFile
# after_initialize do |record|
# if record.caculation_basis_type == "degree"
# if record.caculation_basis != "" && record.consumption.blank?
# record.update(:consumption => record.caculation_basis)
# end
# elsif record.caculation_basis_type == "revenue"
# if record.caculation_basis != "" && record.revenue.blank?
# record.update(:revenue => record.caculation_basis)
# end
# end
# end
# after_save do |record|
# venue_management_main = record.venue_management_main
# if !venue_management_main.venue_management_bill_ids.include?(record.id)
# venue_management_main.update(venue_management_main.venue_management_bill_ids.push(record.id))
# end
# end
def display_note
html = self.note.to_s.split("\r\n").select{|s| !s.blank?}.first
return Nokogiri::HTML(html).css("body").text
end
def display_caculation_basis
caculation_basis_val = eval("#{self.class::CACULATIONBASIS[self.caculation_basis_type]}")
return "#{I18n.t("vm_bill.#{self.class::CACULATIONBASIS[self.caculation_basis_type]}")}: #{caculation_basis_val}"
end
def display_accounting_month
return (self.accounting_month.strftime("%Y-%m") rescue "")
end
def case_no
return (self.contractor.case_no rescue "")
end
def contractor
return self.venue_management_main.venue_management_contracts.where(:contract_start_date.lte=>self.accounting_month,:contract_end_date.gte=>self.accounting_month).first
end
def pay_date
return "#{self.deadline}/#{self.received_date}"
end
def inner_product(a,b,ref_val_for_b={})
result = 0
a.each.with_index{|v,i|
if ref_val_for_b.blank?
p = v*b[i] rescue nil;
else
p = v*ref_val_for_b[b[i]] rescue nil;
end
if(!p.nil?)
result += p;
end
}
return result
end
def inner_product_to_array(a,b)
result = []
a.each.with_index{|v,i|
p = v*b[i] rescue nil;
if(!p.nil?)
result.push(p);
end
}
return result
end
def array_multiply_scalar(arr,scalar)
result = [];
arr.each.with_index{|v,i|
p = v*scalar rescue nil;
if(!p.nil?)
result.push(p);
end
}
return result;
end
def array_add(arr1,arr2)
result = [];
arr1.each.with_index{|v,i|
p = v + arr2[i] rescue nil;
if(!p.nil?)
result.push(p);
end
}
return result;
end
def sum(arr)
result = 0;
arr.each.with_index{|v,i|
if(!v.nil?)
result += v;
end
}
return result;
end
end