Commit 8fabfb85d31e97312cadf503791a3742e92ce3df

Authored by Rodrigo Souto
1 parent a1d51c76

[bsc-contract] Controllers

(ActionItem2079)
plugins/bsc/controllers/bsc_plugin_environment_controller.rb
  1 +include BscPlugin::BscHelper
  2 +
1 3 class BscPluginEnvironmentController < AdminController
2 4  
3 5 def new
... ...
plugins/bsc/controllers/bsc_plugin_myprofile_controller.rb
  1 +include BscPlugin::BscHelper
  2 +
1 3 class BscPluginMyprofileController < MyProfileController
2 4  
3 5 def manage_associated_enterprises
... ... @@ -85,4 +87,129 @@ class BscPluginMyprofileController &lt; MyProfileController
85 87 end
86 88 end
87 89  
  90 + def manage_contracts
  91 + self.class.no_design_blocks
  92 + @sorting = params[:sorting] || 'created_at asc'
  93 + sorted_by = @sorting.split(' ').first
  94 + sort_direction = @sorting.split(' ').last
  95 + @status = params[:status] || BscPlugin::Contract::Status.types.map { |s| s.to_s }
  96 + @contracts = profile.contracts.
  97 + status(@status).
  98 + sorted_by(sorted_by, sort_direction).
  99 + paginate(:per_page => contracts_per_page, :page => params[:page])
  100 + end
  101 +
  102 + def new_contract
  103 + if !request.post?
  104 + @contract = BscPlugin::Contract.new
  105 + else
  106 + @contract = BscPlugin::Contract.new(params[:contract])
  107 + @contract.bsc = profile
  108 + sales = params[:sales] ? params[:sales].map {|key, value| value} : []
  109 + sales.reject! {|sale| sale[:product_id].blank?}
  110 +
  111 + if @contract.save!
  112 + enterprises_ids = params[:enterprises] || ''
  113 + enterprises_ids.split(',').each { |id| @contract.enterprises << Enterprise.find(id) }
  114 + @failed_sales = @contract.save_sales(sales)
  115 +
  116 + if @failed_sales.blank?
  117 + session[:notice] = _('Contract created.')
  118 + redirect_to :action => 'manage_contracts'
  119 + else
  120 + session[:notice] = _('Contract created but some products could not be added.')
  121 + redirect_to :action => 'edit_contract', :contract_id => @contract.id
  122 + end
  123 + end
  124 + end
  125 + end
  126 +
  127 + def view_contract
  128 + begin
  129 + @contract = BscPlugin::Contract.find(params[:contract_id])
  130 + rescue
  131 + session[:notice] = _('Contract doesn\'t exists! Maybe it was already removed.')
  132 + redirect_to :action => 'manage_contracts'
  133 + end
  134 + end
  135 +
  136 + def edit_contract
  137 + begin
  138 + @contract = BscPlugin::Contract.find(params[:contract_id])
  139 + rescue
  140 + session[:notice] = _('Could not edit such contract.')
  141 + redirect_to :action => 'manage_contracts'
  142 + end
  143 + if request.post? && @contract.update_attributes(params[:contract])
  144 +
  145 + # updating associated enterprises
  146 + enterprises_ids = params[:enterprises] || ''
  147 + enterprises = [Enterprise.find(enterprises_ids.split(','))].flatten
  148 + to_remove = @contract.enterprises - enterprises
  149 + to_add = enterprises - @contract.enterprises
  150 + to_remove.each { |enterprise| @contract.enterprises.delete(enterprise)}
  151 + to_add.each { |enterprise| @contract.enterprises << enterprise }
  152 +
  153 + # updating sales
  154 + sales = params[:sales] ? params[:sales].map {|key, value| value} : []
  155 + sales.reject! {|sale| sale[:product_id].blank?}
  156 + products = [Product.find(sales.map { |sale| sale[:product_id] })].flatten
  157 + to_remove = @contract.products - products
  158 + to_keep = sales.select { |sale| @contract.products.include?(Product.find(sale[:product_id])) }
  159 +
  160 + to_keep.each do |sale_attrs|
  161 + sale = @contract.sales.find_by_product_id(sale_attrs[:product_id])
  162 + sale.update_attributes!(sale_attrs)
  163 + sales.delete(sale_attrs)
  164 + end
  165 +
  166 + to_remove.each { |product| @contract.sales.find_by_product_id(product.id).destroy }
  167 + @failed_sales = @contract.save_sales(sales)
  168 +
  169 + if @failed_sales.blank?
  170 + session[:notice] = _('Contract edited.')
  171 + redirect_to :action => 'manage_contracts'
  172 + else
  173 + session[:notice] = _('Contract edited but some products could not be added.')
  174 + redirect_to :action => 'edit_contract', :contract_id => @contract.id
  175 + end
  176 + end
  177 + end
  178 +
  179 + def destroy_contract
  180 + begin
  181 + contract = BscPlugin::Contract.find(params[:contract_id])
  182 + contract.destroy
  183 + session[:notice] = _('Contract removed.')
  184 + rescue
  185 + session[:notice] = _('Contract could not be removed. Sorry! ^^')
  186 + end
  187 + redirect_to :action => 'manage_contracts'
  188 + end
  189 +
  190 + def search_contract_enterprises
  191 + render :text => profile.enterprises.find(:all, :conditions => ["(LOWER(name) LIKE ? OR LOWER(identifier) LIKE ?)", "%#{params[:enterprises]}%", "%#{params[:enterprises]}%"]).
  192 + map {|enterprise| {:id => enterprise.id, :name => enterprise.short_name(60)} }.
  193 + to_json
  194 + end
  195 +
  196 + def search_sale_product
  197 + query = params[:sales].map {|key, value| value}[0][:product_id]
  198 + enterprises = (params[:enterprises] || []).split(',')
  199 + enterprises = enterprises.blank? ? '' : enterprises
  200 + added_products = (params[:added_products] || []).split(',')
  201 + added_products = added_products.blank? ? '' : added_products
  202 + render :text => Product.find(:all, :conditions => ["LOWER(name) LIKE ? AND enterprise_id IN (?) AND id NOT IN (?)", "%#{query}%", enterprises, added_products]).
  203 + map {|product| { :id => product.id,
  204 + :name => short_text(product_display_name(product), 60),
  205 + :sale_id => params[:sale_id],
  206 + :product_price => product.price || 0 }}.
  207 + to_json
  208 + end
  209 +
  210 + private
  211 +
  212 + def contracts_per_page
  213 + 15
  214 + end
88 215 end
... ...
plugins/bsc/test/functional/bsc_plugin_myprofile_controller_test.rb
... ... @@ -40,7 +40,7 @@ class BscPluginMyprofileControllerTest &lt; Test::Unit::TestCase
40 40 e6 = Enterprise.create!(:name => 'Bla', :identifier => 'sample-enterprise-6')
41 41  
42 42 get :search_enterprise, :profile => bsc.identifier, :q => 'sampl'
43   -
  43 +
44 44 assert_match /#{e1.name}/, @response.body
45 45 assert_match /#{e2.name}/, @response.body
46 46 assert_no_match /#{e3.name}/, @response.body
... ... @@ -108,5 +108,204 @@ class BscPluginMyprofileControllerTest &lt; Test::Unit::TestCase
108 108 assert_equal enterprise.bsc, bsc
109 109 end
110 110  
  111 + should 'fecth contracts filtered by status' do
  112 + contract0 = BscPlugin::Contract.create!(:bsc => bsc, :status => 0, :client_name => 'Marvin')
  113 + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :status => 1, :client_name => 'Marvin')
  114 + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :status => 2, :client_name => 'Marvin')
  115 + contract3 = BscPlugin::Contract.create!(:bsc => bsc, :status => 3, :client_name => 'Marvin')
  116 +
  117 + get :manage_contracts, :profile => bsc.identifier, :status => ['1', '3']
  118 +
  119 + assert_not_includes assigns(:contracts), contract0
  120 + assert_includes assigns(:contracts), contract1
  121 + assert_not_includes assigns(:contracts), contract2
  122 + assert_includes assigns(:contracts), contract3
  123 + end
  124 +
  125 + should 'manage contracts should have all status marked by default' do
  126 + get :manage_contracts, :profile => bsc.identifier
  127 + assert_equal assigns(:status), BscPlugin::Contract::Status.types.map { |s| s.to_s }
  128 + end
  129 +
  130 + should 'fetch contracts sorted accordingly' do
  131 + contract0 = BscPlugin::Contract.create!(:bsc => bsc, :created_at => 1.day.ago, :client_name => 'Eva')
  132 + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :created_at => 2.day.ago, :client_name => 'Adam')
  133 + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :created_at => 3.day.ago, :client_name => 'Marvin')
  134 +
  135 + by_date = [contract2, contract1, contract0]
  136 + by_name = [contract1, contract0, contract2]
  137 +
  138 + get :manage_contracts, :profile => bsc.identifier, :sorting => 'created_at asc'
  139 + assert_equal by_date, assigns(:contracts)
  140 +
  141 + get :manage_contracts, :profile => bsc.identifier, :sorting => 'created_at desc'
  142 + assert_equal by_date.reverse, assigns(:contracts)
  143 +
  144 + get :manage_contracts, :profile => bsc.identifier, :sorting => 'client_name asc'
  145 + assert_equal by_name, assigns(:contracts)
  146 +
  147 + get :manage_contracts, :profile => bsc.identifier, :sorting => 'client_name desc'
  148 + assert_equal by_name.reverse, assigns(:contracts)
  149 + end
  150 +
  151 + should 'limit the contracts to defined per page' do
  152 + BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin')
  153 + BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin')
  154 +
  155 + @controller.stubs(:contracts_per_page).returns(1)
  156 +
  157 + get :manage_contracts, :profile => bsc.identifier
  158 +
  159 + assert_equal 1, assigns(:contracts).count
  160 + end
  161 +
  162 + should 'destroy contract' do
  163 + contract = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin')
  164 +
  165 + assert_difference BscPlugin::Contract, :count, -1 do
  166 + get :destroy_contract, :profile => bsc.identifier, :contract_id => contract.id
  167 + end
  168 +
  169 + assert_raise ActiveRecord::RecordNotFound do
  170 + BscPlugin::Contract.find(contract.id)
  171 + end
  172 + end
  173 +
  174 + should 'not crash if trying to destroy a contract that does not exists' do
  175 + assert_nothing_raised do
  176 + get :destroy_contract, :profile => bsc.identifier, :contract_id => -1
  177 + end
  178 + assert_redirected_to :action => 'manage_contracts'
  179 + end
  180 +
  181 + should 'not crash if trying to edit a contract that does not exists' do
  182 + assert_nothing_raised do
  183 + get :edit_contract, :profile => bsc.identifier, :contract_id => -1
  184 + end
  185 + assert_redirected_to :action => 'manage_contracts'
  186 + end
  187 +
  188 + should 'create contract associating the enterprises' do
  189 + enterprise1 = fast_create(Enterprise)
  190 + enterprise2 = fast_create(Enterprise)
  191 +
  192 + post :new_contract, :profile => bsc.identifier, :enterprises => "#{enterprise1.id},#{enterprise2.id}", :contract => {:bsc => bsc, :client_name => 'Marvin'}
  193 +
  194 + bsc.reload
  195 + contract = bsc.contracts.last
  196 +
  197 + assert_includes contract.enterprises, enterprise1
  198 + assert_includes contract.enterprises, enterprise2
  199 + end
  200 +
  201 + should 'edit contract adding or removing enterprises accordingly' do
  202 + enterprise1 = fast_create(Enterprise)
  203 + enterprise2 = fast_create(Enterprise)
  204 + enterprise3 = fast_create(Enterprise)
  205 + contract = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin')
  206 + contract.enterprises << enterprise1
  207 + contract.enterprises << enterprise2
  208 +
  209 + post :edit_contract, :profile => bsc.identifier, :contract_id => contract.id, :enterprises => "#{enterprise2.id},#{enterprise3.id}", :contract => {:bsc => bsc}
  210 + contract.reload
  211 +
  212 + assert_not_includes contract.enterprises, enterprise1
  213 + assert_includes contract.enterprises, enterprise2
  214 + assert_includes contract.enterprises, enterprise3
  215 + end
  216 +
  217 + should 'not crash if there is no enterprises on create' do
  218 + assert_nothing_raised do
  219 + post :new_contract, :profile => bsc.identifier, :contract => {:bsc => bsc, :client_name => 'Marvin'}
  220 + end
  221 + end
  222 +
  223 + should 'create contract with associated sales' do
  224 + product1 = fast_create(Product, :price => 2.50)
  225 + product2 = fast_create(Product)
  226 + sale1 = {:product_id => product1.id, :quantity => 2}
  227 + sale2 = {:product_id => product2.id, :quantity => 5, :price => 3.50}
  228 + sales = {1 => sale1, 2 => sale2}
  229 +
  230 + post :new_contract, :profile => bsc.identifier, :sales => sales, :contract => {:bsc => bsc, :client_name => 'Marvin'}
  231 +
  232 + bsc.reload
  233 + contract = bsc.contracts.last
  234 +
  235 + assert_includes contract.products, product1
  236 + assert_includes contract.products, product2
  237 +
  238 + assert_equal sale1[:quantity], contract.sales.find_by_product_id(sale1[:product_id]).quantity
  239 + assert_equal sale2[:quantity], contract.sales.find_by_product_id(sale2[:product_id]).quantity
  240 + assert_equal sale2[:price], contract.sales.find_by_product_id(sale2[:product_id]).price
  241 + end
  242 +
  243 + should 'edit contract adding or removing sales accordingly' do
  244 + product1 = fast_create(Product)
  245 + product2 = fast_create(Product)
  246 + product3 = fast_create(Product)
  247 + contract = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin')
  248 + BscPlugin::Sale.create!(:product => product1, :contract => contract, :quantity => 1)
  249 + BscPlugin::Sale.create!(:product => product2, :contract => contract, :quantity => 1)
  250 + sales = {1 => {:product_id => product2.id, :quantity => 1}, 2 => {:product_id => product3.id, :quantity => 1}}
  251 +
  252 + post :edit_contract, :profile => bsc.identifier, :contract_id => contract.id, :sales => sales , :contract => {:bsc => bsc}
  253 + contract.reload
  254 +
  255 + assert_not_includes contract.products, product1
  256 + assert_includes contract.products, product2
  257 + assert_includes contract.products, product3
  258 + end
  259 +
  260 + should 'edit sales informations' do
  261 + product1 = fast_create(Product)
  262 + product2 = fast_create(Product)
  263 + contract = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin')
  264 + sale1 = BscPlugin::Sale.create!(:product => product1, :contract => contract, :quantity => 1, :price => 1.0)
  265 + sale2 = BscPlugin::Sale.create!(:product => product2, :contract => contract, :quantity => 2, :price => 2.0)
  266 + sale2.save!
  267 + sales = {1 => {:product_id => product1.id, :quantity => 3, :price => 5.0}, 2 => {:product_id => product2.id, :quantity => 4, :price => 10.0}}
  268 +
  269 + post :edit_contract, :profile => bsc.identifier, :contract_id => contract.id, :sales => sales , :contract => {:bsc => bsc}
  270 +
  271 + sale1.reload
  272 + sale2.reload
  273 +
  274 + assert_equal 3, sale1.quantity
  275 + assert_equal 5.0, sale1.price
  276 + assert_equal 4, sale2.quantity
  277 + assert_equal 10.0, sale2.price
  278 + end
  279 +
  280 + should 'redirect to edit contract if some sale could not be created' do
  281 + product = fast_create(Product)
  282 + # sale without quantity
  283 + sales = {1 => {:product_id => product.id, :price => 1.50}}
  284 +
  285 + post :new_contract, :profile => bsc.identifier, :sales => sales, :contract => {:bsc => bsc, :client_name => 'Marvin'}
  286 +
  287 + bsc.reload
  288 + contract = bsc.contracts.last
  289 +
  290 + assert_redirected_to :action => 'edit_contract', :contract_id => contract.id
  291 + end
  292 +
  293 + should 'search for products from the invoved enterprises' do
  294 + # product1 fits
  295 + # product2 doesn't fits because its in added_products
  296 + # product3 doesn't fits because its enterprise is in enterprises
  297 + enterprise1 = fast_create(Enterprise)
  298 + enterprise2 = fast_create(Enterprise)
  299 + enterprise3 = fast_create(Enterprise)
  300 + product1 = fast_create(Product, :enterprise_id => enterprise1.id, :name => 'Black Bycicle')
  301 + product2 = fast_create(Product, :enterprise_id => enterprise2.id, :name => 'Black Guitar')
  302 + product3 = fast_create(Product, :enterprise_id => enterprise3.id, :name => 'Black Notebook')
  303 +
  304 + get :search_sale_product, :profile => bsc.identifier, :enterprises => [enterprise1.id,enterprise2.id].join(','), :added_products => [product2.id].join(','),:sales => {1 => {:product_id => 'black'}}
  305 +
  306 + assert_match /#{product1.name}/, @response.body
  307 + assert_no_match /#{product2.name}/, @response.body
  308 + assert_no_match /#{product3.name}/, @response.body
  309 + end
111 310 end
112 311  
... ...