From 5204097ed626884e8f6446f86cd8dd93607523c5 Mon Sep 17 00:00:00 2001 From: Axel Liljencrantz Date: Fri, 13 Aug 2010 11:03:43 +0200 Subject: [PATCH] More performance work. Add pagination in a bunch of places. Fix various minor bugs. --- .gitignore | 1 + Gemfile | 4 +- TODO.txt | 19 + app/controllers/admin/companies_controller.rb | 3 +- app/controllers/admin/users_controller.rb | 2 +- app/controllers/application_controller.rb | 7 + app/controllers/journals_controller.rb | 8 +- app/controllers/paychecks_controller.rb | 6 +- app/models/company.rb | 6 + app/models/journal.rb | 2 + app/models/paycheck.rb | 2 + app/models/property.rb | 3 + app/models/user.rb | 5 + app/views/admin/companies/index.html.erb | 2 + app/views/admin/companies/show.html.erb | 10 +- app/views/admin/users/index.html.erb | 2 + app/views/admin/users/show.html.erb | 6 +- app/views/journals/_form.html.erb | 1 - app/views/journals/index.html.erb | 21 +- app/views/paychecks/index.html.erb | 5 +- app/views/shared/_period_picker.html.erb | 16 + config/initializers/periods.rb | 1 + config/initializers/properties.rb | 3 + config/initializers/timer.rb | 11 + config/locales/nb.yml | 5 +- .../20100729115340_create_properties.rb | 17 + db/migrate/20100730090140_add_misc_indices.rb | 24 + lib/period_controller.rb | 43 ++ lib/property_model.rb | 38 ++ lib/tasks/blueprints.rake | 18 +- test/bulkdata.rb | 431 +++++++++++------- 31 files changed, 522 insertions(+), 200 deletions(-) create mode 100644 TODO.txt create mode 100644 app/models/property.rb create mode 100644 app/views/shared/_period_picker.html.erb create mode 100644 config/initializers/periods.rb create mode 100644 config/initializers/properties.rb create mode 100644 config/initializers/timer.rb create mode 100644 db/migrate/20100729115340_create_properties.rb create mode 100644 db/migrate/20100730090140_add_misc_indices.rb create mode 100644 lib/period_controller.rb create mode 100644 lib/property_model.rb diff --git a/.gitignore b/.gitignore index 3daf56b..1cb4196 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ /*.patch !.gitignore /doc/plugins +Gemfile.lock diff --git a/Gemfile b/Gemfile index 7c36551..011d2e6 100644 --- a/Gemfile +++ b/Gemfile @@ -10,10 +10,12 @@ gem 'rails', '3.0.0.rc' # postgresql gem 'pg' +gem 'will_paginate', :git => 'git://github.com/mislav/will_paginate.git', :branch => 'rails3' + gem 'ruby_parser' gem "machinist" gem "faker" -gem "devise", "1.1.rc2" +gem "devise", "~>1.1" gem "warden" gem "declarative_authorization", :git => "http://github.com/stffn/declarative_authorization.git" diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..61d47e2 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,19 @@ + + +Statistik: + +Før alla stængda perioder: + * # open bills + * # bills + * # journal entries + * Før alla konto/unit/project kombos med transaktioner: + * debet + * kredit + +Bættra på bulkinsættning: + +* Ordrer +* Fakturor + + + diff --git a/app/controllers/admin/companies_controller.rb b/app/controllers/admin/companies_controller.rb index 5cd0c07..9307442 100644 --- a/app/controllers/admin/companies_controller.rb +++ b/app/controllers/admin/companies_controller.rb @@ -1,6 +1,5 @@ class Admin::CompaniesController < Admin::BaseController - before_filter :find_company, :only => [:show, :edit, :update, :destroy] def find_company @@ -13,7 +12,7 @@ def find_company # GET /companies # GET /companies.xml def index - @companies = Company.order("name").includes(:assignments).includes(:address) + @companies = Company.order("name").includes(:assignments).includes(:address).paginate({:page => params[:page]}) @companies.each do |c| if !c.address diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index aa10f8f..da1a20e 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -35,7 +35,7 @@ def show end def index - @users = User.order(:email).includes(:companies) + @users = User.order(:email).includes(:companies).paginate({:page => params[:page]}) respond_to do |format| format.html # index.html.erb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e14c86c..e4b1c65 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -50,4 +50,11 @@ def permission_denied redirect_to root_url end + def user_property name, default + fn = controller_name + "." + action_name + "." + name.to_s + foo = params[name] || current_user.get_property( fn ) || default + current_user.set_property( fn, foo) + end + + end diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb index e14c418..7113811 100644 --- a/app/controllers/journals_controller.rb +++ b/app/controllers/journals_controller.rb @@ -1,4 +1,7 @@ class JournalsController < ApplicationController + + include PeriodController + before_filter :find_units_all, :only => [:new, :edit] before_filter :find_projects_all, :only => [:new, :edit] before_filter :find_accounts_all, :only => [:new, :edit] @@ -7,13 +10,14 @@ class JournalsController < ApplicationController # GET /journals # GET /journals.xml def index - @journals = Journal.with_permissions_to(:index).order("number, journal_date desc, journal_type") - + @journals = period_filter(Journal.with_permissions_to(:index).order("number, journal_date desc, journal_type")).paginate({:page => params[:page]}) + respond_to do |format| format.html # index.html.erb format.xml { render :xml => @journals } end end + # GET /journals/1 # GET /journals/1.xml diff --git a/app/controllers/paychecks_controller.rb b/app/controllers/paychecks_controller.rb index 693ebd3..332a7ff 100644 --- a/app/controllers/paychecks_controller.rb +++ b/app/controllers/paychecks_controller.rb @@ -1,4 +1,7 @@ class PaychecksController < ApplicationController + + include PeriodController + before_filter :setup_form before_filter :employee_required, :except => [:index] @@ -11,9 +14,10 @@ def setup_form @units = current_user.current_company.units @projects = current_user.current_company.projects @employees = current_user.current_company.employees - @paychecks = current_user.current_company.paychecks + @paychecks = period_filter(current_user.current_company.paychecks.includes(:period).includes(:employee)) @units = current_user.current_company.units @projects = current_user.current_company.projects + # @periods = current_user.current_company.periods.select {|p| p.open?} end diff --git a/app/models/company.rb b/app/models/company.rb index 342c207..92da935 100644 --- a/app/models/company.rb +++ b/app/models/company.rb @@ -22,6 +22,8 @@ class Company < ActiveRecord::Base attr_accessor :template_company_id after_create :init_from_template, :if => proc { !self.template_company_id.blank? } + self.per_page = 50 + # hmm.. no idea what validations make sense atm #validates :organization_number, :format => {:with => /^(NO|no)?[\d]{9,}(MVA|mva)?$/} @@ -116,4 +118,8 @@ def paychecks r end + def to_s + name + end + end diff --git a/app/models/journal.rb b/app/models/journal.rb index 0ddf0f5..ad74719 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -4,6 +4,8 @@ class Journal < ActiveRecord::Base belongs_to :bill belongs_to :period + self.per_page = 200 + def open? return (not self.closed) end diff --git a/app/models/paycheck.rb b/app/models/paycheck.rb index f22417e..e75c725 100644 --- a/app/models/paycheck.rb +++ b/app/models/paycheck.rb @@ -4,4 +4,6 @@ class Paycheck < ActiveRecord::Base has_many :paycheck_lines accepts_nested_attributes_for :paycheck_lines + + end diff --git a/app/models/property.rb b/app/models/property.rb new file mode 100644 index 0000000..92a8451 --- /dev/null +++ b/app/models/property.rb @@ -0,0 +1,3 @@ +class Property < ActiveRecord::Base + belongs_to :model +end diff --git a/app/models/user.rb b/app/models/user.rb index 0223e81..8304286 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,9 @@ require 'digest/sha1' class User < ActiveRecord::Base + + include ::PropertyModel + has_many :companies, :through => :assignments, :uniq => true, :order => "companies.name" belongs_to :current_company, :class_name => 'Company' @@ -16,6 +19,8 @@ class User < ActiveRecord::Base # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :assignments_attributes + self.per_page = 20 + # return array of roles for self.current_company def role_symbols return @symbols if defined? @symbols diff --git a/app/views/admin/companies/index.html.erb b/app/views/admin/companies/index.html.erb index a4ffe63..5cc8b32 100644 --- a/app/views/admin/companies/index.html.erb +++ b/app/views/admin/companies/index.html.erb @@ -1,5 +1,7 @@

<%= t(:listing_companies, :scope => :companies) -%>

+<%= will_paginate @companies %> + diff --git a/app/views/admin/companies/show.html.erb b/app/views/admin/companies/show.html.erb index 275c1db..d2c9d4a 100644 --- a/app/views/admin/companies/show.html.erb +++ b/app/views/admin/companies/show.html.erb @@ -5,12 +5,12 @@

<%= t(:users, :scope => :companies) -%>: - <%= @company.users.collect {|u| u.email}.join ", " %> -

+ -

- <%= t(:accounts, :scope => :companies) -%>: - <%= @company.accounts.map {|a| "#{a.number} - #{a.name}"}.join(", ") %>

diff --git a/app/views/admin/users/index.html.erb b/app/views/admin/users/index.html.erb index e43580b..4fbf502 100644 --- a/app/views/admin/users/index.html.erb +++ b/app/views/admin/users/index.html.erb @@ -1,5 +1,7 @@

<%= t(:listing_users, :scope => :users) -%>

+<%= will_paginate @users %> +
<%= t(:name, :scope => :companies) -%>
diff --git a/app/views/admin/users/show.html.erb b/app/views/admin/users/show.html.erb index cd266b2..23d5e84 100644 --- a/app/views/admin/users/show.html.erb +++ b/app/views/admin/users/show.html.erb @@ -6,7 +6,11 @@

<%= t(:companies, :scope => :users) -%>: - <%= @user.companies.collect{|c| link_to c.name, admin_company_path(c)}.join(", ") %> +

<%= link_to t(:edit, :scope => :users), edit_admin_user_path(@user) %> | diff --git a/app/views/journals/_form.html.erb b/app/views/journals/_form.html.erb index b7a3ab5..1a91ce1 100644 --- a/app/views/journals/_form.html.erb +++ b/app/views/journals/_form.html.erb @@ -81,7 +81,6 @@ <%= t(:text, :scope => :journals) %> diff --git a/app/views/journals/index.html.erb b/app/views/journals/index.html.erb index 6293027..47ec17c 100644 --- a/app/views/journals/index.html.erb +++ b/app/views/journals/index.html.erb @@ -1,5 +1,8 @@

<%= t(:listing_journals, :scope => :journals) -%>

+<%= render :partial => "shared/period_picker" %> +<%= will_paginate @companies %> +
<%= t(:email, :scope => :users) -%> -
@@ -8,18 +11,27 @@ +<% +show_text = t("global.show") +edit_text = t("global.edit") +destroy_text = t("global.destroy") + +def url_gen(object); "/#{object.class.name.tableize}/#{object.id}"; end + +%> <% for journal in @journals %> <% end %> diff --git a/app/views/paychecks/index.html.erb b/app/views/paychecks/index.html.erb index 3d41187..dcea45e 100644 --- a/app/views/paychecks/index.html.erb +++ b/app/views/paychecks/index.html.erb @@ -15,6 +15,8 @@ <% end %>
<%= t(:type, :scope => :journals) -%>
<%= journal.journal_type %> <%= journal.number %> <%= journal.journal_date ? l(journal.journal_date) : "" %> - <%= link_to t("global.show"), journal %> + + <%= link_to show_text, url_gen(journal) %> <% if permitted_to? :edit, journal %> - <%= link_to t("global.edit"), edit_journal_path(journal) %> + <%= link_to edit_text, url_gen(journal)+"/edit" %> <% end %> <% if permitted_to? :delete, journal %> - <%= link_to t("global.destroy"), journal, :confirm => 'Are you sure?', :method => :delete %> + <%= link_to destroy_text, url_gen(journal), :confirm => 'Are you sure?', :method => :delete %> <% elsif not journal.bill.nil? %> <%= link_to 'Show bill', :controller => "bills", :action => "show", :id => journal.bill.id %> <% if permitted_to? :edit, journal.bill %> @@ -28,7 +40,8 @@ <% if permitted_to? :delete, journal.bill %> <%= link_to 'Destroy bill', journal.bill, :confirm => 'Are you sure?', :method => :delete %> <% end %> - <% end %> + <% end %> +
+<%= render :partial => "shared/period_picker" %> + @@ -29,7 +31,8 @@ + <%= link_to t('global.destroy'), paycheck, :confirm => t('global.confirm'), :method => :delete %> + <% end %> diff --git a/app/views/shared/_period_picker.html.erb b/app/views/shared/_period_picker.html.erb new file mode 100644 index 0000000..d23e380 --- /dev/null +++ b/app/views/shared/_period_picker.html.erb @@ -0,0 +1,16 @@ +
+<%= form_tag "", :method => :get do %> +
+<%= label :first_period, t('period_picker.first_period') %> +<%= select_tag 'first_period', options_for_select(current_user.current_company.periods.map {|e| e.to_s}, first_period) %> +
+
+ +<%= label :first_period, t('period_picker.last_period') %> +<%= select_tag 'last_period', options_for_select(current_user.current_company.periods.map {|e| e.to_s}, last_period) %> +
+<%= submit_tag t('global.filter') %> +<% end %> +
+ + diff --git a/config/initializers/periods.rb b/config/initializers/periods.rb new file mode 100644 index 0000000..799cf9b --- /dev/null +++ b/config/initializers/periods.rb @@ -0,0 +1 @@ +require 'period_controller' diff --git a/config/initializers/properties.rb b/config/initializers/properties.rb new file mode 100644 index 0000000..e5b227f --- /dev/null +++ b/config/initializers/properties.rb @@ -0,0 +1,3 @@ + + +require 'property_model' diff --git a/config/initializers/timer.rb b/config/initializers/timer.rb new file mode 100644 index 0000000..b0c8b19 --- /dev/null +++ b/config/initializers/timer.rb @@ -0,0 +1,11 @@ + +def print_time name, &block + print "#{name}..." + a = Time.now + foo = yield block + b = Time.now + print " Used #{b-a} seconds.\n" + return foo +end + + diff --git a/config/locales/nb.yml b/config/locales/nb.yml index 2506a92..6615e1a 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -143,6 +143,7 @@ one: Periode other: Perioder save: Lagre + filter: Kjempefiltrer admin: companies: select_template_company: Bruk som mal @@ -362,6 +363,8 @@ units: header_edit: Kjemperedigerer avdelning header_index: Kjempelister avdelninger - + period_picker: + first_period: Fra + last_period: Til diff --git a/db/migrate/20100729115340_create_properties.rb b/db/migrate/20100729115340_create_properties.rb new file mode 100644 index 0000000..4203a06 --- /dev/null +++ b/db/migrate/20100729115340_create_properties.rb @@ -0,0 +1,17 @@ +class CreateProperties < ActiveRecord::Migration + def self.up + create_table :properties do |t| + t.string :key, :null => false + t.text :value, :null => false + t.string :model_name + t.integer :model_id + end + add_index :properties, [:key], {:name => 'properties_key'} + add_index :properties, [:model_id], {:name => 'properties_model_id'} + add_index :properties, [:key, :model_name, :model_id], {:unique => true} + end + + def self.down + drop_table :properties + end +end diff --git a/db/migrate/20100730090140_add_misc_indices.rb b/db/migrate/20100730090140_add_misc_indices.rb new file mode 100644 index 0000000..8c0414e --- /dev/null +++ b/db/migrate/20100730090140_add_misc_indices.rb @@ -0,0 +1,24 @@ +class AddMiscIndices < ActiveRecord::Migration + def self.up + add_index :periods, :company_id, {:name => 'periods_company_idx'} + add_index :journals, :period_id, {:name => 'journals_period_idx'} + add_index :bills, :period_id, {:name => 'bills_period_idx'} + add_index :bills, :company_id, {:name => 'bills_company_idx'} + + add_index :journals, [:company_id, :number, :journal_type], {:name => 'journals_misc_idx'} + execute "cluster journals_misc_idx on journals" + + execute "create index journals_bill_idx on journals (bill_id) where bill_id is not null;" + end + + def self.down + remove_index 'periods', 'periods_company_idx' + remove_index 'journals', 'journals_period_idx' + remove_index 'bills', 'bills_period_idx' + remove_index 'bills', 'bills_company_idx' + + remove_index 'journals', 'journals_misc_idx' + + execute "drop index journals_bill_idx" + end +end diff --git a/lib/period_controller.rb b/lib/period_controller.rb new file mode 100644 index 0000000..456c603 --- /dev/null +++ b/lib/period_controller.rb @@ -0,0 +1,43 @@ + +module PeriodController + + def self.included(c) + c.helper_method :first_period + c.helper_method :last_period + end + + def first_period + user_property( :first_period, "#{Time.now.year} 01") + end + + def last_period + user_property( :last_period, "#{Time.now.year} 12") + end + + def period_filter list + + first_period = user_property( :first_period, "#{Time.now.year} 01").split + last_period = user_property( :last_period, "#{Time.now.year} 12").split + + first_year = first_period[0] + last_year = last_period[0] + first_nr = first_period[1] + last_nr = last_period[1] + + if first_year == last_year + list.joins(:period).where("(periods.year = :first_year and periods.nr >= :first_nr and periods.nr <= :last_nr)", + { :first_year => first_year, + :first_nr => first_nr, + :last_nr => last_nr }) + else + list.joins(:period).where("((periods.year > :first_year and periods.year < :last_year) or (periods.year = :first_year and periods.nr >= :first_nr) or (periods.year = :last_year and periods.nr <= :last_nr))", + { :first_year => first_year, + :last_year => last_year, + :first_nr => first_nr, + :last_nr => last_nr }) + end + end + + +end + diff --git a/lib/property_model.rb b/lib/property_model.rb new file mode 100644 index 0000000..5678b22 --- /dev/null +++ b/lib/property_model.rb @@ -0,0 +1,38 @@ + +module PropertyModel + + def get_property key + res = Property.where(:key => key.to_s, :model_id => self.id, :model_name => self.class.to_s).first + res ? ActiveSupport::JSON.decode(res.value):nil + end + + def check_property key, default + res = Property.where(:key => key.to_s, :model_id => self.id, :model_name => self.class.to_s).first + if res + ActiveSupport::JSON.decode(res.value) + else + Property.create :key => key.to_s, :model_id => self.id, :model_name => self.class.to_s, :value => default.to_json + default + end + end + + def set_property key, value + res = Property.where(:key => key.to_s, :model_id => self.id, :model_name => self.class.to_s).first + if res + res.value = value.to_json + res.save + else + Property.create :key => key.to_s, :model_id => self.id, :model_name => self.class.to_s, :value => value.to_json + end + value + end + + def destroy_property key + res = Property.where(:key => key.to_s, :model_id => self.id, :model_name => self.class.to_s).first + if res + res.destroy + end + end + +end + diff --git a/lib/tasks/blueprints.rake b/lib/tasks/blueprints.rake index 020f151..4836840 100644 --- a/lib/tasks/blueprints.rake +++ b/lib/tasks/blueprints.rake @@ -17,9 +17,8 @@ namespace "db" do task "load_bulk" => ["environment", "db:test:prepare"] do raise "set RAILS_ENV=test before running task" unless Rails.env == "test" $BULK_APPEND = false + $BULK_SALARY = false require 'test/bulkdata' - #config = Rails::Configuration.new - #ActiveRecord::Base.connection.execute("vacuum analyze") if config.database_configuration["test"]["adapter"] == "postgresql" end end end @@ -30,9 +29,20 @@ namespace "db" do task "append_bulk" => ["environment"] do raise "set RAILS_ENV=test before running task" unless Rails.env == "test" $BULK_APPEND = true + $BULK_SALARY = false + require 'test/bulkdata' + end + end +end + +namespace "db" do + namespace "test" do + desc "Load salary information into test db" + task "append_salary" => ["environment"] do + raise "set RAILS_ENV=test before running task" unless Rails.env == "test" + $BULK_APPEND = true + $BULK_SALARY = true require 'test/bulkdata' - #config = Rails::Configuration.new - #ActiveRecord::Base.connection.execute("vacuum analyze") if config.database_configuration["test"]["adapter"] == "postgresql" end end end diff --git a/test/bulkdata.rb b/test/bulkdata.rb index 209f7c8..1e8190b 100644 --- a/test/bulkdata.rb +++ b/test/bulkdata.rb @@ -18,7 +18,14 @@ PROJECT_COUNT = 7 # 7 YEARS=(2000..2010) +# Maximum number of journals per period and company MAX_JOURNAL_COUNT=500 +# Number of journal operations per journal entry +JOURNAL_OPERATION_COUNT = 5 +# Number of employees per company +EMPLOYEE_COUNT = 5 +# Password used for _all_ users, including admins +PASSWORD= "Secret123" def print_time name, &block print "#{name}..." @@ -42,6 +49,8 @@ def print_time name, &block suffix = Time.now.usec.to_s Sham.login { Faker::Internet.user_name } +Sham.name(:unique => false) { Faker::Name.name } +Sham.phone(:unique => false) { Faker::PhoneNumber.phone_number } Sham.email { Faker::Internet.email } Sham.company_name { Faker::Company.name + suffix } Sham.street1(:unique => false) { Faker::Address.street_name } @@ -54,17 +63,17 @@ def print_time name, &block Sham.product_name(:unique => false) { Faker::Lorem.words(3).join(" ").capitalize } Sham.account_name(:unique => false) { Faker::Lorem.words(3).join(" ").capitalize } Sham.role_name(:unique => true) { Faker::Lorem.words(3).join("_").downcase } - +Sham.description(:unique => false) { Faker::Company.catch_phrase } User.blueprint do email { Sham.email } - password { "Secret123" } + password { PASSWORD } password_confirmation { password } end Admin.blueprint do email { Sham.email } - password { "Secret123" } + password { PASSWORD } password_confirmation { password } end @@ -128,179 +137,194 @@ def print_time name, &block salary_code { "#{rand(1000)}-#{'abc'.chars.to_a.rand}" } count { rand(200) } rate { rand(1200) } - amount { count * rate } + amount { rand(5000) } payroll_tax { rand(10) > 3 } vacation_basis { rand(10) > 3 } end +Ledger.blueprint do + name {Sham.name} + address + telephone_number {Sham.phone} + mobile_number {Sham.phone} + email {Sham.email} + comment {"Bulk insertion script"} + placement_top {false} + debit_text {"debit"} + credit_text {"credit"} +end + bob = nil admin = nil companies = [] users = nil roles=nil -# ********** Now create some data *************** -ActiveRecord::Base.transaction do - if not $BULK_APPEND - print_time "Creating users" do - - USER_COUNT.times {|i| user = User.make } - - bob = User.make(:email => "bob@bobsdomain.com") - - admin = Admin.make(:email => "admin@adminsdomain.com") - end - else - bob = User.where(:email => "bob@bobsdomain.com").first - admin = User.where(:email => "admin@adminsdomain.com").first - end - - print_time "Creating companies" do - COMPANY_COUNT.times {|i| companies << Company.make } - end +# ********** Now create some data *************** - users = User.all - roles = Role.all - - print_time "Attaching users to companies" do - # attach users to companies - (COMPANY_COUNT * 5).times do - c = companies.rand - u = users.rand - r = roles.rand - c.assignments.create(:user => u, :role => r) +if not $BULK_SALARY + ActiveRecord::Base.transaction do + + if not $BULK_APPEND + print_time "Creating users" do + + USER_COUNT.times {|i| user = User.make } + + bob = User.make(:email => "bob@bobsdomain.com") + + admin = Admin.make(:email => "admin@adminsdomain.com") + end + else + bob = User.where(:email => "bob@bobsdomain.com").first + admin = User.where(:email => "admin@adminsdomain.com").first + end + + print_time "Creating companies" do + COMPANY_COUNT.times {|i| companies << Company.make } end + + users = User.all + roles = Role.all - # make sure bob is assigned to a few companies - companies.shuffle[0..[COMPANY_COUNT, 5].min].each do |c| - c.assignments.create(:user => bob, :role => Role.find_by_name("accountant")) + print_time "Attaching users to companies" do + # attach users to companies + (COMPANY_COUNT * 5).times do + c = companies.rand + u = users.rand + r = roles.rand + c.assignments.create(:user => u, :role => r) + end + + # make sure bob is assigned to a few companies + companies.shuffle[0..[COMPANY_COUNT, 5].min].each do |c| + c.assignments.create(:user => bob, :role => Role.find_by_name("accountant")) + end end - end - print_time "Creating units" do - # create a bunch of units/projects and attach them to companies - (companies.size * UNIT_COUNT).times do - Unit.make(:company => companies.rand) + print_time "Creating units" do + # create a bunch of units/projects and attach them to companies + (companies.size * UNIT_COUNT).times do + Unit.make(:company => companies.rand) + end end - end - print_time "Creating projects" do - (companies.size * PROJECT_COUNT).times do - Project.make(:company => companies.rand) + print_time "Creating projects" do + (companies.size * PROJECT_COUNT).times do + Project.make(:company => companies.rand) + end end - end - - print_time "Creating company accounts" do - # create some accounts - companies.each do |c| - print '.' - # Vat accounts from empatix @ lodo.no - - # **** Outgoing vat; sales *** - a2700 = Account.make(:company => c, :name => "Utg mva kode 10", :number => 2700) - va2700 = VatAccount.create!(:company => c, :overridable => true, :target_account => a2700) - VatAccountPeriod.create!(:vat_account => va2700, :percentage => 0, :valid_from => "1990-01-01") - - - a2701 = Account.make(:company => c, :name => "Utg mva kode 11", :number => 2701) - va2701 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2701) - VatAccountPeriod.create!(:vat_account => va2701, :percentage => 24, :valid_from => "1990-01-01") - VatAccountPeriod.create!(:vat_account => va2701, :percentage => 25, :valid_from => "2005-01-01") - - - a2702 = Account.make(:company => c, :name => "Utg mva kode 12", :number => 2702) - va2702 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2702) - VatAccountPeriod.create!(:vat_account => va2702, :percentage => 12, :valid_from => "1990-01-01") - VatAccountPeriod.create!(:vat_account => va2702, :percentage => 11, :valid_from => "2005-01-01") - VatAccountPeriod.create!(:vat_account => va2702, :percentage => 13, :valid_from => "2006-01-01") - VatAccountPeriod.create!(:vat_account => va2702, :percentage => 14, :valid_from => "2007-01-01") - - - a2703 = Account.make(:company => c, :name => "Utg mva kode 13", :number => 2703) - va2703 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2703) - VatAccountPeriod.create!(:vat_account => va2703, :percentage => 6, :valid_from => "1990-01-01") - VatAccountPeriod.create!(:vat_account => va2703, :percentage => 7, :valid_from => "2005-01-01") - VatAccountPeriod.create!(:vat_account => va2703, :percentage => 8, :valid_from => "2006-01-01") - - # *** Incoming vat; expenses *** - a2710 = Account.make(:company => c, :name => "Ing mva kode 40", :number => 2710) - va2710 = VatAccount.create!(:company => c, :overridable => true, :target_account => a2710) - VatAccountPeriod.create!(:vat_account => va2710, :percentage => 0, :valid_from => "1990-01-01") - - - a2711 = Account.make(:company => c, :name => "Ing mva kode 41", :number => 2711) - va2711 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2711) - VatAccountPeriod.create!(:vat_account => va2711, :percentage => 24, :valid_from => "1990-01-01") - VatAccountPeriod.create!(:vat_account => va2711, :percentage => 25, :valid_from => "2005-01-01") - - - a2712 = Account.make(:company => c, :name => "Ing mva kode 42", :number => 2712) - va2712 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2712) - VatAccountPeriod.create!(:vat_account => va2712, :percentage => 12, :valid_from => "1990-01-01") - VatAccountPeriod.create!(:vat_account => va2712, :percentage => 11, :valid_from => "2005-01-01") - VatAccountPeriod.create!(:vat_account => va2712, :percentage => 13, :valid_from => "2006-01-01") - VatAccountPeriod.create!(:vat_account => va2712, :percentage => 14, :valid_from => "2007-01-01") - - - a2713 = Account.make(:company => c, :name => "Ing mva kode 43", :number => 2713) - va2713 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2713) - VatAccountPeriod.create!(:vat_account => va2713, :percentage => 6, :valid_from => "1990-01-01") - VatAccountPeriod.create!(:vat_account => va2713, :percentage => 7, :valid_from => "2005-01-01") - VatAccountPeriod.create!(:vat_account => va2713, :percentage => 8, :valid_from => "2006-01-01") - - - # Other accounts - Account.make(:company => c, :name => "Sales", :number => 3000, :vat_account => va2701) - Account.make(:company => c, :name => "Cash", :number => 1900) - Account.make(:company => c, :name => "Bank", :number => 1920) - Account.make(:company => c, :name => "Materials", :number => 4000, :vat_account => va2711) - Account.make(:company => c, :name => "Salaries", :number => 5000) - Account.make(:company => c, :name => "Arbeidsgiveravgift", :number => 5400) - Account.make(:company => c, :name => "NAV-refusjon, sykepenger", :number => 5800) - Account.make(:company => c, :name => "Office supplies", :number => 6800, :vat_account => va2711) - Account.make(:company => c, :name => "Phone expenses", :number => 6900, :vat_account => va2711) - - Account.make(:company => c, :name => "Accounts receivable", :number => 1500) - # TODO: create some customers - Account.make(:company => c, :name => "Accounts payable", :number => 2400) - # TODO: create some suppliers - - Account.make(:company => c, :name => "Employees", :number => 2930) - # TODO: create some employees - - # create some random filler accounts - (rand(200) + 40).times do - begin - Account.make(:company => c) - rescue + print_time "Creating company accounts" do + # create some accounts + companies.each do |c| + print '.' + # Vat accounts from empatix @ lodo.no + + # **** Outgoing vat; sales *** + a2700 = Account.make(:company => c, :name => "Utg mva kode 10", :number => 2700) + va2700 = VatAccount.create!(:company => c, :overridable => true, :target_account => a2700) + VatAccountPeriod.create!(:vat_account => va2700, :percentage => 0, :valid_from => "1990-01-01") + + + a2701 = Account.make(:company => c, :name => "Utg mva kode 11", :number => 2701) + va2701 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2701) + VatAccountPeriod.create!(:vat_account => va2701, :percentage => 24, :valid_from => "1990-01-01") + VatAccountPeriod.create!(:vat_account => va2701, :percentage => 25, :valid_from => "2005-01-01") + + + a2702 = Account.make(:company => c, :name => "Utg mva kode 12", :number => 2702) + va2702 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2702) + VatAccountPeriod.create!(:vat_account => va2702, :percentage => 12, :valid_from => "1990-01-01") + VatAccountPeriod.create!(:vat_account => va2702, :percentage => 11, :valid_from => "2005-01-01") + VatAccountPeriod.create!(:vat_account => va2702, :percentage => 13, :valid_from => "2006-01-01") + VatAccountPeriod.create!(:vat_account => va2702, :percentage => 14, :valid_from => "2007-01-01") + + + a2703 = Account.make(:company => c, :name => "Utg mva kode 13", :number => 2703) + va2703 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2703) + VatAccountPeriod.create!(:vat_account => va2703, :percentage => 6, :valid_from => "1990-01-01") + VatAccountPeriod.create!(:vat_account => va2703, :percentage => 7, :valid_from => "2005-01-01") + VatAccountPeriod.create!(:vat_account => va2703, :percentage => 8, :valid_from => "2006-01-01") + + # *** Incoming vat; expenses *** + a2710 = Account.make(:company => c, :name => "Ing mva kode 40", :number => 2710) + va2710 = VatAccount.create!(:company => c, :overridable => true, :target_account => a2710) + VatAccountPeriod.create!(:vat_account => va2710, :percentage => 0, :valid_from => "1990-01-01") + + + a2711 = Account.make(:company => c, :name => "Ing mva kode 41", :number => 2711) + va2711 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2711) + VatAccountPeriod.create!(:vat_account => va2711, :percentage => 24, :valid_from => "1990-01-01") + VatAccountPeriod.create!(:vat_account => va2711, :percentage => 25, :valid_from => "2005-01-01") + + + a2712 = Account.make(:company => c, :name => "Ing mva kode 42", :number => 2712) + va2712 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2712) + VatAccountPeriod.create!(:vat_account => va2712, :percentage => 12, :valid_from => "1990-01-01") + VatAccountPeriod.create!(:vat_account => va2712, :percentage => 11, :valid_from => "2005-01-01") + VatAccountPeriod.create!(:vat_account => va2712, :percentage => 13, :valid_from => "2006-01-01") + VatAccountPeriod.create!(:vat_account => va2712, :percentage => 14, :valid_from => "2007-01-01") + + + a2713 = Account.make(:company => c, :name => "Ing mva kode 43", :number => 2713) + va2713 = VatAccount.create!(:company => c, :overridable => false, :target_account => a2713) + VatAccountPeriod.create!(:vat_account => va2713, :percentage => 6, :valid_from => "1990-01-01") + VatAccountPeriod.create!(:vat_account => va2713, :percentage => 7, :valid_from => "2005-01-01") + VatAccountPeriod.create!(:vat_account => va2713, :percentage => 8, :valid_from => "2006-01-01") + + + # Other accounts + Account.make(:company => c, :name => "Sales", :number => 3000, :vat_account => va2701) + Account.make(:company => c, :name => "Cash", :number => 1900) + Account.make(:company => c, :name => "Bank", :number => 1920) + Account.make(:company => c, :name => "Materials", :number => 4000, :vat_account => va2711) + Account.make(:company => c, :name => "Salaries", :number => 5000) + Account.make(:company => c, :name => "Arbeidsgiveravgift", :number => 5400) + Account.make(:company => c, :name => "NAV-refusjon, sykepenger", :number => 5800) + Account.make(:company => c, :name => "Office supplies", :number => 6800, :vat_account => va2711) + Account.make(:company => c, :name => "Phone expenses", :number => 6900, :vat_account => va2711) + + Account.make(:company => c, :name => "Accounts receivable", :number => 1500) + # TODO: create some customers + + Account.make(:company => c, :name => "Accounts payable", :number => 2400) + # TODO: create some suppliers + + Account.make(:company => c, :name => "Employees", :number => 2930) + # TODO: create some employees + + # create some random filler accounts + (rand(200) + 40).times do + begin + Account.make(:company => c) + rescue + end end end end - end - print_time "Creating products" do - (companies.size * PRODUCT_COUNT).times do |i| - Product.make(:account => companies.rand.accounts.rand) + print_time "Creating products" do + (companies.size * PRODUCT_COUNT).times do |i| + Product.make(:account => companies.rand.accounts.rand) + end end - end - # create random journal entries for the given period - def create_journal_entries(company, period) - # puts "creating journal entries for #{company.name}, period: #{period.year}-#{period.nr}" - # create journal entries - date = Date.civil(period.year, period.nr, 1) - sql = "insert into journals (company_id, period_id, journal_date) select #{company.id}, #{period.id}, ('#{date}'::date + interval '28 days' * random())::date from generate_series (1, #{rand(MAX_JOURNAL_COUNT)})" - ActiveRecord::Base.connection.execute sql + # create random journal entries for the given period + def create_journal_entries(company, period) + # puts "creating journal entries for #{company.name}, period: #{period.year}-#{period.nr}" + # create journal entries + date = Date.civil(period.year, period.nr, 1) + sql = "insert into journals (company_id, period_id, journal_date) select #{company.id}, #{period.id}, ('#{date}'::date + interval '28 days' * random())::date from generate_series (1, #{rand(MAX_JOURNAL_COUNT)})" + ActiveRecord::Base.connection.execute sql + + end - end - - def create_journal_operations(company) - # create 4 journal_operations for every empty journal entry - # sql = "insert into journal_operations (journal_id, account_id, amount) select id as journal_id, #{sample_array_sql(company.accounts)}, (random() * 200 - 100)::numeric(16,2) as amount from (select j.id from journals j where j.company_id = #{company.id} and not exists (select 1 from journal_operations jo where jo.journal_id = j.id)) as aa, (select 1 from generate_series(1, (1 + random() * 5)::integer)) as bb" - sql = " + def create_journal_operations(company) + # create 4 journal_operations for every empty journal entry + # sql = "insert into journal_operations (journal_id, account_id, amount) select id as journal_id, #{sample_array_sql(company.accounts)}, (random() * 200 - 100)::numeric(16,2) as amount from (select j.id from journals j where j.company_id = #{company.id} and not exists (select 1 from journal_operations jo where jo.journal_id = j.id)) as aa, (select 1 from generate_series(1, (1 + random() * 5)::integer)) as bb" + sql = " insert into journal_operations (journal_id, account_id, amount) select @@ -311,11 +335,11 @@ def create_journal_operations(company) where j.company_id = #{company.id} and not exists ( select 1 from journal_operations jo - where jo.journal_id = j.id)) as aa, (select 1 from generate_series(1, 4)) as bb" - ActiveRecord::Base.connection.execute sql - - # find and close open journal entries - sql = " + where jo.journal_id = j.id)) as aa, (select 1 from generate_series(1, #{JOURNAL_OPERATION_COUNT-1})) as bb" + ActiveRecord::Base.connection.execute sql + + # find and close open journal entries + sql = " insert into journal_operations (journal_id, account_id, amount) select @@ -327,35 +351,90 @@ def create_journal_operations(company) inner join journal_operations jo on (j.id = jo.journal_id) where company_id = #{company.id} group by journal_id having sum(amount) <> 0) as qq" - ActiveRecord::Base.connection.execute sql - end + ActiveRecord::Base.connection.execute sql + end - def create_period(company, year, nr) - p = Period.make(:company => company, :year => year, :nr => nr) - create_journal_entries(company, p) - # TODO: close period as appropriate - #puts "p.journal count: #{p.journals.count} -- operations: #{p.journal_operations.count}" - end + def create_period(company, year, nr) + p = Period.make(:company => company, :year => year, :nr => nr) + create_journal_entries(company, p) + # TODO: close period as appropriate + #puts "p.journal count: #{p.journals.count} -- operations: #{p.journal_operations.count}" + end -end + end -# create periods and fill these with tx data -companies.each_with_index do |c,idx| - if idx%40 == 0 - print_time "Vacuuming the house" do - ActiveRecord::Base.connection.execute "vacuum analyze" + # create periods and fill these with tx data + companies.each_with_index do |c,idx| + if idx%40 == 0 + print_time "Vacuuming the house" do + ActiveRecord::Base.connection.execute "vacuum analyze" + end end - end - print_time "Creating periods for company #{idx+1} of #{COMPANY_COUNT}" do - ActiveRecord::Base.transaction do - YEARS.each do |year| - (1..12).each do |month| - create_period(c, year, month) + print_time "Creating periods for company #{idx+1} of #{COMPANY_COUNT}" do + ActiveRecord::Base.transaction do + YEARS.each do |year| + (1..12).each do |month| + create_period(c, year, month) + end end + create_journal_operations(c) + end + end # ActiveRecord::Base.transaction do + end +else + ActiveRecord::Base.connection.execute "truncate paycheck_lines" + ActiveRecord::Base.connection.execute "truncate paychecks" + ActiveRecord::Base.connection.execute "truncate paycheck_line_templates" + ActiveRecord::Base.connection.execute "truncate ledgers" + + companies = Company.all + print_time "Creating employees and salary information" do + companies.each do |c| + print '.' + emp_account = Account.where(:company_id => c.id, :number => 2930).first + + emp_pay_temp = [] + (0..5).each do |i| + emp_pay_temp << PaycheckLineTemplate.make(:company => c, :employee => nil, :account => c.accounts.rand) end - create_journal_operations(c) + + EMPLOYEE_COUNT.times do |i| + emp = Ledger.make :account_id => emp_account.id, :number => i+1, :account_type_id => 0 + + emp_pay_temp.each do |t| + PaycheckLineTemplate.make( + :company => c, + :employee => emp, + :account => t.account, + :line_type => t.line_type, + :description => t.description, + :salary_code => t.salary_code, + :count => t.count, + :rate => t.rate, + :amount => t.amount, + :payroll_tax => t.payroll_tax, + :vacation_basis => t.vacation_basis, + ) + end + sql = " +insert into paychecks +(period_id, employee_id, created_at, updated_at) +select id, #{emp.id}, now(), now() from periods where company_id = #{c.id}; +" + ActiveRecord::Base.connection.execute sql + + sql = " +insert into paycheck_lines +(line_type, description, paycheck_id, account_id, count, rate, amount, payroll_tax, vacation_basis, salary_code, created_at, updated_at) +select plt.line_type, plt.description, p.id, plt.account_id, plt.count, plt.rate, plt.amount, plt.payroll_tax, plt.vacation_basis, plt.salary_code, now(), now() +from paychecks p, paycheck_line_templates plt +where p.employee_id = #{emp.id} + and plt.employee_id = #{emp.id} +" + ActiveRecord::Base.connection.execute sql + + end end - end # ActiveRecord::Base.transaction do + end end -
<%= link_to t('global.show'), paycheck %> <%= link_to t('global.edit'), edit_paycheck_path(paycheck) %> - <%= link_to t('global.destroy'), paycheck, :confirm => t('global.confirm'), :method => :delete %>