app/models/constitution_proposal_bundle.rb
require 'one_click_orgs/model_wrapper'
# Provides an ActiveModel like interface to a bundle of ConstitutionProposals.
# The attributes exposed are the constitution settings themselves (e.g. organisation_name,
# voting_period, etc.), plus a single 'proposer' attribute.
class ConstitutionProposalBundle < OneClickOrgs::ModelWrapper
attr_accessor :organisation,
:organisation_name,
:objectives,
:assets,
:general_voting_system,
:membership_voting_system,
:constitution_voting_system,
:voting_period,
:proposer,
:proposals,
:registered_office_address, # Coop clauses
:user_members, :employee_members, :supporter_members, :producer_members, :consumer_members,
:producer_members_description, :consumer_members_description,
:single_shareholding,
:max_user_directors, :max_employee_directors, :max_supporter_directors, :max_producer_directors, :max_consumer_directors,
:common_ownership
def after_initialize
# Load existing settings from organisation, if given, but don't
# overwrite new settings that have been passed directly in as attributes.
if organisation
case organisation
when Association
[:organisation_name, :objectives, :voting_period].each do |clause_name|
send("#{clause_name}=", organisation.constitution.send(clause_name)) unless send("#{clause_name}")
end
[:general, :membership, :constitution].each do |voting_system_type|
send("#{voting_system_type}_voting_system=", organisation.constitution.voting_system(voting_system_type).simple_name) unless send("#{voting_system_type}_voting_system")
end
self.assets = (!!organisation.constitution.assets ? '1' : '0') unless assets
when Coop
[
:organisation_name, :objectives, :registered_office_address,
:max_user_directors, :max_employee_directors, :max_supporter_directors, :max_producer_directors, :max_consumer_directors,
:producer_members_description, :consumer_members_description
].each do |clause_name|
send("#{clause_name}=", organisation.constitution.send(clause_name)) unless send(clause_name)
end
[
:user_members, :employee_members, :supporter_members, :producer_members, :consumer_members,
:single_shareholding,
:common_ownership
].each do |clause_name|
send("#{clause_name}=", !!organisation.constitution.send(clause_name) ? '1' : '0') unless send(clause_name)
end
end
end
self.proposals ||= []
end
def save
case organisation
when Association
build_proposals_for_association
when Coop
build_proposals_for_coop
end
# Early exit?
if proposals.empty?
errors.add(:base, "No changes were made")
return false
end
# Only save if we have no errors
if errors.empty?
proposals.each(&:save!)
true
else
false
end
end
def persisted?
false
end
protected
def build_proposals_for_association
# Organisation name
if organisation.name != organisation_name
proposal = (organisation.change_text_proposals.new(
:name => 'organisation_name',
:value => organisation_name
))
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:organisation_name, proposal.errors.full_messages.to_sentence)
end
end
# Objectives
if organisation.objectives != objectives
proposal = (organisation.change_text_proposals.new(
:name => 'organisation_objectives',
:value => objectives
))
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:objectives, proposal.errors.full_messages.to_sentence)
end
end
# Assets
if assets == '1'
title = "Change the constitution to allow holding, transferral and disposal of material assets and intangible assets"
new_assets_value = true
else
title = "Change the constitution to prohibit holding, transferral or disposal of material assets and intangible assets"
new_assets_value = false
end
if (organisation.assets && !new_assets_value) || (!organisation.assets && new_assets_value) # Bit verbose, to cope with null values
proposal = (organisation.change_boolean_proposals.new(
:title => title,
:name => 'assets',
:value => new_assets_value
))
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:assets, proposal.errors.full_messages.to_sentence)
end
end
# General voting system
proposed_system = VotingSystems.get(general_voting_system)
current_system = organisation.constitution.voting_system :general
if current_system != proposed_system
proposal = (organisation.change_voting_system_proposals.new(
:proposal_type => 'general',
:proposed_system => proposed_system.simple_name
))
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:general_voting_system, proposal.errors.full_messages.to_sentence)
end
end
# Membership voting system
proposed_system = VotingSystems.get(membership_voting_system)
current_system = organisation.constitution.voting_system :membership
if current_system != proposed_system
proposal = (organisation.change_voting_system_proposals.new(
:proposal_type => 'membership',
:proposed_system => proposed_system.simple_name
))
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:membership_voting_system, proposal.errors.full_messages.to_sentence)
end
end
# Constitution voting system
proposed_system = VotingSystems.get(constitution_voting_system)
current_system = organisation.constitution.voting_system :constitution
if current_system != proposed_system
proposal = (organisation.change_voting_system_proposals.new(
:proposal_type => 'constitution',
:proposed_system => proposed_system.simple_name
))
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:constitution_voting_system, proposal.errors.full_messages.to_sentence)
end
end
# Voting period
if organisation.constitution.voting_period != voting_period.to_i
proposal = organisation.change_voting_period_proposals.new(
:new_voting_period => voting_period
)
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:voting_period, proposal.errors.full_messages.to_sentence)
end
end
end
def build_proposals_for_coop
ability = Ability.new(proposer)
# Organisation name
if organisation.name != organisation_name
proposal = if ability.can?(:create, Resolution)
organisation.change_text_resolutions.build(
:name => 'organisation_name',
:value => organisation_name,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:resolution_class => 'ChangeTextResolution',
:resolution_parameters => {
:name => 'organisation_name',
:value => organisation_name
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:organisation_name, proposal.errors.full_messages.to_sentence)
end
end
# Objectives
if organisation.objectives != objectives
proposal = if ability.can?(:create, Resolution)
organisation.change_text_resolutions.build(
:name => 'organisation_objectives',
:value => objectives,
:title => "Change objects to '#{objectives}'",
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => "Change objects to '#{objectives}'",
:resolution_class => "ChangeTextResolution",
:resolution_parameters => {
:name => 'organisation_objectives',
:value => objectives,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:objectives, proposal.errors.full_messages.to_sentence)
end
end
# Registered office address
if organisation.registered_office_address != registered_office_address
proposal = if ability.can?(:create, Resolution)
organisation.change_text_resolutions.build(
:name => 'registered_office_address',
:value => registered_office_address,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:resolution_class => "ChangeTextResolution",
:resolution_parameters => {
:name => 'registered_office_address',
:value => registered_office_address
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:registered_office_address, proposal.errors.full_messages.to_sentence)
end
end
# Member types
if user_members == '1'
title = "Change the Rules to allow User Members"
new_user_members_value = true
else
title = "Change the Rules to disallow User Members"
new_user_members_value = false
end
if (organisation.user_members && !new_user_members_value) || (!organisation.user_members && new_user_members_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'user_members',
:value => new_user_members_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => 'ChangeBooleanResolution',
:resolution_parameters => {
:name => 'user_members',
:value => new_user_members_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:user_members, proposal.errors.full_messages.to_sentence)
end
end
if employee_members == '1'
title = "Change the Rules to allow Employee Members"
new_employee_members_value = true
else
title = "Change the Rules to disallow Employee Members"
new_employee_members_value = false
end
if (organisation.employee_members && !new_employee_members_value) || (!organisation.employee_members && new_employee_members_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'employee_members',
:value => new_employee_members_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => 'ChangeBooleanResolution',
:resolution_parameters => {
:name => 'employee_members',
:value => new_employee_members_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:employee_members, proposal.errors.full_messages.to_sentence)
end
end
if supporter_members == '1'
title = "Change the Rules to allow Supporter Members"
new_supporter_members_value = true
else
title = "Change the Rules to disallow Supporter Members"
new_supporter_members_value = false
end
if (organisation.supporter_members && !new_supporter_members_value) || (!organisation.supporter_members && new_supporter_members_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'supporter_members',
:value => new_supporter_members_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => 'ChangeBooleanResolution',
:resolution_parameters => {
:name => 'supporter_members',
:value => new_supporter_members_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:supporter_members, proposal.errors.full_messages.to_sentence)
end
end
if producer_members == '1'
title = "Change the Rules to allow Producer Members"
new_producer_members_value = true
else
title = "Change the Rules to disallow Producer Members"
new_producer_members_value = false
end
if (organisation.producer_members && !new_producer_members_value) || (!organisation.producer_members && new_producer_members_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'producer_members',
:value => new_producer_members_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => 'ChangeBooleanResolution',
:resolution_parameters => {
:name => 'producer_members',
:value => new_producer_members_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:producer_members, proposal.errors.full_messages.to_sentence)
end
end
if consumer_members == '1'
title = "Change the Rules to allow Consumer Members"
new_consumer_members_value = true
else
title = "Change the Rules to disallow Consumer Members"
new_consumer_members_value = false
end
if (organisation.consumer_members && !new_consumer_members_value) || (!organisation.consumer_members && new_consumer_members_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'consumer_members',
:value => new_consumer_members_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => 'ChangeBooleanResolution',
:resolution_parameters => {
:name => 'consumer_members',
:value => new_consumer_members_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:consumer_members, proposal.errors.full_messages.to_sentence)
end
end
# Shareholding
if single_shareholding == '1'
title = "Change the Rules to permit each Member to hold only one share"
new_single_shareholding_value = true
else
title = "Change the Rules to permit each Member to hold more than one share"
new_single_shareholding_value = false
end
if (organisation.single_shareholding && !new_single_shareholding_value) || (!organisation.single_shareholding && new_single_shareholding_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'single_shareholding',
:value => new_single_shareholding_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => "ChangeBooleanResolution",
:resolution_parameters => {
:name => 'single_shareholding',
:value => new_single_shareholding_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:single_shareholding, proposal.errors.full_messages.to_sentence)
end
end
# Board composition
if organisation.max_user_directors != max_user_directors.to_i
proposal = if ability.can?(:create, Resolution)
organisation.change_integer_resolutions.build(
:name => 'max_user_directors',
:value => max_user_directors.to_i,
:title => "Allow a maximum of #{max_user_directors} User Members on the Board",
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => "Allow a maximum of #{max_user_directors} User Members on the Board",
:resolution_class => 'ChangeIntegerResolution',
:resolution_parameters => {
:name => 'max_user_directors',
:value => max_user_directors.to_i
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:max_user_directors, proposal.errors.full_messages.to_sentence)
end
end
if organisation.max_employee_directors != max_employee_directors.to_i
proposal = if ability.can?(:create, Resolution)
organisation.change_integer_resolutions.build(
:name => 'max_employee_directors',
:value => max_employee_directors.to_i,
:title => "Allow a maximum of #{max_employee_directors} Employee Members on the Board",
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => "Allow a maximum of #{max_employee_directors} Employee Members on the Board",
:resolution_class => 'ChangeIntegerResolution',
:resolution_parameters => {
:name => 'max_employee_directors',
:value => max_employee_directors.to_i
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:max_employee_directors, proposal.errors.full_messages.to_sentence)
end
end
if organisation.max_supporter_directors != max_supporter_directors.to_i
proposal = if ability.can?(:create, Resolution)
organisation.change_integer_resolutions.build(
:name => 'max_supporter_directors',
:value => max_supporter_directors.to_i,
:title => "Allow a maximum of #{max_supporter_directors} Supporter Members on the Board",
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => "Allow a maximum of #{max_supporter_directors} Supporter Members on the Board",
:resolution_class => 'ChangeIntegerResolution',
:resolution_parameters => {
:name => 'max_supporter_directors',
:value => max_supporter_directors.to_i
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:max_supporter_directors, proposal.errors.full_messages.to_sentence)
end
end
if organisation.max_producer_directors != max_producer_directors.to_i
proposal = if ability.can?(:create, Resolution)
organisation.change_integer_resolutions.build(
:name => 'max_producer_directors',
:value => max_producer_directors.to_i,
:title => "Allow a maximum of #{max_producer_directors} Producer Members on the Board",
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => "Allow a maximum of #{max_producer_directors} Producer Members on the Board",
:resolution_class => 'ChangeIntegerResolution',
:resolution_parameters => {
:name => 'max_producer_directors',
:value => max_producer_directors.to_i
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:max_producer_directors, proposal.errors.full_messages.to_sentence)
end
end
if organisation.max_consumer_directors != max_consumer_directors.to_i
proposal = if ability.can?(:create, Resolution)
organisation.change_integer_resolutions.build(
:name => 'max_consumer_directors',
:value => max_consumer_directors.to_i,
:title => "Allow a maximum of #{max_consumer_directors} Consumer Members on the Board",
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => "Allow a maximum of #{max_consumer_directors} Consumer Members on the Board",
:resolution_class => 'ChangeIntegerResolution',
:resolution_parameters => {
:name => 'max_consumer_directors',
:value => max_consumer_directors.to_i
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:max_consumer_directors, proposal.errors.full_messages.to_sentence)
end
end
# Ownership
if common_ownership == '1'
title = "Change the organisation to be a Common Ownership enterprise"
new_common_ownership_value = true
else
title = "Change the organisation to be a Co-ownership enterprise"
new_common_ownership_value = false
end
if (organisation.common_ownership && !new_common_ownership_value) || (!organisation.common_ownership && new_common_ownership_value) # Bit verbose, to cope with null values
proposal = if ability.can?(:create, Resolution)
organisation.change_boolean_resolutions.build(
:title => title,
:name => 'common_ownership',
:value => new_common_ownership_value,
:draft => true
)
elsif ability.can?(:create, ResolutionProposal)
organisation.resolution_proposals.build(
:title => title,
:resolution_class => 'ChangeBooleanResolution',
:resolution_parameters => {
:name => 'common_ownership',
:value => new_common_ownership_value,
}
)
end
proposal.proposer = proposer
if proposal.valid?
proposals.push(proposal)
else
errors.add(:common_ownership, proposal.errors.full_messages.to_sentence)
end
end
end
end