Commit df887fc89812b073b83e3a66331998cd47ab609e
Exists in
master
and in
29 other branches
Merge commit 'refs/merge-requests/71' of git://gitorious.org/noosfero/noosfero
Showing
36 changed files
with
1353 additions
and
124 deletions
Show diff stats
app/helpers/dates_helper.rb
@@ -42,11 +42,11 @@ module DatesHelper | @@ -42,11 +42,11 @@ module DatesHelper | ||
42 | end | 42 | end |
43 | end | 43 | end |
44 | 44 | ||
45 | - def show_period(date1, date2 = nil) | 45 | + def show_period(date1, date2 = nil, use_numbers = false) |
46 | if (date1 == date2) || (date2.nil?) | 46 | if (date1 == date2) || (date2.nil?) |
47 | - show_date(date1) | 47 | + show_date(date1, use_numbers) |
48 | else | 48 | else |
49 | - _('from %{date1} to %{date2}') % {:date1 => show_date(date1), :date2 => show_date(date2)} | 49 | + _('from %{date1} to %{date2}') % {:date1 => show_date(date1, use_numbers), :date2 => show_date(date2, use_numbers)} |
50 | end | 50 | end |
51 | end | 51 | end |
52 | 52 |
plugins/bsc/controllers/bsc_plugin_environment_controller.rb
plugins/bsc/controllers/bsc_plugin_myprofile_controller.rb
1 | +include BscPlugin::BscHelper | ||
2 | + | ||
1 | class BscPluginMyprofileController < MyProfileController | 3 | class BscPluginMyprofileController < MyProfileController |
2 | 4 | ||
3 | def manage_associated_enterprises | 5 | def manage_associated_enterprises |
@@ -85,4 +87,129 @@ class BscPluginMyprofileController < MyProfileController | @@ -85,4 +87,129 @@ class BscPluginMyprofileController < MyProfileController | ||
85 | end | 87 | end |
86 | end | 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? ? -1 : enterprises | ||
200 | + added_products = (params[:added_products] || []).split(',') | ||
201 | + added_products = added_products.blank? ? -1 : 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 | end | 215 | end |
plugins/bsc/db/migrate/20111018201143_create_bsc_plugin_sale.rb
0 → 100644
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +class CreateBscPluginSale < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :bsc_plugin_sales do |t| | ||
4 | + t.references :product, :null => false | ||
5 | + t.references :contract, :null => false | ||
6 | + t.integer :quantity, :null => false | ||
7 | + t.decimal :price | ||
8 | + t.timestamps | ||
9 | + end | ||
10 | + end | ||
11 | + | ||
12 | + def self.down | ||
13 | + drop_table :bsc_plugin_sales | ||
14 | + end | ||
15 | +end |
plugins/bsc/db/migrate/20111018201220_create_bsc_plugin_contracts_enterprises.rb
0 → 100644
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +class CreateBscPluginContractsEnterprises < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :bsc_plugin_contracts_enterprises, :id => false do |t| | ||
4 | + t.references :contract | ||
5 | + t.references :enterprise | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | + def self.down | ||
10 | + drop_table :bsc_plugin_contracts_enterprises | ||
11 | + end | ||
12 | +end |
plugins/bsc/db/migrate/20111018201239_create_bsc_plugin_contract.rb
0 → 100644
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +class CreateBscPluginContract < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :bsc_plugin_contracts do |t| | ||
4 | + t.string :client_name | ||
5 | + t.integer :client_type | ||
6 | + t.integer :business_type | ||
7 | + t.string :state | ||
8 | + t.string :city | ||
9 | + t.integer :status, :default => 0 | ||
10 | + t.integer :number_of_producers, :default => 0 | ||
11 | + t.datetime :supply_start | ||
12 | + t.datetime :supply_end | ||
13 | + t.text :annotations | ||
14 | + t.references :bsc | ||
15 | + t.timestamps | ||
16 | + end | ||
17 | + end | ||
18 | + | ||
19 | + def self.down | ||
20 | + drop_table :bsc_plugin_contracts | ||
21 | + end | ||
22 | +end |
plugins/bsc/lib/bsc_plugin.rb
@@ -22,6 +22,7 @@ class BscPlugin < Noosfero::Plugin | @@ -22,6 +22,7 @@ class BscPlugin < Noosfero::Plugin | ||
22 | buttons = [] | 22 | buttons = [] |
23 | buttons << {:title => _("Manage associated enterprises"), :icon => 'bsc-enterprises', :url => {:controller => 'bsc_plugin_myprofile', :action => 'manage_associated_enterprises'}} if bsc?(context.profile) | 23 | buttons << {:title => _("Manage associated enterprises"), :icon => 'bsc-enterprises', :url => {:controller => 'bsc_plugin_myprofile', :action => 'manage_associated_enterprises'}} if bsc?(context.profile) |
24 | buttons << {:title => _('Transfer ownership'), :icon => 'transfer-enterprise-ownership', :url => {:controller => 'bsc_plugin_myprofile', :action => 'transfer_ownership'}} if context.profile.enterprise? | 24 | buttons << {:title => _('Transfer ownership'), :icon => 'transfer-enterprise-ownership', :url => {:controller => 'bsc_plugin_myprofile', :action => 'transfer_ownership'}} if context.profile.enterprise? |
25 | + buttons << {:title => _("Manage contracts"), :icon => '', :url => {:controller => 'bsc_plugin_myprofile', :action => 'manage_contracts'}} if bsc?(context.profile) | ||
25 | buttons | 26 | buttons |
26 | end | 27 | end |
27 | 28 |
plugins/bsc/lib/bsc_plugin/bsc.rb
@@ -3,6 +3,7 @@ class BscPlugin::Bsc < Enterprise | @@ -3,6 +3,7 @@ class BscPlugin::Bsc < Enterprise | ||
3 | has_many :enterprises | 3 | has_many :enterprises |
4 | has_many :enterprise_requests, :class_name => 'BscPlugin::AssociateEnterprise' | 4 | has_many :enterprise_requests, :class_name => 'BscPlugin::AssociateEnterprise' |
5 | has_many :products, :finder_sql => 'select * from products where enterprise_id in (#{enterprises.map(&:id).join(",")})' | 5 | has_many :products, :finder_sql => 'select * from products where enterprise_id in (#{enterprises.map(&:id).join(",")})' |
6 | + has_many :contracts, :class_name => 'BscPlugin::Contract' | ||
6 | 7 | ||
7 | validates_presence_of :nickname | 8 | validates_presence_of :nickname |
8 | validates_presence_of :company_name | 9 | validates_presence_of :company_name |
@@ -19,8 +20,8 @@ class BscPlugin::Bsc < Enterprise | @@ -19,8 +20,8 @@ class BscPlugin::Bsc < Enterprise | ||
19 | enterprise_requests.pending.map(&:enterprise).include?(enterprise) | 20 | enterprise_requests.pending.map(&:enterprise).include?(enterprise) |
20 | end | 21 | end |
21 | 22 | ||
22 | - def enterprises_to_json | ||
23 | - enterprises.map { |enterprise| {:id => enterprise.id, :name => enterprise.name} }.to_json | 23 | + def enterprises_to_token_input |
24 | + enterprises.map { |enterprise| {:id => enterprise.id, :name => enterprise.name} } | ||
24 | end | 25 | end |
25 | 26 | ||
26 | def control_panel_settings_button | 27 | def control_panel_settings_button |
@@ -0,0 +1,75 @@ | @@ -0,0 +1,75 @@ | ||
1 | +module BscPlugin::BscHelper | ||
2 | + include ActionView::Helpers::FormTagHelper | ||
3 | + | ||
4 | + def token_input_field_tag(name, element_id, search_action, options = {}, text_field_options = {}, html_options = {}) | ||
5 | + options[:min_chars] ||= 3 | ||
6 | + options[:hint_text] ||= _("Type in a search term") | ||
7 | + options[:no_results_text] ||= _("No results") | ||
8 | + options[:searching_text] ||= _("Searching...") | ||
9 | + options[:search_delay] ||= 1000 | ||
10 | + options[:prevent_duplicates] ||= true | ||
11 | + options[:backspace_delete_item] ||= false | ||
12 | + options[:focus] ||= false | ||
13 | + options[:avoid_enter] ||= true | ||
14 | + options[:on_result] ||= 'null' | ||
15 | + options[:on_add] ||= 'null' | ||
16 | + options[:on_delete] ||= 'null' | ||
17 | + options[:on_ready] ||= 'null' | ||
18 | + | ||
19 | + result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id}))) | ||
20 | + result += | ||
21 | + " | ||
22 | + <script type='text/javascript'> | ||
23 | + jQuery('##{element_id}') | ||
24 | + .tokenInput('#{url_for(search_action)}', { | ||
25 | + minChars: #{options[:min_chars].to_json}, | ||
26 | + prePopulate: #{options[:pre_populate].to_json}, | ||
27 | + hintText: #{options[:hint_text].to_json}, | ||
28 | + noResultsText: #{options[:no_results_text].to_json}, | ||
29 | + searchingText: #{options[:searching_text].to_json}, | ||
30 | + searchDelay: #{options[:serach_delay].to_json}, | ||
31 | + preventDuplicates: #{options[:prevent_duplicates].to_json}, | ||
32 | + backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, | ||
33 | + queryParam: #{name.to_json}, | ||
34 | + tokenLimit: #{options[:token_limit].to_json}, | ||
35 | + onResult: #{options[:on_result]}, | ||
36 | + onAdd: #{options[:on_add]}, | ||
37 | + onDelete: #{options[:on_delete]}, | ||
38 | + onReady: #{options[:on_ready]}, | ||
39 | + }) | ||
40 | + " | ||
41 | + result += options[:focus] ? ".focus();" : ";" | ||
42 | + if options[:avoid_enter] | ||
43 | + result += "jQuery('#token-input-#{element_id}') | ||
44 | + .live('keydown', function(event){ | ||
45 | + if(event.keyCode == '13') return false; | ||
46 | + });" | ||
47 | + end | ||
48 | + result += "</script>" | ||
49 | + result | ||
50 | + end | ||
51 | + | ||
52 | + def product_display_name(product) | ||
53 | + "#{product.name} (#{product.enterprise.name})" | ||
54 | + end | ||
55 | + | ||
56 | + def display_text_field(name, value, options={:display_nil => false, :nil_symbol => '---'}) | ||
57 | + value = value.to_s | ||
58 | + if !value.blank? || options[:display_nil] | ||
59 | + value = value.blank? ? options[:nil_symbol] : value | ||
60 | + content_tag('tr', content_tag('td', name+': ', :class => 'bsc-field-label') + content_tag('td', value, :class => 'bsc-field-value')) | ||
61 | + end | ||
62 | + end | ||
63 | + | ||
64 | + def display_list_field(list, options={:nil_symbol => '---'}) | ||
65 | + list.map do |item| | ||
66 | + item = item.blank? ? options[:nil_symbol] : item | ||
67 | + content_tag('tr', content_tag('td', item, :class => 'bsc-field-value')) | ||
68 | + end.join | ||
69 | + end | ||
70 | + | ||
71 | + def short_text(name, chars = 40) | ||
72 | + truncate name, chars, '...' | ||
73 | + end | ||
74 | + | ||
75 | +end |
@@ -0,0 +1,84 @@ | @@ -0,0 +1,84 @@ | ||
1 | +class BscPlugin::Contract < Noosfero::Plugin::ActiveRecord | ||
2 | + validates_presence_of :bsc, :client_name | ||
3 | + | ||
4 | + has_many :sales, :class_name => 'BscPlugin::Sale' | ||
5 | + has_many :products, :through => :sales | ||
6 | + has_and_belongs_to_many :enterprises, :join_table => 'bsc_plugin_contracts_enterprises' | ||
7 | + | ||
8 | + belongs_to :bsc, :class_name => 'BscPlugin::Bsc' | ||
9 | + | ||
10 | + named_scope :status, lambda { |status_list| status_list.blank? ? {} : {:conditions => ['status in (?)', status_list]} } | ||
11 | + named_scope :sorted_by, lambda { |sorter, direction| {:order => "#{sorter} #{direction}"} } | ||
12 | + | ||
13 | + before_create do |contract| | ||
14 | + contract.created_at ||= Time.now.utc | ||
15 | + contract.updated_at ||= Time.now.utc | ||
16 | + end | ||
17 | + | ||
18 | + before_update do |contract| | ||
19 | + contract.updated_at ||= Time.now.utc | ||
20 | + end | ||
21 | + | ||
22 | + module Status | ||
23 | + OPENED = 0 | ||
24 | + NEGOTIATING = 1 | ||
25 | + EXECUTING = 2 | ||
26 | + CLOSED = 3 | ||
27 | + | ||
28 | + def self.types | ||
29 | + [OPENED, NEGOTIATING, EXECUTING, CLOSED] | ||
30 | + end | ||
31 | + | ||
32 | + def self.names | ||
33 | + [_('Opened'), _('Negotiating'), _('Executing'), _('Closed')] | ||
34 | + end | ||
35 | + end | ||
36 | + | ||
37 | + module ClientType | ||
38 | + STATE = 0 | ||
39 | + FEDERAL = 1 | ||
40 | + | ||
41 | + def self.types | ||
42 | + [STATE, FEDERAL] | ||
43 | + end | ||
44 | + | ||
45 | + def self.names | ||
46 | + [_('State'), _('Federal')] | ||
47 | + end | ||
48 | + end | ||
49 | + | ||
50 | + module BusinessType | ||
51 | + PROJECTA = 0 | ||
52 | + PROJECTB = 1 | ||
53 | + | ||
54 | + def self.types | ||
55 | + [PROJECTA, PROJECTB] | ||
56 | + end | ||
57 | + | ||
58 | + def self.names | ||
59 | + [_('ProjectA'), _('ProjectB')] | ||
60 | + end | ||
61 | + end | ||
62 | + | ||
63 | + def enterprises_to_token_input | ||
64 | + enterprises.map { |enterprise| {:id => enterprise.id, :name => enterprise.name} } | ||
65 | + end | ||
66 | + | ||
67 | + def save_sales(sales) | ||
68 | + failed_sales = {} | ||
69 | + sales.each do |sale| | ||
70 | + sale.merge!({:contract_id => id}) | ||
71 | + begin | ||
72 | + BscPlugin::Sale.create!(sale) | ||
73 | + rescue Exception => exception | ||
74 | + name = Product.find(sale[:product_id]).name | ||
75 | + failed_sales[exception.clean_message] ? failed_sales[exception.clean_message] << name : failed_sales[exception.clean_message] = [name] | ||
76 | + end | ||
77 | + end | ||
78 | + failed_sales | ||
79 | + end | ||
80 | + | ||
81 | + def total_price | ||
82 | + sales.inject(0) {|result, sale| sale.price*sale.quantity + result} | ||
83 | + end | ||
84 | +end |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +class BscPlugin::Sale < Noosfero::Plugin::ActiveRecord | ||
2 | + validates_presence_of :product, :contract | ||
3 | + validates_uniqueness_of :product_id, :scope => :contract_id | ||
4 | + validates_numericality_of :quantity, :only_integer => true, :greater_than_or_equal_to => 0 | ||
5 | + validates_numericality_of :price, :allow_nil => true | ||
6 | + | ||
7 | + belongs_to :product | ||
8 | + belongs_to :contract, :class_name => 'BscPlugin::Contract' | ||
9 | + | ||
10 | + before_create do |sale| | ||
11 | + sale.price ||= sale.product.price || 0 | ||
12 | + sale.created_at ||= Time.now.utc | ||
13 | + sale.updated_at ||= Time.now.utc | ||
14 | + end | ||
15 | + | ||
16 | + before_update do |contract| | ||
17 | + contract.updated_at ||= Time.now.utc | ||
18 | + end | ||
19 | +end |
plugins/bsc/lib/ext/enterprise.rb
@@ -2,6 +2,8 @@ require_dependency 'enterprise' | @@ -2,6 +2,8 @@ require_dependency 'enterprise' | ||
2 | 2 | ||
3 | class Enterprise | 3 | class Enterprise |
4 | belongs_to :bsc, :class_name => 'BscPlugin::Bsc' | 4 | belongs_to :bsc, :class_name => 'BscPlugin::Bsc' |
5 | + has_and_belongs_to_many :contracts, :class_name => 'BscPlugin::Contract', :join_table => 'bsc_plugin_contracts_enterprises' | ||
6 | + | ||
5 | FIELDS << 'bsc_id' | 7 | FIELDS << 'bsc_id' |
6 | FIELDS << 'enabled' | 8 | FIELDS << 'enabled' |
7 | FIELDS << 'validated' | 9 | FIELDS << 'validated' |
plugins/bsc/lib/ext/product.rb
1 | require_dependency 'product' | 1 | require_dependency 'product' |
2 | 2 | ||
3 | class Product | 3 | class Product |
4 | + | ||
5 | + has_many :sales, :class_name => 'BscPlugin::Sale' | ||
6 | + has_many :contracts, :through => :sales, :class_name => 'BscPlugin::Contract' | ||
7 | + | ||
4 | def bsc | 8 | def bsc |
5 | enterprise.bsc if enterprise | 9 | enterprise.bsc if enterprise |
6 | end | 10 | end |
@@ -0,0 +1,86 @@ | @@ -0,0 +1,86 @@ | ||
1 | +var BSCContracts = {}; | ||
2 | + | ||
3 | +(function($){ | ||
4 | + BSCContracts.onDelete = function(item){ | ||
5 | + $('.token-input-dropdown').hide(); | ||
6 | + $('#bsc-plugin-row-'+item.sale_id.toString()).remove(); | ||
7 | + BSCContracts.updateTotal(); | ||
8 | + }; | ||
9 | + | ||
10 | + BSCContracts.onAdd = function(item){ | ||
11 | + var quantity = $('#bsc-plugin-sale-'+item.sale_id.toString()+'-quantity'); | ||
12 | + var price = $('#bsc-plugin-sale-'+item.sale_id.toString()+'-price'); | ||
13 | + quantity.addClass('required'); | ||
14 | + price.addClass('required'); | ||
15 | + quantity.val(1); | ||
16 | + price.val(item.product_price); | ||
17 | + BSCContracts.updateTotal(); | ||
18 | + }; | ||
19 | + | ||
20 | + BSCContracts.newID = function(){ | ||
21 | + if ( !this.idNum ) this.idNum = 0; | ||
22 | + return this.idNum++; | ||
23 | + }; | ||
24 | + | ||
25 | + BSCContracts.newProductLine = function(item){ | ||
26 | + var id = this.newID(); | ||
27 | + var tr = $('<tr class="bsc-plugin-sales-product" id="bsc-plugin-row-'+id+'"></tr>'); | ||
28 | + var tds = $('<td></td><td></td><td>'+this.currencyUnit+'</td>').appendTo(tr); | ||
29 | + var input = $('<input name="sales['+id+'][product_id]" class="search-product-field"/>').appendTo(tds[0]); | ||
30 | + var searchUrl = this.searchUrl | ||
31 | + .replace('ENTERPRISES', $('#involved-enterprises').val()) | ||
32 | + .replace('SALE_ID', id) | ||
33 | + .replace('ADDED_PRODUCTS', $.map($('.search-product-field'), function(item){return item.value}).join(',')); | ||
34 | + var prePopulation = []; | ||
35 | + var quantity = ''; | ||
36 | + var price = ''; | ||
37 | + var required = ''; | ||
38 | + if(item) { | ||
39 | + item.sale_id = id; | ||
40 | + prePopulation = [item]; | ||
41 | + quantity = item.quantity; | ||
42 | + price = item.product_price; | ||
43 | + required = 'required'; | ||
44 | + } | ||
45 | + var opts = $.extend( { prePopulate: prePopulation, queryParam: input[0].name }, this.tokenInputOptions ); | ||
46 | + | ||
47 | + input.keydown(function(event){ if(event.keyCode == '13') return false }) | ||
48 | + .tokenInput(searchUrl, opts); | ||
49 | + $('#bsc-plugin-contract-total-row').before(tr); | ||
50 | + $('<input id="bsc-plugin-sale-'+id+'-quantity" class="bsc-plugin-sales-quantity '+required+' digits" name="sales['+id+'][quantity]" align="center" size="8" value="'+quantity+'"/>').appendTo(tds[1]); | ||
51 | + $('<input id="bsc-plugin-sale-'+id+'-price" class="bsc-plugin-sales-price '+required+' number" name="sales['+id+'][price]" value="'+price+'"/>').appendTo(tds[2]); | ||
52 | + }; | ||
53 | + | ||
54 | + BSCContracts.prePopulate = function(items){ | ||
55 | + $(items).each(function(index, item){BSCContracts.newProductLine(item)}); | ||
56 | + } | ||
57 | + | ||
58 | + BSCContracts.updateTotal = function(){ | ||
59 | + var total = 0; | ||
60 | + var quantity = 0; | ||
61 | + var price = 0; | ||
62 | + $('.bsc-plugin-sales-product').each(function(index){ | ||
63 | + quantity = $('#' + $(this).attr('id') + " .bsc-plugin-sales-quantity").val(); | ||
64 | + price = $('#'+$(this).attr('id') + " .bsc-plugin-sales-price").val(); | ||
65 | + total += quantity*price; | ||
66 | + }); | ||
67 | + $('#bsc-plugin-sales-total-value').text(BSCContracts.currencyUnit+' '+total); | ||
68 | + } | ||
69 | + | ||
70 | + $(".bsc-plugin-sales-price, .bsc-plugin-sales-quantity").live('change', function(e){ | ||
71 | + BSCContracts.updateTotal(); | ||
72 | + }); | ||
73 | + | ||
74 | + $("#bsc-plugin-add-new-product").click(function(){ | ||
75 | + var last = $('.search-product-field:last'); | ||
76 | + if(!last.val() && last.size() != 0){ | ||
77 | + last.focus(); | ||
78 | + return false; | ||
79 | + } | ||
80 | + var next_id = parseInt(last.attr('data-sale-id'))+1; | ||
81 | + var enterprises = $('#involved-enterprises').val().replace(/,/g,'-'); | ||
82 | + BSCContracts.newProductLine(); | ||
83 | + return false; | ||
84 | + }); | ||
85 | + | ||
86 | +})(jQuery); |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +var dates = jQuery( "#from, #to" ).datepicker({ | ||
2 | + defaultDate: "+1w", | ||
3 | + changeMonth: true, | ||
4 | + dateFormat: 'yy-mm-dd', | ||
5 | + onSelect: function( selectedDate ) { | ||
6 | + var option = this.id == "from" ? "minDate" : "maxDate", | ||
7 | + instance = jQuery( this ).data( "datepicker" ), | ||
8 | + date = jQuery.datepicker.parseDate( | ||
9 | + instance.settings.dateFormat || | ||
10 | + jQuery.datepicker._defaults.dateFormat, | ||
11 | + selectedDate, instance.settings ); | ||
12 | + dates.not( this ).datepicker( "option", option, date ); | ||
13 | + } | ||
14 | +}); |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +Subproject commit bd879003043b4a93b78cbd4a582b6e0650900bcb |
plugins/bsc/public/style.css
1 | +@import url(jquery.ui.spinner/ui.spinner.css); | ||
2 | + | ||
1 | .controller-profile_editor a.control-panel-bsc-enterprises {background-image: url(images/manage-bsc-enterprises.png)} | 3 | .controller-profile_editor a.control-panel-bsc-enterprises {background-image: url(images/manage-bsc-enterprises.png)} |
2 | .controller-profile_editor .msie6 a.control-panel-bsc-enterprises {background-image: url(images/manage-bsc-enterprises.gif)} | 4 | .controller-profile_editor .msie6 a.control-panel-bsc-enterprises {background-image: url(images/manage-bsc-enterprises.gif)} |
3 | 5 | ||
4 | .controller-profile_editor a.control-panel-transfer-enterprise-ownership {background-image: url(images/transfer-ownership.png)} | 6 | .controller-profile_editor a.control-panel-transfer-enterprise-ownership {background-image: url(images/transfer-ownership.png)} |
5 | 7 | ||
8 | +.ui-spinner-up{ | ||
9 | + height: 6.5px !important; | ||
10 | +} | ||
11 | + | ||
12 | +.ui-spinner-down{ | ||
13 | + height: 8.5px !important; | ||
14 | +} | ||
15 | + | ||
16 | +.ui-icon-triangle-1-n { | ||
17 | + margin-top: -4px !important; | ||
18 | +} | ||
19 | + | ||
20 | +.ui-icon-triangle-1-s { | ||
21 | + margin-left: -1px !important; | ||
22 | + margin-top: -3.5px !important; | ||
23 | +} | ||
24 | + | ||
6 | .icon-menu-bsc { | 25 | .icon-menu-bsc { |
7 | background-image: url(images/manage-bsc-enterprises-icon.png); | 26 | background-image: url(images/manage-bsc-enterprises-icon.png); |
8 | } | 27 | } |
@@ -10,3 +29,154 @@ | @@ -10,3 +29,154 @@ | ||
10 | #content .token-input-list { | 29 | #content .token-input-list { |
11 | margin-bottom: 30px; | 30 | margin-bottom: 30px; |
12 | } | 31 | } |
32 | + | ||
33 | +#bsc-plugin-sorter { | ||
34 | + text-align: right; | ||
35 | + margin: 3px 0px; | ||
36 | +} | ||
37 | + | ||
38 | +#bsc-plugin-sales-table th, | ||
39 | +#bsc-plugin-sales-table td { | ||
40 | + border: 1px solid #000; | ||
41 | + border-collapse: collapse; | ||
42 | + padding: 0px | ||
43 | +} | ||
44 | + | ||
45 | +#content #bsc-plugin-sales-table td .token-input-list{ | ||
46 | + margin-bottom: 0px; | ||
47 | +} | ||
48 | + | ||
49 | +#bsc-plugin-sales-table { | ||
50 | + border: 1px solid #000; | ||
51 | + border-collapse: collapse; | ||
52 | +} | ||
53 | + | ||
54 | +#bsc-plugin-sales-table th { | ||
55 | + background-color: #cdcdcd; | ||
56 | + padding: 0px 10px; | ||
57 | +} | ||
58 | + | ||
59 | +.alternate-colors tr:nth-child(odd), | ||
60 | +.alternate-colors tr:nth-child(odd):hover td { | ||
61 | + background-color: #f4f4f4; | ||
62 | +} | ||
63 | + | ||
64 | +.alternate-colors tr:nth-child(even), | ||
65 | +.alternate-colors tr:nth-child(even):hover td { | ||
66 | + background-color: #fff; | ||
67 | +} | ||
68 | + | ||
69 | +#bsc-plugin-sales-table input.error{ | ||
70 | + background-color: #F8DBDD; | ||
71 | + border: 1px solid #f5697c; | ||
72 | + margin-left: 2px; | ||
73 | +} | ||
74 | + | ||
75 | +.bsc-plugin-sales-price { | ||
76 | + width: 75%; | ||
77 | +} | ||
78 | + | ||
79 | +.bsc-plugin-sales-products-column { | ||
80 | + width: 70%; | ||
81 | +} | ||
82 | + | ||
83 | +.bsc-plugin-sales-quantity-column { | ||
84 | + width: 10%; | ||
85 | + text-align: center; | ||
86 | +} | ||
87 | + | ||
88 | +.bsc-plugin-sales-price-column { | ||
89 | + width: 18%; | ||
90 | +} | ||
91 | + | ||
92 | +#bsc-plugin-sales-add-new-row { | ||
93 | + padding: 0px 10px; | ||
94 | +} | ||
95 | + | ||
96 | +#bsc-plugin-manage-contracts-table a { | ||
97 | + color: #555753; | ||
98 | +} | ||
99 | + | ||
100 | +#bsc-plugin-manage-contracts-table { | ||
101 | + border:none; | ||
102 | +} | ||
103 | +#bsc-plugin-manage-contracts-table td { | ||
104 | + padding: 5px 10px; | ||
105 | +} | ||
106 | + | ||
107 | +#bsc-plugin-manage-contracts-table td.links { | ||
108 | + text-align: right; | ||
109 | +} | ||
110 | + | ||
111 | +#bsc-plugin-contracts-filter { | ||
112 | + float: left; | ||
113 | + width: 20%; | ||
114 | + height: 100%; | ||
115 | +} | ||
116 | + | ||
117 | + | ||
118 | +#bsc-plugin-contracts-results { | ||
119 | + float: left; | ||
120 | + width: 80%; | ||
121 | +} | ||
122 | + | ||
123 | +#bsc-plugin-contract-total-string, | ||
124 | +#bsc-plugin-contract-total { | ||
125 | + text-align: right; | ||
126 | +} | ||
127 | + | ||
128 | +.bsc-fields-table { | ||
129 | + border: collapse; | ||
130 | + width: 49%; | ||
131 | +} | ||
132 | + | ||
133 | +.bsc-fields-table th{ | ||
134 | + font-size: 14px; | ||
135 | + padding: 0px; | ||
136 | +} | ||
137 | + | ||
138 | +.bsc-fields-table td { | ||
139 | + border: none; | ||
140 | + padding: 0px; | ||
141 | +} | ||
142 | + | ||
143 | +.bsc-fields-table tr:hover td { | ||
144 | + background-color: transparent; | ||
145 | +} | ||
146 | + | ||
147 | +.bsc-field-label { | ||
148 | + font-weight: bold; | ||
149 | +} | ||
150 | + | ||
151 | +.bsc-full-table { | ||
152 | + margin: 3px 0px; | ||
153 | +} | ||
154 | + | ||
155 | +.bsc-plugin-view-contract { | ||
156 | + margin-top: 10px; | ||
157 | +} | ||
158 | + | ||
159 | +.bsc-plugin-view-contract td { | ||
160 | + padding: 2px 10px !important; | ||
161 | +} | ||
162 | + | ||
163 | +.bsc-plugin-total { | ||
164 | + font-weight: bold; | ||
165 | +} | ||
166 | + | ||
167 | +.bsc-plugin-annotation { | ||
168 | + background-color: #eeeeec; | ||
169 | + margin: 10px 0px; | ||
170 | + padding: 5px 10px; | ||
171 | + border-radius: 5px; | ||
172 | +} | ||
173 | + | ||
174 | +.bsc-plugin-annotation-title { | ||
175 | + font-weight: bold; | ||
176 | + font-size: 15px; | ||
177 | + margin-bottom: 5px; | ||
178 | +} | ||
179 | + | ||
180 | +.bsc-plugin-annotation-content { | ||
181 | + font-style: italic; | ||
182 | +} |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +Feature: Bsc contract | ||
2 | +As a Bsc admin | ||
3 | +I would like to register a contract | ||
4 | +In order to make negotiations | ||
5 | + | ||
6 | + Background: | ||
7 | + Given "Bsc" plugin is enabled | ||
8 | + And the folllowing "bsc" from "bsc_plugin" | ||
9 | + | business_name | identifier | company_name | cnpj | | ||
10 | + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | | ||
11 | + And I am logged in as admin | ||
12 | + | ||
13 | + Scenario: be able see the manage contracts button only if the profile is a Bsc | ||
14 | + Given the following community | ||
15 | + | name | identifier | | ||
16 | + | Sample Community | sample-community | | ||
17 | + When I am on Sample Community's control panel | ||
18 | + Then I should not see "Manage contracts" | ||
19 | + But I am on Bsc Test's control panel | ||
20 | + Then I should see "Manage contracts" | ||
21 | + |
plugins/bsc/test/functional/bsc_plugin_myprofile_controller_test.rb
@@ -40,7 +40,7 @@ class BscPluginMyprofileControllerTest < Test::Unit::TestCase | @@ -40,7 +40,7 @@ class BscPluginMyprofileControllerTest < Test::Unit::TestCase | ||
40 | e6 = Enterprise.create!(:name => 'Bla', :identifier => 'sample-enterprise-6') | 40 | e6 = Enterprise.create!(:name => 'Bla', :identifier => 'sample-enterprise-6') |
41 | 41 | ||
42 | get :search_enterprise, :profile => bsc.identifier, :q => 'sampl' | 42 | get :search_enterprise, :profile => bsc.identifier, :q => 'sampl' |
43 | - | 43 | + |
44 | assert_match /#{e1.name}/, @response.body | 44 | assert_match /#{e1.name}/, @response.body |
45 | assert_match /#{e2.name}/, @response.body | 45 | assert_match /#{e2.name}/, @response.body |
46 | assert_no_match /#{e3.name}/, @response.body | 46 | assert_no_match /#{e3.name}/, @response.body |
@@ -108,5 +108,204 @@ class BscPluginMyprofileControllerTest < Test::Unit::TestCase | @@ -108,5 +108,204 @@ class BscPluginMyprofileControllerTest < Test::Unit::TestCase | ||
108 | assert_equal enterprise.bsc, bsc | 108 | assert_equal enterprise.bsc, bsc |
109 | end | 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 | end | 310 | end |
112 | 311 |
plugins/bsc/test/unit/bsc_plugin/bsc_test.rb
@@ -5,6 +5,12 @@ require File.dirname(__FILE__) + '/../../../lib/ext/enterprise' | @@ -5,6 +5,12 @@ require File.dirname(__FILE__) + '/../../../lib/ext/enterprise' | ||
5 | class BscPlugin::BscTest < Test::Unit::TestCase | 5 | class BscPlugin::BscTest < Test::Unit::TestCase |
6 | VALID_CNPJ = '94.132.024/0001-48' | 6 | VALID_CNPJ = '94.132.024/0001-48' |
7 | 7 | ||
8 | + def setup | ||
9 | + @bsc = BscPlugin::Bsc.create!(:business_name => 'Sample Bsc', :company_name => 'Sample Bsc', :identifier => 'sample-bsc', :cnpj => VALID_CNPJ) | ||
10 | + end | ||
11 | + | ||
12 | + attr_accessor :bsc | ||
13 | + | ||
8 | should 'validate presence of cnpj' do | 14 | should 'validate presence of cnpj' do |
9 | bsc = BscPlugin::Bsc.new() | 15 | bsc = BscPlugin::Bsc.new() |
10 | bsc.valid? | 16 | bsc.valid? |
@@ -13,7 +19,7 @@ class BscPlugin::BscTest < Test::Unit::TestCase | @@ -13,7 +19,7 @@ class BscPlugin::BscTest < Test::Unit::TestCase | ||
13 | end | 19 | end |
14 | 20 | ||
15 | should 'validate uniqueness of cnpj' do | 21 | should 'validate uniqueness of cnpj' do |
16 | - bsc1 = BscPlugin::Bsc.create!({:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}) | 22 | + bsc1 = bsc |
17 | bsc2 = BscPlugin::Bsc.new(:cnpj => VALID_CNPJ) | 23 | bsc2 = BscPlugin::Bsc.new(:cnpj => VALID_CNPJ) |
18 | bsc2.valid? | 24 | bsc2.valid? |
19 | assert bsc2.errors.invalid?(:cnpj) | 25 | assert bsc2.errors.invalid?(:cnpj) |
@@ -22,7 +28,6 @@ class BscPlugin::BscTest < Test::Unit::TestCase | @@ -22,7 +28,6 @@ class BscPlugin::BscTest < Test::Unit::TestCase | ||
22 | should 'have many enterprises' do | 28 | should 'have many enterprises' do |
23 | e1 = Enterprise.new(:name => 'Enterprise1', :identifier => 'enterprise1') | 29 | e1 = Enterprise.new(:name => 'Enterprise1', :identifier => 'enterprise1') |
24 | e2 = Enterprise.new(:name => 'Enterprise2', :identifier => 'enterprise2') | 30 | e2 = Enterprise.new(:name => 'Enterprise2', :identifier => 'enterprise2') |
25 | - bsc = BscPlugin::Bsc.new(:business_name => 'Sample Bsc', :company_name => 'Sample Bsc Ltda.', :identifier => 'sample-bsc', :cnpj => VALID_CNPJ) | ||
26 | bsc.enterprises << e1 | 31 | bsc.enterprises << e1 |
27 | bsc.enterprises << e2 | 32 | bsc.enterprises << e2 |
28 | bsc.save! | 33 | bsc.save! |
@@ -34,7 +39,6 @@ class BscPlugin::BscTest < Test::Unit::TestCase | @@ -34,7 +39,6 @@ class BscPlugin::BscTest < Test::Unit::TestCase | ||
34 | should 'verify already requested enterprises' do | 39 | should 'verify already requested enterprises' do |
35 | e1 = fast_create(Enterprise) | 40 | e1 = fast_create(Enterprise) |
36 | e2 = fast_create(Enterprise) | 41 | e2 = fast_create(Enterprise) |
37 | - bsc = BscPlugin::Bsc.new() | ||
38 | task = BscPlugin::AssociateEnterprise.new(:target => e1, :bsc => bsc) | 42 | task = BscPlugin::AssociateEnterprise.new(:target => e1, :bsc => bsc) |
39 | bsc.enterprise_requests.stubs(:pending).returns([task]) | 43 | bsc.enterprise_requests.stubs(:pending).returns([task]) |
40 | 44 | ||
@@ -46,7 +50,6 @@ class BscPlugin::BscTest < Test::Unit::TestCase | @@ -46,7 +50,6 @@ class BscPlugin::BscTest < Test::Unit::TestCase | ||
46 | e1 = fast_create(Enterprise) | 50 | e1 = fast_create(Enterprise) |
47 | e2 = fast_create(Enterprise) | 51 | e2 = fast_create(Enterprise) |
48 | category = fast_create(ProductCategory) | 52 | category = fast_create(ProductCategory) |
49 | - bsc = BscPlugin::Bsc.create!({:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}) | ||
50 | 53 | ||
51 | p1 = fast_create(Product, :product_category_id => category.id) | 54 | p1 = fast_create(Product, :product_category_id => category.id) |
52 | p2 = fast_create(Product, :product_category_id => category.id) | 55 | p2 = fast_create(Product, :product_category_id => category.id) |
@@ -67,8 +70,15 @@ class BscPlugin::BscTest < Test::Unit::TestCase | @@ -67,8 +70,15 @@ class BscPlugin::BscTest < Test::Unit::TestCase | ||
67 | end | 70 | end |
68 | 71 | ||
69 | should 'not be able to create product' do | 72 | should 'not be able to create product' do |
70 | - bsc = BscPlugin::Bsc.new | ||
71 | assert !bsc.create_product? | 73 | assert !bsc.create_product? |
72 | end | 74 | end |
73 | 75 | ||
76 | + should 'have many contracts' do | ||
77 | + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin') | ||
78 | + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin') | ||
79 | + | ||
80 | + assert_includes bsc.contracts, contract1 | ||
81 | + assert_includes bsc.contracts, contract2 | ||
82 | + end | ||
83 | + | ||
74 | end | 84 | end |
@@ -0,0 +1,109 @@ | @@ -0,0 +1,109 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | +#require File.dirname(__FILE__) + '/../../../../../app/models/uploaded_file' | ||
3 | +#require File.dirname(__FILE__) + '/../../../lib/ext/enterprise' | ||
4 | + | ||
5 | +class BscPlugin::ContractTest < Test::Unit::TestCase | ||
6 | + def setup | ||
7 | + @contract = BscPlugin::Contract.new(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
8 | + end | ||
9 | + | ||
10 | + attr_accessor :contract | ||
11 | + | ||
12 | + should 'validates presence of bsc' do | ||
13 | + contract.bsc = nil | ||
14 | + contract.valid? | ||
15 | + assert contract.errors.invalid?(:bsc) | ||
16 | + | ||
17 | + contract.bsc = BscPlugin::Bsc.new | ||
18 | + contract.valid? | ||
19 | + assert !contract.errors.invalid?(:bsc) | ||
20 | + end | ||
21 | + | ||
22 | + should 'associate contract with products through sales' do | ||
23 | + contract.save! | ||
24 | + product1 = fast_create(Product) | ||
25 | + product2 = fast_create(Product) | ||
26 | + sale1 = BscPlugin::Sale.create!(:product => product1, :contract => contract, :quantity => 3) | ||
27 | + sale2 = BscPlugin::Sale.create!(:product => product2, :contract => contract, :quantity => 5) | ||
28 | + | ||
29 | + assert_includes contract.products, product1 | ||
30 | + assert_includes contract.products, product2 | ||
31 | + end | ||
32 | + | ||
33 | + should 'have many enterprises' do | ||
34 | + contract.save! | ||
35 | + enterprise1 = fast_create(Enterprise) | ||
36 | + contract.enterprises << enterprise1 | ||
37 | + enterprise2 = fast_create(Enterprise) | ||
38 | + contract.enterprises << enterprise2 | ||
39 | + | ||
40 | + assert_includes contract.enterprises, enterprise1 | ||
41 | + assert_includes contract.enterprises, enterprise2 | ||
42 | + end | ||
43 | + | ||
44 | + should 'filter contracts by status' do | ||
45 | + bsc = BscPlugin::Bsc.new | ||
46 | + opened = BscPlugin::Contract::Status::OPENED | ||
47 | + negotiating = BscPlugin::Contract::Status::NEGOTIATING | ||
48 | + executing = BscPlugin::Contract::Status::EXECUTING | ||
49 | + closed = BscPlugin::Contract::Status::CLOSED | ||
50 | + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :status => opened, :client_name => 'Marvin') | ||
51 | + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :status => negotiating, :client_name => 'Marvin') | ||
52 | + contract3 = BscPlugin::Contract.create!(:bsc => bsc, :status => executing, :client_name => 'Marvin') | ||
53 | + contract4 = BscPlugin::Contract.create!(:bsc => bsc, :status => closed, :client_name => 'Marvin') | ||
54 | + | ||
55 | + opened_and_executing = BscPlugin::Contract.status([opened, executing]) | ||
56 | + negotiating_and_closed = BscPlugin::Contract.status([negotiating, closed]) | ||
57 | + all = BscPlugin::Contract.status([]) | ||
58 | + | ||
59 | + assert_includes opened_and_executing, contract1 | ||
60 | + assert_not_includes opened_and_executing, contract2 | ||
61 | + assert_includes opened_and_executing, contract3 | ||
62 | + assert_not_includes opened_and_executing, contract4 | ||
63 | + | ||
64 | + assert_not_includes negotiating_and_closed, contract1 | ||
65 | + assert_includes negotiating_and_closed, contract2 | ||
66 | + assert_not_includes negotiating_and_closed, contract3 | ||
67 | + assert_includes negotiating_and_closed, contract4 | ||
68 | + | ||
69 | + assert_includes all, contract1 | ||
70 | + assert_includes all, contract2 | ||
71 | + assert_includes all, contract3 | ||
72 | + assert_includes all, contract4 | ||
73 | + end | ||
74 | + | ||
75 | + should 'sort contracts by date' do | ||
76 | + bsc = BscPlugin::Bsc.new | ||
77 | + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :created_at => 2.day.ago, :client_name => 'Marvin') | ||
78 | + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :created_at => 1.day.ago, :client_name => 'Marvin') | ||
79 | + contract3 = BscPlugin::Contract.create!(:bsc => bsc, :created_at => 3.day.ago, :client_name => 'Marvin') | ||
80 | + | ||
81 | + assert_equal [contract3, contract1, contract2], BscPlugin::Contract.sorted_by('created_at', 'asc') | ||
82 | + end | ||
83 | + | ||
84 | + should 'sort contracts by client name' do | ||
85 | + bsc = BscPlugin::Bsc.new | ||
86 | + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvim') | ||
87 | + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Adam') | ||
88 | + contract3 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Eva') | ||
89 | + | ||
90 | + assert_equal [contract2, contract3, contract1], BscPlugin::Contract.sorted_by('client_name', 'asc') | ||
91 | + end | ||
92 | + | ||
93 | + should 'return contract total price' do | ||
94 | + contract.save! | ||
95 | + price1 = 1 | ||
96 | + quantity1 = 3 | ||
97 | + price2 = 2 | ||
98 | + quantity2 = 5 | ||
99 | + total = price1*quantity1 + price2*quantity2 | ||
100 | + product1 = fast_create(Product, :price => price1) | ||
101 | + product2 = fast_create(Product, :price => price2) | ||
102 | + sale1 = BscPlugin::Sale.create!(:product => product1, :contract => contract, :quantity => quantity1) | ||
103 | + sale2 = BscPlugin::Sale.create!(:product => product2, :contract => contract, :quantity => quantity2) | ||
104 | + | ||
105 | + contract.reload | ||
106 | + | ||
107 | + assert_equal total, contract.total_price | ||
108 | + end | ||
109 | +end |
plugins/bsc/test/unit/bsc_plugin/enterprise_test.rb
@@ -1,26 +0,0 @@ | @@ -1,26 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | -require File.dirname(__FILE__) + '/../../../../../app/models/uploaded_file' | ||
3 | -require File.dirname(__FILE__) + '/../../../../../app/models/enterprise' | ||
4 | -require File.dirname(__FILE__) + '/../../../lib/ext/enterprise' | ||
5 | - | ||
6 | -class ProductTest < Test::Unit::TestCase | ||
7 | - VALID_CNPJ = '94.132.024/0001-48' | ||
8 | - | ||
9 | - should 'belongs to a bsc' do | ||
10 | - bsc = BscPlugin::Bsc.create!({:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}) | ||
11 | - enterprise = fast_create(Enterprise, :bsc_id => bsc.id) | ||
12 | - | ||
13 | - assert_equal bsc, enterprise.bsc | ||
14 | - end | ||
15 | - | ||
16 | - should 'return correct enterprises on validated and not validated namedscopes' do | ||
17 | - validated_enterprise = fast_create(Enterprise, :validated => true) | ||
18 | - not_validated_enterprise = fast_create(Enterprise, :validated => false) | ||
19 | - | ||
20 | - assert_includes Enterprise.validated, validated_enterprise | ||
21 | - assert_not_includes Enterprise.validated, not_validated_enterprise | ||
22 | - assert_not_includes Enterprise.not_validated, validated_enterprise | ||
23 | - assert_includes Enterprise.not_validated, not_validated_enterprise | ||
24 | - end | ||
25 | -end | ||
26 | - |
plugins/bsc/test/unit/bsc_plugin/product_test.rb
@@ -1,14 +0,0 @@ | @@ -1,14 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | -require File.dirname(__FILE__) + '/../../../../../app/models/uploaded_file' | ||
3 | - | ||
4 | -class ProductTest < Test::Unit::TestCase | ||
5 | - VALID_CNPJ = '94.132.024/0001-48' | ||
6 | - | ||
7 | - should 'return have bsc' do | ||
8 | - bsc = BscPlugin::Bsc.create!({:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}) | ||
9 | - enterprise = fast_create(Enterprise, :bsc_id => bsc.id) | ||
10 | - product = fast_create(Product, :enterprise_id => enterprise.id) | ||
11 | - | ||
12 | - assert_equal bsc, product.bsc | ||
13 | - end | ||
14 | -end |
@@ -0,0 +1,86 @@ | @@ -0,0 +1,86 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | + | ||
3 | +class BscPlugin::SaleTest < Test::Unit::TestCase | ||
4 | + def setup | ||
5 | + @sale = BscPlugin::Sale.new | ||
6 | + end | ||
7 | + | ||
8 | + attr_accessor :sale | ||
9 | + | ||
10 | + should 'validate presence of product and contract' do | ||
11 | + sale.valid? | ||
12 | + | ||
13 | + assert sale.errors.invalid?(:product) | ||
14 | + assert sale.errors.invalid?(:contract) | ||
15 | + | ||
16 | + product = Product.new | ||
17 | + contract = BscPlugin::Contract.new | ||
18 | + sale.product = product | ||
19 | + sale.contract = contract | ||
20 | + | ||
21 | + assert !sale.errors.invalid?(product) | ||
22 | + assert !sale.errors.invalid?(contract) | ||
23 | + end | ||
24 | + | ||
25 | + should 'validate uniqueness of product and contract composed' do | ||
26 | + product = fast_create(Product) | ||
27 | + contract = BscPlugin::Contract.create!(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
28 | + sale1 = BscPlugin::Sale.create!(:product => product, :contract => contract, :quantity => 1) | ||
29 | + sale2 = BscPlugin::Sale.new(:product => product, :contract => contract, :quantity => 1) | ||
30 | + sale2.valid? | ||
31 | + | ||
32 | + assert sale2.errors.invalid?(:product_id) | ||
33 | + end | ||
34 | + | ||
35 | + should 'validate quantity as a positive integer' do | ||
36 | + sale.quantity = -1 | ||
37 | + sale.valid? | ||
38 | + assert sale.errors.invalid?(:quantity) | ||
39 | + | ||
40 | + sale.quantity = 1.5 | ||
41 | + sale.valid? | ||
42 | + assert sale.errors.invalid?(:quantity) | ||
43 | + | ||
44 | + sale.quantity = 3 | ||
45 | + sale.valid? | ||
46 | + assert !sale.errors.invalid?(:quantity) | ||
47 | + end | ||
48 | + | ||
49 | + should 'set default price as product price if no price indicated' do | ||
50 | + product = fast_create(Product, :price => 3.50) | ||
51 | + contract = BscPlugin::Contract.create!(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
52 | + sale.product = product | ||
53 | + sale.contract = contract | ||
54 | + sale.quantity = 1 | ||
55 | + sale.save! | ||
56 | + | ||
57 | + assert_equal product.price, sale.price | ||
58 | + end | ||
59 | + | ||
60 | + should 'not overwrite with the product price if price informed' do | ||
61 | + product = fast_create(Product, :price => 3.50) | ||
62 | + contract = BscPlugin::Contract.create!(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
63 | + sale.product = product | ||
64 | + sale.contract = contract | ||
65 | + sale.quantity = 1 | ||
66 | + sale.price = 2.50 | ||
67 | + sale.save! | ||
68 | + | ||
69 | + assert_equal 2.50, sale.price | ||
70 | + end | ||
71 | + | ||
72 | + should 'have default value for price' do | ||
73 | + product1 = fast_create(Product, :price => 1) | ||
74 | + product2 = fast_create(Product, :price => 1) | ||
75 | + product3 = fast_create(Product) | ||
76 | + contract = BscPlugin::Contract.create!(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
77 | + sale1 = BscPlugin::Sale.create!(:price => 2, :product => product1, :contract => contract, :quantity => 1) | ||
78 | + sale2 = BscPlugin::Sale.create!(:product => product2, :contract => contract, :quantity => 1) | ||
79 | + sale3 = BscPlugin::Sale.create!(:product => product3, :contract => contract, :quantity => 1) | ||
80 | + | ||
81 | + assert_equal 2, sale1.price | ||
82 | + assert_equal 1, sale2.price | ||
83 | + assert_equal 0, sale3.price | ||
84 | + end | ||
85 | +end | ||
86 | + |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | +require File.dirname(__FILE__) + '/../../../../../app/models/uploaded_file' | ||
3 | +require File.dirname(__FILE__) + '/../../../../../app/models/enterprise' | ||
4 | +require File.dirname(__FILE__) + '/../../../lib/ext/enterprise' | ||
5 | + | ||
6 | +class EnterpriseTest < Test::Unit::TestCase | ||
7 | + VALID_CNPJ = '94.132.024/0001-48' | ||
8 | + | ||
9 | + def setup | ||
10 | + @bsc = BscPlugin::Bsc.create!({:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}) | ||
11 | + end | ||
12 | + | ||
13 | + attr_accessor :bsc | ||
14 | + | ||
15 | + should 'belongs to a bsc' do | ||
16 | + enterprise = fast_create(Enterprise, :bsc_id => bsc.id) | ||
17 | + assert_equal bsc, enterprise.bsc | ||
18 | + end | ||
19 | + | ||
20 | + should 'return correct enterprises on validated and not validated namedscopes' do | ||
21 | + validated_enterprise = fast_create(Enterprise, :validated => true) | ||
22 | + not_validated_enterprise = fast_create(Enterprise, :validated => false) | ||
23 | + | ||
24 | + assert_includes Enterprise.validated, validated_enterprise | ||
25 | + assert_not_includes Enterprise.validated, not_validated_enterprise | ||
26 | + assert_not_includes Enterprise.not_validated, validated_enterprise | ||
27 | + assert_includes Enterprise.not_validated, not_validated_enterprise | ||
28 | + end | ||
29 | + | ||
30 | + should 'be involved with many contracts' do | ||
31 | + enterprise = fast_create(Enterprise) | ||
32 | + contract1 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin') | ||
33 | + contract2 = BscPlugin::Contract.create!(:bsc => bsc, :client_name => 'Marvin') | ||
34 | + enterprise.contracts << contract1 | ||
35 | + enterprise.contracts << contract2 | ||
36 | + | ||
37 | + assert_includes enterprise.contracts, contract1 | ||
38 | + assert_includes enterprise.contracts, contract2 | ||
39 | + end | ||
40 | +end | ||
41 | + |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | +require File.dirname(__FILE__) + '/../../../../../app/models/uploaded_file' | ||
3 | + | ||
4 | +class ProductTest < Test::Unit::TestCase | ||
5 | + VALID_CNPJ = '94.132.024/0001-48' | ||
6 | + | ||
7 | + should 'return have bsc' do | ||
8 | + bsc = BscPlugin::Bsc.create!({:business_name => 'Sample Bsc', :identifier => 'sample-bsc', :company_name => 'Sample Bsc Ltda.', :cnpj => VALID_CNPJ}) | ||
9 | + enterprise = fast_create(Enterprise, :bsc_id => bsc.id) | ||
10 | + product = fast_create(Product, :enterprise_id => enterprise.id) | ||
11 | + | ||
12 | + assert_equal bsc, product.bsc | ||
13 | + end | ||
14 | + | ||
15 | + should 'have contracts through sales' do | ||
16 | + product = fast_create(Product) | ||
17 | + contract1 = BscPlugin::Contract.create!(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
18 | + contract2 = BscPlugin::Contract.create!(:bsc => BscPlugin::Bsc.new, :client_name => 'Marvin') | ||
19 | + sale1 = BscPlugin::Sale.create!(:product => product, :contract => contract1, :quantity => 3) | ||
20 | + sale2 = BscPlugin::Sale.create!(:product => product, :contract => contract2, :quantity => 5) | ||
21 | + | ||
22 | + assert_includes product.contracts, contract1 | ||
23 | + assert_includes product.contracts, contract2 | ||
24 | + end | ||
25 | +end |
plugins/bsc/views/bsc_plugin_environment/validate_enterprises.html.erb
1 | <h1><%= _('Validate enterprises') %></h1> | 1 | <h1><%= _('Validate enterprises') %></h1> |
2 | 2 | ||
3 | <% form_tag :action => 'save_validations' do %> | 3 | <% form_tag :action => 'save_validations' do %> |
4 | - <%= text_field_tag(:q, nil, :id => 'search-enterprises') %> | 4 | + <%= token_input_field_tag(:q, 'search-enterprises', {:action => 'search_enterprise'}, |
5 | + { :hint_text => _('Type in a search term for enterprise'), | ||
6 | + :focus => true }) %> | ||
5 | 7 | ||
6 | <% button_bar do %> | 8 | <% button_bar do %> |
7 | <%= submit_button('save', _('Save'))%> | 9 | <%= submit_button('save', _('Save'))%> |
8 | <%= button('cancel', _('Cancel'), {:controller => 'admin_panel'})%> | 10 | <%= button('cancel', _('Cancel'), {:controller => 'admin_panel'})%> |
9 | <% end %> | 11 | <% end %> |
10 | <% end %> | 12 | <% end %> |
11 | - | ||
12 | -<%= javascript_include_tag '/plugins/bsc/jquery_tokeninput/src/jquery.tokeninput.js' %> | ||
13 | -<% stylesheet('/plugins/bsc/jquery_tokeninput/styles/token-input.css') %> | ||
14 | -<% search_url = url_for(:action => 'search_enterprise') %> | ||
15 | -<script type="text/javascript"> | ||
16 | - jQuery("#search-enterprises") | ||
17 | - .tokenInput("<%= search_url %>", { | ||
18 | - hintText: <%= _('Type in a search term for enterprise').to_json %>, | ||
19 | - noResultsText: <%= _('No results').to_json %>, | ||
20 | - searchingText: <%= _('Searching...').to_json %>, | ||
21 | - searchDelay: 500, | ||
22 | - backspaceDeleteItem: false | ||
23 | - }) | ||
24 | - .focus(); | ||
25 | - | ||
26 | - jQuery("#token-input-search-enterprises") | ||
27 | - .live("keydown", function(event){ | ||
28 | - if(event.keyCode == "13") return false; | ||
29 | - }); | ||
30 | -</script> | ||
31 | - |
plugins/bsc/views/bsc_plugin_myprofile/_contract_form.html.erb
0 → 100644
@@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
1 | +<%= error_messages_for :contract %> | ||
2 | + | ||
3 | +<% labelled_form_for :contract, @contract, :html => {:id => 'bsc-plugin-sales-form'} do |f| %> | ||
4 | + <%= hidden_field_tag :contract_id, @contract.id %> | ||
5 | + <%= required f.text_field(:client_name) %> | ||
6 | + <%= labelled_form_field(_('Client type'), f.select(:client_type, BscPlugin::Contract::ClientType.types.map{|type| [BscPlugin::Contract::ClientType.names[type], type]}))%> | ||
7 | + <%= labelled_form_field(_('Business type'), f.select(:business_type, BscPlugin::Contract::BusinessType.types.map{|type| [BscPlugin::Contract::BusinessType.names[type], type]}))%> | ||
8 | + <%= f.text_field(:state) %> | ||
9 | + <%= f.text_field(:city) %> | ||
10 | + <%= labelled_form_field(_('Status'), f.select(:status, BscPlugin::Contract::Status.types. | ||
11 | + map { |s| [BscPlugin::Contract::Status.names[s], s] })) %> | ||
12 | + <%= f.text_field(:number_of_producers, :size => 8, :id => 'bsc-plugin-contract-spinner') %> | ||
13 | + <%= _('Empreendimentos')+':' %> | ||
14 | + | ||
15 | + <% search_action = {:action => 'search_contract_enterprises', :profile => profile.identifier} %> | ||
16 | + <%= token_input_field_tag(:enterprises, 'involved-enterprises', search_action, | ||
17 | + { :pre_populate => @contract.enterprises_to_token_input, | ||
18 | + :hint_text => _('Type in serach term for enterprise') }) %> | ||
19 | + | ||
20 | + <table id="bsc-plugin-sales-table" class="alternate-colors"> | ||
21 | + <tr> | ||
22 | + <th class="bsc-plugin-sales-products-column"><%= _('Products') %></th> | ||
23 | + <th class="bsc-plugin-sales-quantity-column" ><%= _('Quantity') %></th> | ||
24 | + <th class="bsc-plugin-sales-price-column" ><%= _('Unit price') %></th> | ||
25 | + </tr> | ||
26 | + <tr id='bsc-plugin-contract-total-row'> | ||
27 | + <td id="bsc-plugin-contract-total-string" colspan="2" ><strong><%= _('Total')%></strong></td> | ||
28 | + <td id="bsc-plugin-contract-total"><strong id='bsc-plugin-sales-total-value'><%= float_to_currency(@contract.total_price)%></strong></td> | ||
29 | + </tr> | ||
30 | + <tr> | ||
31 | + <td colspan="3" class="bsc-plugin-sales-add-new-row"><%= link_to(_('Add new product'), {}, :id => 'bsc-plugin-add-new-product', 'data-bsc' => profile.identifier) %></td> | ||
32 | + </tr> | ||
33 | + </table> | ||
34 | + | ||
35 | + <%= labelled_form_field( _('Supply period'), | ||
36 | + text_field_tag('contract[supply_start]', (@contract.supply_start ? @contract.supply_start.strftime("%Y-%m-%d") : nil), :id => 'from', :size => 9) + | ||
37 | + _(' to ') + | ||
38 | + text_field_tag('contract[supply_end]', (@contract.supply_end ? @contract.supply_end.strftime("%Y-%m-%d") : nil), :id => 'to', :size => 9) ) | ||
39 | + %> | ||
40 | + | ||
41 | + <%= f.text_area(:annotations, :rows => 5, :cols => 68) %> | ||
42 | + <% button_bar do%> | ||
43 | + <%= submit_button(:save, _('Save'), :cancel => {:action => 'manage_contracts'})%> | ||
44 | + <% end %> | ||
45 | +<% end %> | ||
46 | + | ||
47 | +<% scripts = %w{/plugins/bsc/jquery.ui.spinner/ui.spinner.js | ||
48 | + /plugins/bsc/contracts /plugins/bsc/datepicker | ||
49 | + /plugins/bsc/spinner} %> | ||
50 | +<% scripts.each do |script|%> | ||
51 | + <%= javascript_include_tag script %> | ||
52 | +<% end %> | ||
53 | + | ||
54 | +<script> | ||
55 | + BSCContracts.tokenInputOptions = { | ||
56 | + minChars: 3, | ||
57 | + hintText: <%= _('Type in a search term for product').to_json %>, | ||
58 | + noResultsText: <%= _("No results").to_json %>, | ||
59 | + searchingText: <%= _("Searching...").to_json %>, | ||
60 | + searchDelay: 1000, | ||
61 | + preventDuplicates: true, | ||
62 | + backspaceDeleteItem: false, | ||
63 | + tokenLimit: 1, | ||
64 | + onDelete: BSCContracts.onDelete, | ||
65 | + onAdd: BSCContracts.onAdd | ||
66 | + }; | ||
67 | + BSCContracts.searchUrl = <%= url_for( | ||
68 | + :action => 'search_sale_product', | ||
69 | + :profile => profile.identifier, | ||
70 | + :enterprises => 'ENTERPRISES', | ||
71 | + :sale_id => 'SALE_ID', | ||
72 | + :added_products => 'ADDED_PRODUCTS', | ||
73 | + :escape => true).to_json %>.replace(/amp;/g,""); | ||
74 | + BSCContracts.currencyUnit = <%= profile.environment.currency_unit.to_json %>; | ||
75 | + BSCContracts.prePopulate( <%= @contract.sales.map{|sale| { | ||
76 | + :id => sale.product_id, | ||
77 | + :name => short_text(product_display_name(sale.product), 60), | ||
78 | + :product_price => sale.price || sale.product.price || 0, | ||
79 | + :quantity => sale.quantity}}.to_json | ||
80 | + %>); | ||
81 | +</script> | ||
82 | + | ||
83 | +<%= javascript_include_tag '/plugins/bsc/validation' %> |
plugins/bsc/views/bsc_plugin_myprofile/edit_contract.html.erb
0 → 100644
plugins/bsc/views/bsc_plugin_myprofile/manage_associated_enterprises.html.erb
@@ -10,7 +10,11 @@ | @@ -10,7 +10,11 @@ | ||
10 | <% end %> | 10 | <% end %> |
11 | 11 | ||
12 | <% form_tag :action => 'save_associations' do %> | 12 | <% form_tag :action => 'save_associations' do %> |
13 | - <%= text_field_tag(:q, nil, :id => 'search-enterprises') %> | 13 | + <% search_action = {:action => 'search_enterprise', :profile => profile.identifier} %> |
14 | + <%= token_input_field_tag(:q, 'search-enterprises', search_action, | ||
15 | + { :pre_populate => profile.enterprises_to_token_input, | ||
16 | + :hint_text => _('Type in a search term for enterprise'), | ||
17 | + :focus => true }) %> | ||
14 | 18 | ||
15 | <%= button('add', _('Add new enterprise'), {:action => 'create_enterprise'}) %> | 19 | <%= button('add', _('Add new enterprise'), {:action => 'create_enterprise'}) %> |
16 | 20 | ||
@@ -20,24 +24,3 @@ | @@ -20,24 +24,3 @@ | ||
20 | <% end %> | 24 | <% end %> |
21 | 25 | ||
22 | <% end %> | 26 | <% end %> |
23 | -<%= javascript_include_tag '/plugins/bsc/jquery_tokeninput/src/jquery.tokeninput.js' %> | ||
24 | -<% stylesheet('/plugins/bsc/jquery_tokeninput/styles/token-input.css') %> | ||
25 | -<% search_url = url_for(:action => 'search_enterprise', :profile => profile.identifier) %> | ||
26 | -<script type="text/javascript"> | ||
27 | - jQuery("#search-enterprises") | ||
28 | - .tokenInput("<%= search_url %>", { | ||
29 | - minChars: 3, | ||
30 | - prePopulate: <%= profile.enterprises_to_json %>, | ||
31 | - hintText: <%= _('Type in a search term for enterprise').to_json %>, | ||
32 | - noResultsText: <%= _('No results').to_json %>, | ||
33 | - searchingText: <%= _('Searching...').to_json %>, | ||
34 | - searchDelay: 500, | ||
35 | - backspaceDeleteItem: false | ||
36 | - }) | ||
37 | - .focus(); | ||
38 | - | ||
39 | - jQuery("#token-input-search-enterprises") | ||
40 | - .live("keydown", function(event){ | ||
41 | - if(event.keyCode == "13") return false; | ||
42 | - }); | ||
43 | -</script> |
plugins/bsc/views/bsc_plugin_myprofile/manage_contracts.html.erb
0 → 100644
@@ -0,0 +1,49 @@ | @@ -0,0 +1,49 @@ | ||
1 | +<h1><%= _('Manage contracts') %></h1> | ||
2 | + | ||
3 | +<% form_tag({}, {:id => "bsc-plugin-contracts-form"}) do %> | ||
4 | + <div id="bsc-plugin-contracts-filter"> | ||
5 | + <h2><%= _('Status') %></h2> | ||
6 | + <% BscPlugin::Contract::Status.types.each do |status| %> | ||
7 | + <%= check_box_tag('status[]', status, @status.include?(status.to_s), :id => 'status-checkbox-'+status.to_s) %> | ||
8 | + <%= content_tag('label', BscPlugin::Contract::Status.names[status], :for => 'status-checkbox-'+status.to_s) %> | ||
9 | + <br style="clear:both" /> | ||
10 | + <% end %> | ||
11 | + <br style="clear:both" /> | ||
12 | + <%= submit_button(:save, _('Filter')) %> | ||
13 | + </div> | ||
14 | + | ||
15 | + <div id='bsc-plugin-contracts-results'> | ||
16 | + <div id="bsc-plugin-sorter"> | ||
17 | + <%= labelled_select(_('Sort by')+' ', :sorting, :first, :last, @sorting, | ||
18 | + [['created_at asc', _('Date(newest first)')], ['created_at desc', _('Date(oldest first)')], | ||
19 | + ['client_name asc', _('Client name(A-Z)')], ['client_name desc', _('Client name(Z-A)')]], | ||
20 | + :onchange => "jQuery('#bsc-plugin-contracts-form').submit()") %> | ||
21 | + </div> | ||
22 | + | ||
23 | + <% if @contracts.blank? %> | ||
24 | + <%= content_tag('em', _('There are no contracts at all.'))%> | ||
25 | + <% else %> | ||
26 | + <table id="bsc-plugin-manage-contracts-table" class="alternate-colors"> | ||
27 | + <% @contracts.each do |contract| %> | ||
28 | + <tr> | ||
29 | + <td> | ||
30 | + <%= link_to(content_tag('b', contract.client_name ), :action => 'view_contract', :contract_id => contract.id) %> <br /> | ||
31 | + <%= content_tag('i', show_date(contract.created_at)) %> | ||
32 | + </td> | ||
33 | + <td class="links"> | ||
34 | + <%= link_to(_('Edit'), :action => 'edit_contract', :contract_id => contract.id)%> | ||
35 | + <%= link_to(_('Remove'), {:action => 'destroy_contract', :contract_id => contract.id}, :confirm => _('Are you sure?'))%> | ||
36 | + </td> | ||
37 | + </tr> | ||
38 | + <% end %> | ||
39 | + </table> | ||
40 | + <%= pagination_links @contracts %> | ||
41 | + <% end %> | ||
42 | + | ||
43 | + <% button_bar do %> | ||
44 | + <%= button(:back, _('Go back'), :controller => 'profile_editor') %> | ||
45 | + <%= button(:new, _('Create new contract'), :action => 'new_contract')%> | ||
46 | + <% end %> | ||
47 | + </div> | ||
48 | +<% end %> | ||
49 | +<br style="clear:both" /> |
plugins/bsc/views/bsc_plugin_myprofile/new_contract.html.erb
0 → 100644
plugins/bsc/views/bsc_plugin_myprofile/transfer_ownership.html.erb
@@ -13,10 +13,16 @@ | @@ -13,10 +13,16 @@ | ||
13 | </ul> | 13 | </ul> |
14 | <% end %> | 14 | <% end %> |
15 | 15 | ||
16 | + | ||
16 | <% form_tag do %> | 17 | <% form_tag do %> |
17 | <% @roles.each do |role|%> | 18 | <% @roles.each do |role|%> |
18 | <%= content_tag('b', _('Administrator:')) %> | 19 | <%= content_tag('b', _('Administrator:')) %> |
19 | - <%= text_field_tag('q_'+role.key, nil, :id => 'search_'+role.key) %> | 20 | + <% search_action = {:controller => 'profile_members', :action => 'search_user', :role => role.id, :profile => profile.identifier} %> |
21 | + <%= token_input_field_tag('q_'+role.key, 'search_'+role.key, search_action, | ||
22 | + { :hint_text => _('Type in a search term for the new administrator'), | ||
23 | + :focus => true, | ||
24 | + :token_limit => 1}) %> | ||
25 | + | ||
20 | <% end %> | 26 | <% end %> |
21 | 27 | ||
22 | <% button_bar do %> | 28 | <% button_bar do %> |
@@ -24,31 +30,3 @@ | @@ -24,31 +30,3 @@ | ||
24 | <%= button('cancel', _('Cancel'), {:controller => 'profile_editor'})%> | 30 | <%= button('cancel', _('Cancel'), {:controller => 'profile_editor'})%> |
25 | <% end %> | 31 | <% end %> |
26 | <% end %> | 32 | <% end %> |
27 | - | ||
28 | -<%= javascript_include_tag '/plugins/bsc/jquery_tokeninput/src/jquery.tokeninput.js' %> | ||
29 | -<% stylesheet('/plugins/bsc/jquery_tokeninput/styles/token-input.css') %> | ||
30 | - | ||
31 | -<% @roles.each do |role| %> | ||
32 | - <% search_url = url_for(:controller => 'profile_members', :action => 'search_user', :role => role.id, :profile => profile.identifier) %> | ||
33 | - <script type="text/javascript"> | ||
34 | - jQuery(<%= ('#search_' + role.key).to_json %>) | ||
35 | - .tokenInput("<%= search_url %>", { | ||
36 | - hintText: <%= _('Type in a search term for the new administrator').to_json %>, | ||
37 | - noResultsText: <%= _('No results').to_json %>, | ||
38 | - searchingText: <%= _('Searching...').to_json %>, | ||
39 | - searchDelay: 500, | ||
40 | - backspaceDeleteItem: false, | ||
41 | - preventDuplicates: true, | ||
42 | - tokenLimit: 1, | ||
43 | - queryParam: <%= ('q_'+role.key).to_json %> | ||
44 | - }) | ||
45 | - .focus(); | ||
46 | - | ||
47 | - jQuery("#token-input-search-enterprises") | ||
48 | - .live("keydown", function(event){ | ||
49 | - if(event.keyCode == "13") return false; | ||
50 | - }); | ||
51 | - </script> | ||
52 | -<% end %> | ||
53 | - | ||
54 | - |
plugins/bsc/views/bsc_plugin_myprofile/view_contract.html.erb
0 → 100644
@@ -0,0 +1,55 @@ | @@ -0,0 +1,55 @@ | ||
1 | +<h1><%= @contract.client_name %></h1> | ||
2 | + | ||
3 | +<table class='bsc-fields-table' style="float: left;"> | ||
4 | + <tr> | ||
5 | + <th colspan='2'><%= _('Basic information') %></th> | ||
6 | + </tr> | ||
7 | + <%= display_text_field(_('Client type'), BscPlugin::Contract::ClientType.names[@contract.client_type]) %> | ||
8 | + <%= display_text_field(_('Business type'), BscPlugin::Contract::BusinessType.names[@contract.business_type]) %> | ||
9 | + <%= display_text_field(_('State'), @contract.state) %> | ||
10 | + <%= display_text_field(_('City'), @contract.city) %> | ||
11 | + <%= display_text_field(_('Status'), BscPlugin::Contract::Status.names[@contract.status]) %> | ||
12 | + <%= display_text_field(_('Number of producers'), @contract.number_of_producers) %> | ||
13 | + <%= display_text_field(_('Supply period'), show_period(@contract.supply_start, @contract.supply_end, true)) %> | ||
14 | +</table> | ||
15 | + | ||
16 | +<table class='bsc-fields-table' style="float: right;"> | ||
17 | + <tr> | ||
18 | + <th colspan='2'><%= _('Enterprises') %></th> | ||
19 | + </tr> | ||
20 | + <%= display_list_field(@contract.enterprises.map {|enterprise| link_to(enterprise.short_name(60), enterprise.url)}) %> | ||
21 | +</table> | ||
22 | + | ||
23 | +<% if !@contract.sales.blank?%> | ||
24 | + <table id='bsc-plugin-sales-table' class="bsc-plugin-view-contract alternate-colors"> | ||
25 | + <tr> | ||
26 | + <th><%= _('Product') %></th> | ||
27 | + <th align="center"><%= _('Quantity') %></th> | ||
28 | + <th><%= _('Unit price') %></th> | ||
29 | + </tr> | ||
30 | + <% @contract.sales.each do |sale| %> | ||
31 | + <tr> | ||
32 | + <td><%= short_text(product_display_name(Product.find(sale.product_id)), 110) %></td> | ||
33 | + <td align="center"><%= sale.quantity %></td> | ||
34 | + <td align="right"><%= float_to_currency(sale.price) %></td> | ||
35 | + </tr> | ||
36 | + <% end %> | ||
37 | + <tr> | ||
38 | + <td id="bsc-plugin-contract-total-string" class="bsc-plugin-total" colspan='2'><%= _('Total')%></td> | ||
39 | + <td id="bsc-plugin-contract-total" class="bsc-plugin-total"><%= float_to_currency(@contract.total_price) %></td> | ||
40 | + </tr> | ||
41 | + </table> | ||
42 | +<% end %> | ||
43 | + | ||
44 | +<br style="clear: both" /> | ||
45 | + | ||
46 | +<% if !@contract.annotations.blank? %> | ||
47 | + <div class="bsc-plugin-annotation"> | ||
48 | + <div class="bsc-plugin-annotation-title"><%= _("Annotations") %></div> | ||
49 | + <div class="bsc-plugin-annotation-content"><%= @contract.annotations %></div> | ||
50 | + </div> | ||
51 | +<% end %> | ||
52 | + | ||
53 | +<% button_bar do %> | ||
54 | + <%= button(:back, _('Go back'), :action => 'manage_contracts') %> | ||
55 | +<% end %> |