require 'orbit_form_helper' class VenueManagementBill include Mongoid::Document include Mongoid::Timestamps 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_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