Changeset 44

Show
Ignore:
Timestamp:
08/07/06 11:18:56 (2 years ago)
Author:
markku
Message:
  • #12 implemented. Also made some minor improvements on asset permission code.
  • Few translations for #12.
  • AssetTest? and AssetControllerTest? rewriten. They don't use fixture files and many of the tests are simpler and better than the old ones. Some new tests were added.
  • Added temporary models db/temp_models.rb, which are be used to create records to the database without the actual models. Usefull in test and migrations.
  • Fixed broken link and checkbox disabling in view asset/user_permissions.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/controllers/asset_controller.rb

    r38 r44  
    3535 
    3636  def add_sub_asset 
    37     unless @selected_asset.authorized_to_edit? 
     37    unless @selected_asset.authorized_to_create_subasset? 
    3838      redirect_with_message(msg_unauthorized_operation(_('create subassets'), @selected_asset.code_and_name), :action => 'view') 
    3939      return 
     
    9191      @selected_asset.attributes = params[:selected_asset] 
    9292 
    93       if not @selected_asset.save 
     93      unless @selected_asset.save 
    9494        flash[:error] = msg_saving_failed 
    9595        render :action => 'view' 
     
    114114  end 
    115115 
    116   # FIXME: Should these be moved to DataPermissionController
     116  # TODO: It might be best to create AssetPermissionController for these actions
    117117 
    118118  # Managing permissions. 
     
    126126  # link to parent's permissions page are shown 
    127127  def user_permissions 
     128    @authorized_to_edit = @selected_asset.authorized_to_edit_permissions? 
     129 
    128130    if @selected_asset.use_parents_permissions 
    129131      @title = _("Asset %s uses same permissions as its parent asset %s", @selected_asset.code_and_name, @selected_asset.parent.code_and_name) 
     
    139141    @available_groups = UserGroup.find(:all, :readonly => true) - @items 
    140142 
    141     @authorized_to_edit = @selected_asset.authorized_to_edit? 
    142143    # Render edit permissions action link if user is authorized 
    143     if @authorized_to_edit and session[:user].authorized?('asset/edit_permissions') 
     144    if @authorized_to_edit and session[:user].authorized?('asset/edit_user_permissions') 
    144145      @actions = [ [_('Edit permissions'), {:action => 'edit_user_permissions', :asset_id => @selected_asset.id, :image => '16x16/edit'}] ] 
    145146    else 
     
    159160    # Check that user is authorized to edit the asset and that it isn't using parent's permissions. 
    160161    asset = Asset.find(params[:asset_id], :readonly => true) 
    161     return unless authorized_to_edit_asset(asset) and not(asset.use_parents_permissions) 
     162    return unless authorized_to_edit_assets_permissions(asset) and not(asset.use_parents_permissions) 
    162163 
    163164    user_group = UserGroup.find(params[:id], :readonly => true) 
     
    181182    # Check that user is authorized to edit the asset and that it isn't using parent's permissions. 
    182183    asset = Asset.find(params[:asset_id], :readonly => true) 
    183     return unless authorized_to_edit_asset(asset) and not(asset.use_parents_permissions) 
     184    return unless authorized_to_edit_assets_permissions(asset) and not(asset.use_parents_permissions) 
    184185 
    185186    redirect_to(:action => 'user_permissions') 
     
    196197  # Sets asset @selected_asset's use_parents_permissions attribute. 
    197198  def set_use_parents_permissions 
     199    invalid_request and return unless request.post? and params[:selected_asset] and ['0', '1'].include?(params[:selected_asset][:use_parents_permissions]) 
     200 
     201    if @selected_asset.update_attribute(:use_parents_permissions, params[:selected_asset][:use_parents_permissions]) 
     202      flash[:notice] = msg_changes_saved  
     203    else 
     204      flash[:error] = msg_saving_failed 
     205    end 
    198206    redirect_to :back 
    199  
    200     if request.post? and params[:selected_asset] and 
    201         ['0', '1'].include?(params[:selected_asset][:use_parents_permissions]) and 
    202         @selected_asset.update_attribute(:use_parents_permissions, params[:selected_asset][:use_parents_permissions]) 
    203  
    204       flash[:notice] = msg_changes_saved  
    205     else 
    206       flash[:error] = msg_saving_failed 
    207     end 
    208207  end 
    209208 
     
    212211    if request.post? and params[:id] and params[:depth] 
    213212      asset = Asset.find(params[:id], :readonly => true) 
    214       return unless authorized_to_edit_asset(asset) and not(asset.use_parents_permissions) 
     213      return unless authorized_to_edit_assets_permissions(asset) and not(asset.use_parents_permissions) 
    215214      copies = asset.copy_permissions_to_subassets(params[:depth].to_i) 
    216215      if copies > 0 
     
    228227    # Find objects and check that authorized to edit asset 
    229228    @asset = Asset.find(params[:asset_id], :readonly => true) 
    230     return unless authorized_to_edit_asset(@asset) and not(@asset.use_parents_permissions) 
     229    return unless authorized_to_edit_assets_permissions(@asset) and not(@asset.use_parents_permissions) 
    231230 
    232231    @user_group = UserGroup.find params[:id] 
     
    256255    assets_user_group = AssetsUserGroup.find(params[:id]) 
    257256    asset = assets_user_group.asset 
    258     return unless authorized_to_edit_asset(asset) and not(asset.use_parents_permissions) 
     257    return unless authorized_to_edit_assets_permissions(asset) and not(asset.use_parents_permissions) 
    259258 
    260259    # Update user group's permissions to the asset. 
     
    279278    assets_user_group = AssetsUserGroup.find(params[:id]) 
    280279    asset = assets_user_group.asset 
    281     return unless authorized_to_edit_asset(asset) and not(asset.use_parents_permissions) 
     280    return unless authorized_to_edit_assets_permissions(asset) and not(asset.use_parents_permissions) 
    282281 
    283282    assets_user_group.update_permission_profiles(params[:profile], params[:report], params[:work_order], params[:attachment]) 
     
    297296    assets_user_group = AssetsUserGroup.find(params[:id]) 
    298297    asset = assets_user_group.asset 
    299     return unless authorized_to_edit_asset(asset) and not(asset.use_parents_permissions) 
     298    return unless authorized_to_edit_assets_permissions(asset) and not(asset.use_parents_permissions) 
    300299 
    301300    redirect_to(:action => 'edit_user_permissions', 
     
    318317private 
    319318 
    320   # Returns true if user is authorized to edit asset +asset+ and 
    321   # otherwise redirects with error message and returns false 
    322   def authorized_to_edit_asset(asset) 
    323     unless asset.authorized_to_edit
     319  # Returns true if user is authorized to edit asset +asset+'s permissions and 
     320  # otherwise redirects with error message and returns false. 
     321  def authorized_to_edit_assets_permissions(asset) 
     322    unless asset.authorized_to_edit_permissions
    324323      error("Unauthorized to edit asset #{asset.full_code}'s permissions") 
    325324      redirect_with_error_message(msg_unauthorized_operation(_('edit permissions'), asset.code_and_name), 
  • trunk/app/models/asset.rb

    r24 r44  
    174174  end 
    175175 
     176  # Returns true if the user is authorized to create sub-assets to this asset 
     177  def authorized_to_create_subasset? 
     178    authorized_to(:create_subasset) 
     179  end 
     180 
     181  # Returns true if the user is authorized to edit asset permissions for this asset 
     182  def authorized_to_edit_permissions? 
     183    authorized_to(:edit_permissions) 
     184  end 
     185 
     186  # Returns true if the user is authorized to remove this asset 
     187  def authorized_to_remove? 
     188    authorized_to(:remove) 
     189  end 
     190 
    176191  # Returns true if the user is authorized to create new instances of +datatype+ to this asset 
    177192  def authorized_to_create?(datatype) 
     
    202217  # The same association is created also for all sub-assets using this asset's permissions. 
    203218  # Returns true if the creation is successfull and returns false if it fails. 
    204   def add_user_group(user_group, edit = false
     219  def add_user_group(user_group, permissions = {}
    205220    raise("#{user_group.class} in not a UserGroup") unless user_group.is_a?(UserGroup) 
    206     raise("Unauthorized to add user group to asset #{self.full_code}") unless not(use_parents_permissions) and authorized_to_edit? 
     221    raise("Unauthorized to add user group to asset #{self.full_code}") unless not(self.use_parents_permissions) and authorized_to_edit_permissions? 
     222 
     223    user_group_to_add = AssetsUserGroup.new(permissions) 
     224    user_group_to_add.asset = self 
     225    user_group_to_add.user_group = user_group 
    207226 
    208227    AssetsUserGroup.transaction do 
    209228 
    210       if self.assets_user_groups.build(:user_group_id => user_group.id, :edit => edit).save 
     229      if user_group_to_add.save 
    211230        _info("User group \"#{user_group.name}\" added to asset #{self.full_code} and to all sub-assets using it's permissions.") 
    212231        return true 
     
    223242  def remove_user_groups(user_group_ids) 
    224243    raise('Unable to remove user groups without ids') if user_group_ids.empty? 
    225     raise("Unauthorized to remove user groups from asset #{self.full_code}") unless not(use_parents_permissions) and authorized_to_edit
     244    raise("Unauthorized to remove user groups from asset #{self.full_code}") unless not(self.use_parents_permissions) and authorized_to_edit_permissions
    226245 
    227246    associations_to_destroy = self.assets_user_groups.find(:all, :conditions => ['user_group_id IN (?)', user_group_ids]) 
     
    335354 
    336355    self.children.each { |subasset| 
    337       next unless subasset.use_parents_permissions and subasset.authorized_to_edit
     356      next unless subasset.use_parents_permissions and subasset.authorized_to_edit_permissions
    338357 
    339358      case operation 
     
    353372                                             :create_report => assets_user_group.create_report, 
    354373                                             :create_work_order => assets_user_group.create_work_order, 
    355                                              :attach_file => assets_user_group.attach_file) 
     374                                             :attach_file => assets_user_group.attach_file, 
     375                                             :create_subasset => assets_user_group.create_subasset, 
     376                                             :edit_permissions => assets_user_group.edit_permissions, 
     377                                             :remove => assets_user_group.remove) 
    356378          _info("AssetsUserGroup(id=#{subassets_group.id}) updated") 
    357379        else 
     
    361383        subassets_group = AssetsUserGroup.find_by_asset_id_and_user_group_id(subasset.id, user_group_id) 
    362384 
    363         if not(subassets_group.nil?) and subassets_group.destroy 
     385        if subassets_group != nil and subassets_group.destroy 
    364386          _info("User group (id=#{user_group_id}) removed from asset #{subasset.full_code}") 
    365387        else 
     
    373395  end 
    374396 
    375   # Updates user group's data permission profiles in sub-asset's using this asset's permissions 
     397  # Updates user groups data permission profiles in sub-assets using this asset's permissions 
    376398  # by performing +operation+ to sub-asset's user group's data permission profile. 
    377399  # Called by after_[create|update|destroy] callbacks in DataPermissionProfile model. 
     
    416438        profile = permission_profile.class.find_by_assets_user_group_id_and_user_group_id(subassets_group.id, permission_profile.user_group_id) 
    417439 
    418         if not(profile.nil?) and profile.destroy 
     440        if profile != nil and profile.destroy 
    419441          _info("#{profile.class}(id=#{profile.id}) removed") 
    420442        else 
     
    431453 
    432454  # Version of find which only returns assets the user is authorized to perform +operation+. 
     455  # +operation+::  Symbol defining which permission is checked. One of :edit, :create_subasset, 
     456  #                :remove, :edit_permissions, :create_report, :create_work_order, :attach_file. 
    433457  def Asset.find_authorized_to(operation, args) 
    434458    return records_not_found(args) unless user = User.current_user 
     
    440464                when :read 
    441465                  sanitize_sql(['user_group_id IN (?)', group_ids]) 
    442                 when :edit 
    443                   sanitize_sql(['user_group_id IN (?) AND edit = ?', group_ids, true]) 
     466                when :edit, :create_subasset, :edit_permissions, :remove, :create_report, :create_work_order, :attach_file 
     467                  sanitize_sql(["user_group_id IN (?) AND #{operation} = ?", group_ids, true]) 
    444468                else 
    445469                  raise("Unknown operation: #{operation}") 
     
    448472    return records_not_found(args) if asset_ids.empty? 
    449473 
    450     final_args = add_conditions_to_find_arguments(args, "#{self.table_name}.id IN (?)", [asset_ids]) 
    451  
    452     return self.find(*final_args) 
     474    args = add_conditions_to_find_arguments(args, "#{self.table_name}.id IN (?)", [asset_ids]) 
     475 
     476    return self.find(*args) 
    453477  end 
    454478 
    455479  # Returns true if the user is authorized to perform operation +operation+ to this asset. 
    456   # +operation+:: Symbol defining which permission is checked. 
    457   #               One of :edit, :create_report, :create_work_order, :attach_file. 
     480  # +operation+:: Symbol defining which permission is checked. One of :edit, :create_report, 
     481  #                :create_work_order, :attach_file, :create_subasset, :edit_permissions, :remove. 
    458482  def authorized_to(operation) 
    459483    if user = User.current_user 
     
    474498  end 
    475499 
    476   # Prevents creation of parentless assets if root asset exists. Verifies that user is authorized to create new asset, which requires editing permission to asset's parent. 
     500  # Prevents creation of parentless assets if root asset exists. Verifies that user is authorized to create new asset, which requires create_subasset permission to asset's parent. 
    477501  def check_authorized_to_edit_parent 
    478502    if Asset.count == 0 
     
    484508    raise(ActiveRecord::ActiveRecordError, "Asset #{self.full_code} doesn't have parent!") if parent_asset.nil? 
    485509 
    486     if parent_asset.authorized_to_edit? 
     510    if parent_asset.authorized_to_create_subasset? 
    487511      _info("Authorized to create sub-asset to asset #{parent_asset.full_code}") 
    488512      return true 
     
    500524    end 
    501525 
    502     if self.authorized_to_edit? 
    503       _info("Authorized to save #{self.class}(id=#{self.id})") 
    504       return true 
     526    if only_use_parents_permissions_changed? 
     527      if use_parents_permissions_unchanged? 
     528        # Nothing was changed 
     529        self.errors.add_to_base(_('No changes have been made')) 
     530        return false 
     531      end 
     532      # Only use_parents_permissions changed 
     533      if authorized_to_edit_permissions? 
     534        _info("Authorized to save #{self.class}(id=#{self.id})") 
     535        return true 
     536      end 
    505537    else 
    506       _error("Unauthorized to save #{self.class}(id=#{self.id})") 
    507       self.errors.add_to_base(_('Unauthorized to save %s', _(self.class.to_s))) 
    508       return false 
    509     end 
     538      if use_parents_permissions_unchanged? and authorized_to_edit? 
     539        _info("Authorized to save #{self.class}(id=#{self.id})") 
     540        return true 
     541      end 
     542    end 
     543 
     544    _error("Unauthorized to save #{self.class}(id=#{self.id})") 
     545    self.errors.add_to_base(_('Unauthorized to save %s', _(self.class.to_s))) 
     546    return false 
    510547  end 
    511548 
     
    536573  # permissions are identical with those in +assets_groups+. 
    537574  def copy_permissions(assets_groups) 
    538     return false unless self.new_record? or self.authorized_to_edit
     575    return false unless self.new_record? or self.authorized_to_edit_permissions
    539576 
    540577    if self.new_record? 
    541578      self.assets_user_groups = AssetsUserGroup.new_ones_from_instances(assets_groups) 
    542579 
    543       Range.new(0, assets_groups.size-1).each { |j| 
     580      0.upto(assets_groups.size - 1) { |j| 
    544581        self.assets_user_groups[j].copy_data_permission_profiles_from(assets_groups[j]) 
    545582      } 
     
    552589          :create_report => aug.create_report, 
    553590          :create_work_order => aug.create_work_order, 
    554           :attach_file => aug.attach_file 
     591          :attach_file => aug.attach_file, 
     592          :create_subasset => aug.create_subasset, 
     593          :edit_permissions => aug.edit_permissions, 
     594          :remove => aug.remove 
    555595        } 
    556596        if new_aug.nil? 
     
    573613  end 
    574614 
     615  # Returns true if all attributes, except use_parents_permissions, are unchanged. 
     616  def only_use_parents_permissions_changed? 
     617    original_attributes = Asset.find(self.id).attributes 
     618    original_attributes.delete('use_parents_permissions') 
     619    attributes = self.attributes 
     620    attributes.delete('use_parents_permissions') 
     621 
     622    attributes == original_attributes 
     623  end 
     624 
     625  # Returns true if use_parents_permissions is unchanged. 
     626  def use_parents_permissions_unchanged? 
     627    self.use_parents_permissions == @original_use_parents_permissions 
     628  end 
     629 
    575630end 
  • trunk/app/models/asset_join_model.rb

    r24 r44  
    2323  def new_from_instance 
    2424    new_obj = self.clone 
    25     new_obj.send(self.class::PROTECTOR_MODEL.to_s + '_id=', nil) 
     25    new_obj.send(self.class::PROTECTOR_MODEL[0].to_s + '_id=', nil) 
    2626    new_obj 
    2727  end 
  • trunk/app/models/assets_user_group.rb

    r24 r44  
    2525  before_update :check_authorized_to_edit 
    2626  # Associations 
    27   belongs_to_protector :asset 
     27  belongs_to_protector :asset, :edit_permission => :authorized_to_edit_permissions? 
    2828  has_many :data_permission_profiles, :dependent => :delete_all 
    2929  has_many :report_permission_profiles, :order => 'other', :dependent => :delete_all 
  • trunk/app/models/data_permission_profile.rb

    r24 r44  
    3939      add = true 
    4040      profiles.each { |profile| 
     41        next unless profile.class == profile_to_add.class 
     42 
    4143        if profile.user_group_id == profile_to_add.user_group_id 
    4244          add = false 
  • trunk/app/models/protected_asset_data.rb

    r24 r44  
    161161    end 
    162162 
    163     final_args = add_conditions_to_find_arguments(args, extra_conditions, arguments) 
    164  
    165     return self.find(*final_args) 
     163    args = add_conditions_to_find_arguments(args, extra_conditions, arguments) 
     164 
     165    return self.find(*args) 
    166166  end 
    167167 
     
    175175    return records_not_found(args) if asset_ids.empty? 
    176176 
    177     final_args = add_conditions_to_find_arguments(args, 'asset_id IN (?) AND ready = ?', [asset_ids, ready]) 
    178  
    179     return self.find(*final_args) 
     177    args = add_conditions_to_find_arguments(args, 'asset_id IN (?) AND ready = ?', [asset_ids, ready]) 
     178 
     179    return self.find(*args) 
    180180  end 
    181181 
  • trunk/app/models/protected_join_model.rb

    r24 r44  
    1717  belongs_to :user_group 
    1818 
     19  # Like ARs belongs_to association. In addition sets protector model for the model. 
     20  # Default value for option :edit_permission is :authorized_to_edit? 
     21  # 
     22  def ProtectedJoinModel.belongs_to_protector(association_id, options = {}) 
     23    edit_permission = options.delete(:edit_permission) || :authorized_to_edit? 
    1924 
    20   # Like belongs_to association. In addition sets protector model for the model. 
    21   def ProtectedJoinModel.belongs_to_protector(association_id, options = {}) 
    2225    belongs_to(association_id, options) 
    2326 
    24     self.const_set(:PROTECTOR_MODEL, association_id
     27    self.const_set(:PROTECTOR_MODEL, [association_id, edit_permission]
    2528  end 
    2629 
     
    4447  # Returns an instance of the protector model for this object. 
    4548  def protector 
    46     return self.send(self.class::PROTECTOR_MODEL
     49    return self.send(self.class::PROTECTOR_MODEL[0]
    4750  end 
    4851 
     
    5053  def authorized_to_edit? 
    5154    begin 
    52       return self.protector.authorized_to_edit? 
     55      return self.protector.send(self.class::PROTECTOR_MODEL[1]) 
    5356    rescue NoMethodError 
    54       raise(NoMethodError, "#{self.class}(id=#{self.id}) doesn't belong to a protecting #{self.class::PROTECTOR_MODEL}.") 
     57      raise(NoMethodError, "#{self.class}(id=#{self.id}) doesn't belong to a protecting #{self.class::PROTECTOR_MODEL[0]}.") 
    5558    end 
    5659  end 
  • trunk/app/views/asset/edit_user_permissions.rhtml

    r12 r44  
    2222      <th><%= _('Attach files') %></th> 
    2323      <td><%= check_box(:assets_user_group, :attach_file) %></td> 
     24    </tr> 
     25    <tr> 
     26      <th><%= _('Create sub-assets') %></th> 
     27      <td><%= check_box(:assets_user_group, :create_subasset) %></td> 
     28    </tr> 
     29    <tr> 
     30      <th><%= _('Edit asset permissions') %></th> 
     31      <td><%= check_box(:assets_user_group, :edit_permissions) %></td> 
     32    </tr> 
     33    <tr> 
     34      <th><%= _('Remove asset') %></th> 
     35      <td><%= check_box(:assets_user_group, :remove) %></td> 
    2436    </tr> 
    2537    <tr> 
  • trunk/app/views/asset/user_permissions.rhtml

    r27 r44  
    2929 
    3030<% else -%> 
    31   <%= link_to(_("Parent asset's permissions"), :action => 'select', :id => @selected_asset.parent_id) %><br/> 
     31  <%= link_to(_("Parent asset's permissions"), :controller => 'asset_tree', :action => 'select', :id => @selected_asset.parent_id) %><br/> 
    3232<% end -%> 
    3333 
    3434<% if @selected_asset.parent -%> 
    3535  <br/> 
    36   <% disabled = (not @selected_asset.authorized_to_edit?) -%> 
     36  <% disabled = (@authorized_to_edit != true) -%> 
    3737  <%= form_tag(:action => 'set_use_parents_permissions') %> 
    3838    <table class="form"> 
  • trunk/db/migrate/001_initial.rb

    r35 r44  
    22  def self.up 
    33    use_limit_for_binary_columns = ['MySQL'].include?(ActiveRecord::Base.connection.adapter_name) 
     4 
    45    #transaction do  
    56      # USERS 
     
    275276        t.column "user_group_id", :integer 
    276277        t.column "edit", :boolean, :default => false 
    277         t.column "add_subasset", :boolean, :default => false 
    278         t.column "remove", :boolean, :default => false 
    279         t.column "edit_permissions", :boolean, :default => false 
    280278        t.column "create_report", :boolean, :default => false 
    281279        t.column "create_work_order", :boolean, :default => false 
    282280        t.column "attach_file", :boolean, :default => false 
     281        t.column "create_subasset", :boolean, :default => false 
     282        t.column "edit_permissions", :boolean, :default => false 
     283        t.column "remove", :boolean, :default => false 
    283284      end 
    284285      add_index "assets_user_groups", ["asset_id"] 
  • trunk/db/migrate/002_initial_data.rb

    r16 r44  
    2626      execute "INSERT INTO assets (code, name) VALUES ('CMMS', 'NorfelloCMMS');" 
    2727      # User permissions to assets 
    28       [["(1, 1, ?, ?, ?, ?)", true, true, true, true], 
    29        ["(1, 2, ?, ?, ?, ?)", false, false, false, false] 
    30       ].each { |values| 
    31         execute "INSERT INTO assets_user_groups (asset_id, user_group_id, edit, create_report, create_work_order, attach_file) VALUES #{ActiveRecord::Base.sanitize_sql(values)};" 
    32       } 
    33       # Default permissions to data created to root asset 
     28      [["(1, 1, ?, ?, ?, ?, ?, ?, ?)", true, true, true, true, true, true, true], 
     29       ["(1, 2, ?, ?, ?, ?, ?, ?, ?)", false, false, false, false, false, false, false] 
     30      ].each { |values| 
     31        execute "INSERT INTO assets_user_groups (asset_id, user_group_id, edit, create_report, create_work_order, attach_file, create_subasset, edit_permissions, remove) VALUES #{ActiveRecord::Base.sanitize_sql(values)};" 
     32      } 
     33      # default permissions to data created to root asset 
    3434      [["(1, 1, ?, 'ReportPermissionProfile', ?, ?, ?)", false, true, true, true], 
    3535       ["(1, 1, ?, 'WorkOrderPermissionProfile', ?, ?, ?)", false, true, true, true], 
  • trunk/po/fi_FI/norfello_cmms.po

    r43 r44  
    22msgstr "" 
    33"Project-Id-Version: NorfelloCMMS SVN trunk\n" 
    4 "POT-Creation-Date: 2006-08-07 10:50+0300\n" 
    5 "PO-Revision-Date: 2006-08-04 14:38+0200\n" 
    6 "Last-Translator: Jarmo Hekkanen <jarmo.hekkanen@norfello.com>\n" 
     4"POT-Creation-Date: 2006-08-07 11:11+0300\n" 
     5"PO-Revision-Date: 2006-08-07 11:13+0200\n" 
     6"Last-Translator: Markku Oksanen <markku.oksanen@norfello.com>\n" 
    77"Language-Team: Norfello Ltd. <contact@norfello.com>\n" 
    88"MIME-Version: 1.0\n" 
     
    1414"X-Poedit-Bookmarks: 311,243,-1,-1,-1,-1,-1,-1,-1,-1\n" 
    1515 
    16 #: app/controllers/asset_controller.rb:15 
    17 msgid "Asset information" 
    18 msgstr "Kohteen tiedot " 
    19  
    20 #: app/controllers/asset_controller.rb:22 
    21 msgid "Displaying the asset" 
    22 msgstr "Kohteen nÀyttÀminen" 
    23  
     16#: app/helpers/application_helper.rb:42 
     17msgid "January" 
     18msgstr "tammikuu" 
     19 
     20#: app/helpers/application_helper.rb:43 
     21msgid "February" 
     22msgstr "helmikuu" 
     23 
     24#: app/helpers/application_helper.rb:44 
     25msgid "March" 
     26msgstr "maaliskuu" 
     27 
     28#: app/helpers/application_helper.rb:45 
     29msgid "April" 
     30msgstr "huhtikuu" 
     31 
     32#: app/helpers/application_helper.rb:46 
     33msgid "May" 
     34msgstr "toukokuu" 
     35 
     36#: app/helpers/application_helper.rb:47 
     37msgid "June" 
     38msgstr "kesÀkuu" 
     39 
     40#: app/helpers/application_helper.rb:48 
     41msgid "July" 
     42msgstr "heinÀkuu" 
     43 
     44#: app/helpers/application_helper.rb:49 
     45msgid "August" 
     46msgstr "elokuu" 
     47 
     48#: app/helpers/application_helper.rb:50 
     49msgid "September" 
     50msgstr "syyskuu" 
     51 
     52#: app/helpers/application_helper.rb:51 
     53msgid "October" 
     54msgstr "lokakuu" 
     55 
     56#: app/helpers/application_helper.rb:52 
     57msgid "November" 
     58msgstr "marraskuu" 
     59 
     60#: app/helpers/application_helper.rb:53 
     61msgid "December" 
     62msgstr "joulukuu" 
     63 
     64#: app/helpers/application_helper.rb:56 
     65msgid "All" 
     66msgstr "Kaikki" 
     67 
     68#: app/helpers/application_helper.rb:96 
     69msgid "Popup calendar" 
     70msgstr "Popup-kalenteri" 
     71 
     72#: app/helpers/application_helper.rb:276 
     73#: app/controllers/report_controller.rb:361 
     74msgid "Report" 
     75msgstr "Raportti" 
     76 
     77#: app/helpers/application_helper.rb:289 
     78#: app/controllers/work_order_controller.rb:23 
     79msgid "Work order" 
     80msgstr "TyömÀÀrÀin" 
     81 
     82#: app/helpers/application_helper.rb:302 
     83#: app/controllers/attachment_controller.rb:13 
     84#: app/controllers/attachment_controller.rb:44 
     85msgid "Attachment" 
     86msgstr "Liitetiedosto" 
     87 
     88#: app/models/report_type.rb:- 
     89msgid "report type" 
     90msgstr "raporttityyppi" 
     91 
     92#: app/models/report_type.rb:- 
     93msgid "ReportType|Report category" 
     94msgstr "Raporttikategoria" 
     95 
     96#: app/models/report_type.rb:- 
     97msgid "ReportType|Name" 
     98msgstr "Nimi" 
     99 
     100#: app/models/report_type.rb:- 
     101msgid "ReportType|Editable" 
     102msgstr "Muokattavissa" 
     103 
     104#: app/models/report_type.rb:- 
     105msgid "ReportType|Ready" 
     106msgstr "Valmis" 
     107 
     108#: app/models/protected_asset_data.rb:375 
     109#: app/models/asset.rb:545 
     110msgid "Unauthorized to save %s" 
     111msgstr "Ei oikeutta %s tallentamiseen" 
     112 
     113#: app/models/permission.rb:- 
     114msgid "permission" 
     115msgstr "kÀyttöoikeus" 
     116 
     117#: app/models/permission.rb:- 
     118msgid "Permission|Name" 
     119msgstr "Nimi" 
     120 
     121#: app/models/permission.rb:- 
     122msgid "Permission|Info" 
     123msgstr "Tiedot" 
     124 
     125#: app/models/open_document_file.rb:- 
     126msgid "open document file" 
     127msgstr "Avaa asiakirja" 
     128 
     129#: app/models/open_document_file.rb:- 
     130msgid "OpenDocumentFile|Type" 
     131msgstr "Tyyppi" 
     132 
     133#: app/models/open_document_file.rb:- 
     134msgid "OpenDocumentFile|Content type" 
     135msgstr "SisÀllön tyyppi" 
     136 
     137#: app/models/open_document_file.rb:- 
     138msgid "OpenDocumentFile|Data" 
     139msgstr "Data" 
     140 
     141#: app/models/open_document_file.rb:- 
     142msgid "OpenDocumentFile|Report type" 
     143msgstr "Raporttityyppi" 
     144 
     145#: app/models/open_document_file.rb:18 
     146msgid "cannot be empty" 
     147msgstr "ei voi olla tyhjÀ" 
     148 
     149#: app/models/open_document_file.rb:31 
     150msgid "You can only upload OpenDocument files" 
     151msgstr "Voit ladata vain OpenDocument-tiedostoja" 
     152 
     153#: app/models/timeline_event.rb:- 
     154msgid "timeline event" 
     155msgstr "aikajanan tapahtuma" 
     156 
     157#: app/models/timeline_event.rb:- 
     158msgid "TimelineEvent|Type" 
     159msgstr "Tyyppi" 
     160 
     161#: app/models/timeline_event.rb:- 
     162msgid "TimelineEvent|Event type" 
     163msgstr "Tapahtuman tyyppi" 
     164 
     165#: app/models/timeline_event.rb:- 
     166msgid "TimelineEvent|Comment text" 
     167msgstr "Kommenttiteksti" 
     168 
     169#: app/models/timeline_event.rb:- 
     170msgid "TimelineEvent|Created by" 
     171msgstr "Luoja" 
     172 
     173#: app/models/timeline_event.rb:- 
     174msgid "TimelineEvent|Created at" 
     175msgstr "Luotu" 
     176 
     177#: app/models/timeline_event.rb:- 
     178msgid "TimelineEvent|Work order" 
     179msgstr "TyömÀÀrÀin" 
     180 
     181#: app/models/timeline_event.rb:- 
     182msgid "TimelineEvent|Responsible user" 
     183msgstr "Vastuussa oleva kÀyttÀjÀ" 
     184 
     185#: app/models/timeline_event.rb:- 
     186msgid "TimelineEvent|Report" 
     187msgstr "Raportti" 
     188 
     189#: app/models/timeline_event.rb:- 
     190msgid "TimelineEvent|Attachment" 
     191msgstr "Liitetiedosto" 
     192 
     193#: app/models/work_order_template.rb:27 
     194msgid "User field %s is missing" 
     195msgstr "KÀyttÀjÀkenttÀ %s puuttuu" 
     196 
     197#: app/models/work_order_template.rb:29 
     198msgid "User fields %s are missing" 
     199msgstr "KÀyttÀjÀkentÀt %s puuttuvat" 
     200 
     201#: app/models/lockable.rb:- 
     202msgid "lockable" 
     203msgstr "lockable" 
     204 
     205#: app/models/work_order.rb:31 
     206msgid "is not a positive number" 
     207msgstr "ei ole kokonaisluku" 
     208 
     209#: app/models/work_order.rb:75 
     210msgid "cannot be earlier than the starting time" 
     211msgstr "ei saa olla aikaisempi kuin aloitusaika" 
     212 
     213#: app/models/report_field.rb:- 
     214msgid "report field" 
     215msgstr "raporttikenttÀ" 
     216 
     217#: app/models/report_field.rb:- 
     218msgid "ReportField|Report type" 
     219msgstr "Raporttityyppi" 
     220 
     221#: app/models/report_field.rb:- 
     222msgid "ReportField|Report field group" 
     223msgstr "RaporttikenttÀryhmÀ" 
     224 
     225#: app/models/report_field.rb:- 
     226msgid "ReportField|Place" 
     227msgstr "Sijoitus" 
     228 
     229#: app/models/report_field.rb:- 
     230msgid "ReportField|Name" 
     231msgstr "Nimi" 
     232 
     233#: app/models/report_field.rb:- 
     234msgid "ReportField|User field name" 
     235msgstr "KentÀn nimi" 
     236 
     237#: app/models/report_field.rb:- 
     238msgid "ReportField|Type code" 
     239msgstr "Tyyppikoodi" 
     240 
     241#: app/models/report_field.rb:- 
     242msgid "ReportField|List column" 
     243msgstr "ReportField|List column" 
     244 
     245#: app/models/report_field.rb:- 
     246msgid "ReportField|Validate presence" 
     247msgstr "ReportField|Validate presence" 
     248 
     249#: app/models/user.rb:- 
     250msgid "user" 
     251msgstr "kÀyttÀjÀ" 
     252 
     253#: app/models/user.rb:- 
     254msgid "User|Login" 
     255msgstr "KÀyttÀjÀtunnus" 
     256 
     257#: app/models/user.rb:- 
     258msgid "User|Password" 
     259msgstr "Salasana" 
     260 
     261#: app/models/user.rb:- 
     262msgid "User|First name" 
     263msgstr "Etunimi" 
     264 
     265#: app/models/user.rb:- 
     266msgid "User|Last name" 
     267msgstr "Sukunimi" 
     268 
     269#: app/models/user.rb:- 
     270msgid "User|Description" 
     271msgstr "Kuvaus" 
     272 
     273#: app/models/user.rb:- 
     274msgid "User|Email" 
     275msgstr "SÀhköposti" 
     276 
     277#: app/models/user.rb:- 
     278msgid "User|Phone" 
     279msgstr "Puhelin" 
     280 
     281#: app/models/user.rb:- 
     282msgid "User|Lang" 
     283msgstr "Kieli" 
     284 
     285#: app/models/user.rb:- 
     286msgid "User|Created at" 
     287msgstr "Luotu" 
     288 
     289#: app/models/user.rb:- 
     290msgid "User|Updated at" 
     291msgstr "PÀivitetty" 
     292 
     293#: app/models/user.rb:- 
     294msgid "User|Accessed at" 
     295msgstr "User|Accessed at" 
     296 
     297#: app/models/work_order_type.rb:- 
     298msgid "work order type" 
     299msgstr "työmÀÀrÀintyyppi" 
     300 
     301#: app/models/work_order_type.rb:- 
     302msgid "WorkOrderType|Name" 
     303msgstr "Nimi" 
     304 
     305#: app/models/work_order_type.rb:- 
     306msgid "WorkOrderType|Description" 
     307msgstr "Kuvaus" 
     308 
     309#: app/models/asset.rb:529 
     310msgid "No changes have been made" 
     311msgstr "" 
     312 
     313#: app/models/message.rb:- 
     314msgid "message" 
     315msgstr "viesti" 
     316 
     317#: app/models/message.rb:- 
     318msgid "Message|Receiver user" 
     319msgstr "Vastaanottaja" 
     320 
     321#: app/models/message.rb:- 
     322msgid "Message|Sender user" 
     323msgstr "LÀhettÀjÀ" 
     324 
     325#: app/models/message.rb:- 
     326msgid "Message|Unread" 
     327msgstr "Lukematon" 
     328 
     329#: app/models/message.rb:- 
     330msgid "Message|Subject" 
     331msgstr "Aihe" 
     332 
     333#: app/models/message.rb:- 
     334msgid "Message|Body" 
     335msgstr "SisÀltö" 
     336 
     337#: app/models/message.rb:- 
     338msgid "Message|Created at" 
     339msgstr "Luotu" 
     340 
     341#: app/models/attachment.rb:53 
     342msgid "Text file" 
     343msgstr "Tekstitiedosto" 
     344 
     345#: app/models/attachment.rb:55 
     346msgid "Image file" 
     347msgstr "Kuvatiedosto" 
     348 
     349#: app/models/attachment.rb:57 
     350msgid "PDF file" 
     351msgstr "PDF-tiedosto" 
     352 
     353#: app/models/attachment.rb:59 
     354msgid "gzip (GNU zip) file" 
     355msgstr "gzip (GNU zip) -tiedosto" 
     356 
     357#: app/models/attachment.rb:61 
     358msgid "Unknown" 
     359msgstr "Tuntematon" 
     360 
     361#: app/models/report_field_group.rb:- 
     362msgid "report field group" 
     363msgstr "RaporttikenttÀryhmÀ" 
     364 
     365#: app/models/report_field_group.rb:- 
     366msgid "ReportFieldGroup|Report type" 
     367msgstr "Raporttityyppi" 
     368 
     369#: app/models/report_field_group.rb:- 
     370msgid "ReportFieldGroup|Name" 
     371msgstr "Nimi" 
     372 
     373#: app/models/report_field_group.rb:- 
     374msgid "ReportFieldGroup|Place" 
     375msgstr "Sijoitus" 
     376 
     377#: app/models/user_group.rb:- 
     378msgid "user group" 
     379msgstr "kÀyttÀjÀryhmÀ" 
     380 
     381#: app/models/user_group.rb:- 
     382msgid "UserGroup|Name" 
     383msgstr "Nimi" 
     384 
     385#: app/models/user_group.rb:- 
     386msgid "UserGroup|Information" 
     387msgstr "Tiedot" 
     388 
     389#: app/models/role.rb:- 
     390msgid "role" 
     391msgstr "rooli" 
     392 
     393#: app/models/role.rb:- 
     394msgid "Role|Name" 
     395msgstr "Nimi" 
     396 
     397#: app/models/role.rb:- 
     398msgid "Role|Info" 
     399msgstr "Tiedot" 
     400 
     401#: app/models/report_category.rb:- 
     402msgid "report category" 
     403msgstr "Raporttikategoria" 
     404 
     405#: app/models/report_category.rb:- 
     406msgid "ReportCategory|Parent" 
     407msgstr "Vanhempi" 
     408 
     409#: app/models/report_category.rb:- 
     410msgid "ReportCategory|Name" 
     411msgstr "Nimi" 
     412 
     413#: app/models/report_field_value.rb:- 
     414msgid "report field value" 
     415msgstr "report field value" 
     416 
     417#: app/models/report_field_value.rb:- 
     418msgid "ReportFieldValue|Type" 
     419msgstr "ReportFieldValue|Type" 
     420 
     421#: app/models/report_field_value.rb:- 
     422msgid "ReportFieldValue|Report" 
     423msgstr "ReportFieldValue|Report" 
     424 
     425#: app/models/report_field_value.rb:- 
     426msgid "ReportFieldValue|Report field" 
     427msgstr "ReportFieldValue|Report field" 
     428 
     429#: app/models/report_field_value.rb:- 
     430msgid "ReportFieldValue|String value" 
     431msgstr "ReportFieldValue|String value" 
     432 
     433#: app/models/report_field_value.rb:- 
     434msgid "ReportFieldValue|Int value" 
     435msgstr "ReportFieldValue|Int value" 
     436 
     437#: app/models/report_field_value.rb:- 
     438msgid "ReportFieldValue|Bool value" 
     439msgstr "ReportFieldValue|Bool value" 
     440 
     441#: app/models/report_field_value.rb:- 
     442msgid "ReportFieldValue|Float value" 
     443msgstr "ReportFieldValue|Float value" 
     444 
     445#: app/models/report_field_value.rb:- 
     446msgid "ReportFieldValue|Date value" 
     447msgstr "ReportFieldValue|Date value" 
     448 
     449#: app/models/report_field_value.rb:- 
     450msgid "ReportFieldValue|Time value" 
     451msgstr "ReportFieldValue|Time value" 
     452 
     453#: app/models/report_field_value.rb:- 
     454msgid "ReportFieldValue|Datetime value" 
     455msgstr "ReportFieldValue|Datetime value" 
     456 
     457#: app/models/report_field_value.rb:- 
     458msgid "ReportFieldValue|Position x" 
     459msgstr "ReportFieldValue|Position x" 
     460 
     461#: app/models/report_field_value.rb:- 
     462msgid "ReportFieldValue|Position y" 
     463msgstr "ReportFieldValue|Position y" 
     464 
     465#: app/models/protected_join_model.rb:- 
     466msgid "protected join model" 
     467msgstr "Suojattu liitosmalli" 
     468 
     469#: app/controllers/work_order_controller.rb:22 
     470#: app/controllers/report_controller.rb:360 
     471#: app/controllers/attachment_controller.rb:12 
     472#: app/views/attachment/view.rhtml:3 
     473#: app/views/report/view.rhtml:11 
     474#: app/views/work_order/_form.rhtml:5 
     475#: app/views/online_help/index.rhtml:2 
     476#: config/menu.rb:50 
     477msgid "Asset" 
     478msgstr "Kohde" 
     479 
     480#: app/controllers/work_order_controller.rb:24 
     481#: app/controllers/work_order_type_controller.rb:11 
     482#: app/controllers/work_order_type_controller.rb:18 
     483#: app/controllers/user_controller.rb:61 
     484#: app/views/asset/online_help__edit.rhtml:16 
     485#: app/views/work_order/_form.rhtml:54 
     486#: app/views/user/edit.rhtml:21 
     487msgid "Description" 
     488msgstr "Kuvaus" 
     489 
     490#: app/controllers/work_order_controller.rb:25 
     491#: app/controllers/report_controller.rb:362 
     492#: app/controllers/attachment_controller.rb:15 
     493#: app/views/attachment/view.rhtml:25 
     494#: app/views/report_type/preview.rhtml:22 
     495msgid "Creator" 
     496msgstr "Luoja" 
     497 
     498#: app/controllers/work_order_controller.rb:26 
     499#: app/views/work_order/_form.rhtml:28 
     500#: app/views/work_order/create.rhtml:30 
     501msgid "Starting time" 
     502msgstr "Aloitusaika" 
     503 
     504#: app/controllers/work_order_controller.rb:27 
     505#: app/views/work_order/_form.rhtml:37 
     506#: app/views/work_order/create.rhtml:34 
     507msgid "Deadline" 
     508msgstr "Takaraja" 
     509 
     510#: app/controllers/work_order_controller.rb:31 
     511msgid "Anybody" 
     512msgstr "Kuka tahansa" 
     513 
     514#: app/controllers/work_order_controller.rb:42 
     515msgid "Work orders for branch %s" 
     516msgstr "TyömÀÀrÀimet haaralle %s" 
     517 
     518#: app/controllers/work_order_controller.rb:45 
     519msgid "Work orders for asset %s" 
     520msgstr "TyömÀÀrÀimet kohteelle %s" 
     521 
     522#: app/controllers/work_order_controller.rb:73 
    24523#: app/controllers/asset_controller.rb:31 
    25 #: app/controllers/asset_tree_controller.rb:50 
    26524#: app/controllers/data_permission_controller.rb:31 
    27525#: app/controllers/data_permission_controller.rb:34 
    28526#: app/controllers/data_permission_controller.rb:37 
    29527#: app/controllers/attachment_controller.rb:46