From 11e738b42827669add6e81b7a5dbef0a21fcc4c0 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sat, 19 Jan 2013 15:59:47 -0500 Subject: [PATCH 1/8] Adding transactions -Need to create a customers table to store contact information of customers who are not a user. -Need to scope "User Transactions" for users, staff, and admin. Need to have a "All Shop Transactions" tab. -Need to add conditional UX to form. --- app/components/app_tab_panel.rb | 2 +- app/components/transactions.rb | 17 +++++++++++++++++ app/models/bike.rb | 2 ++ app/models/transaction.rb | 8 ++++++++ app/models/user.rb | 1 + .../20121205043759_create_transactions.rb | 6 +++++- db/schema.rb | 11 ++++++++--- 7 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 app/components/transactions.rb create mode 100644 app/models/transaction.rb diff --git a/app/components/app_tab_panel.rb b/app/components/app_tab_panel.rb index 7442c27..d881e54 100644 --- a/app/components/app_tab_panel.rb +++ b/app/components/app_tab_panel.rb @@ -10,7 +10,7 @@ class AppTabPanel < Netzke::Basepack::TabPanel #all users # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items = [ :bikes_border, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] + @@app_tab_panel_items = [ :transactions, :bikes_border, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] #for users if controller.current_user.user? diff --git a/app/components/transactions.rb b/app/components/transactions.rb new file mode 100644 index 0000000..040230b --- /dev/null +++ b/app/components/transactions.rb @@ -0,0 +1,17 @@ +class Transactions < Netzke::Basepack::Grid + def configure(c) + super + c.model = "Transaction" + c.strong_default_attrs = { :vendor_id => controller.current_user.id } + c.columns = [ + :amount, + :item, + { :name => :bike__serial_number}, + { :name => :vendor, :getter => lambda { |rec| + user = rec.vendor + user.nil? ? "" : "#{user.first_name} #{user.last_name}" + } + } + ] + end +end diff --git a/app/models/bike.rb b/app/models/bike.rb index b57b59f..4389ffb 100644 --- a/app/models/bike.rb +++ b/app/models/bike.rb @@ -2,6 +2,8 @@ class Bike < ActiveRecord::Base acts_as_loggable attr_accessible :serial_number, :bike_brand_id, :bike_model_id, :color, :bike_style_id, :seat_tube_height, :top_tube_length, :wheel_size, :value, :bike_condition_id, :bike_status_id + + has_many :transactions has_one :owner, :class_name => 'User' belongs_to :bike_brand diff --git a/app/models/transaction.rb b/app/models/transaction.rb new file mode 100644 index 0000000..484e8f9 --- /dev/null +++ b/app/models/transaction.rb @@ -0,0 +1,8 @@ +class Transaction < ActiveRecord::Base + acts_as_loggable + attr_accessible :vendor_id, :customer_id, :customer_type, :bike_id, :amount, :item + + belongs_to :vendor, :class_name => 'User', :foreign_key => 'vendor_id' + belongs_to :bike + +end diff --git a/app/models/user.rb b/app/models/user.rb index a656337..c51f98a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,6 +10,7 @@ class User < ActiveRecord::Base :first_name, :last_name, :nickname, :user_role_id, :bike_id, :user_profiles_attributes + has_many :transactions has_many :user_profiles accepts_nested_attributes_for :user_profiles, allow_destroy: false diff --git a/db/migrate/20121205043759_create_transactions.rb b/db/migrate/20121205043759_create_transactions.rb index 86f5222..827e7a8 100644 --- a/db/migrate/20121205043759_create_transactions.rb +++ b/db/migrate/20121205043759_create_transactions.rb @@ -1,9 +1,12 @@ class CreateTransactions < ActiveRecord::Migration def change create_table :transactions do |t| - t.integer "user_id", :null => false + t.integer "vendor_id", :null => false + t.integer "customer_id" + t.integer "customer_type" t.integer "bike_id" t.integer "amount", :null => false + t.string "item", :null => false #Adding whether or not a user sold or purchased the bike #could be used to help keep track of external sales. #aka, a collective member (user) sold a bike to @@ -11,6 +14,7 @@ class CreateTransactions < ActiveRecord::Migration #Currently this model automatically assumes that the user is #purchasing a bike, or a part for a bike from the collective #t.boolean "user_sold_flag", :default => false + t.timestamps end end end diff --git a/db/schema.rb b/db/schema.rb index 0b8e94a..62957cf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -88,9 +88,14 @@ ActiveRecord::Schema.define(:version => 20121229160809) do end create_table "transactions", :force => true do |t| - t.integer "user_id", :null => false - t.integer "bike_id" - t.integer "amount", :null => false + t.integer "vendor_id", :null => false + t.integer "customer_id" + t.integer "customer_type" + t.integer "bike_id" + t.integer "amount", :null => false + t.string "item", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "user_actions", :force => true do |t| From d95f51eeca110e2e6085358f41183dd14c335978 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sun, 20 Jan 2013 13:52:19 -0500 Subject: [PATCH 2/8] Created customers --- app/models/customer.rb | 10 ++++++++++ db/migrate/20130120142249_create_customers.rb | 19 +++++++++++++++++++ db/schema.rb | 17 ++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 app/models/customer.rb create mode 100644 db/migrate/20130120142249_create_customers.rb diff --git a/app/models/customer.rb b/app/models/customer.rb new file mode 100644 index 0000000..bc47613 --- /dev/null +++ b/app/models/customer.rb @@ -0,0 +1,10 @@ +class Customer < ActiveRecord::Base + attr_accessible :first_name, :last_name, :addrStreet1, + :addrStreet2, :addrCity, :addrState, :addrZip, :phone, :email + + has_many :transactions + + def to_s + "#{first_name} #{last_name}" + end +end diff --git a/db/migrate/20130120142249_create_customers.rb b/db/migrate/20130120142249_create_customers.rb new file mode 100644 index 0000000..6c23c86 --- /dev/null +++ b/db/migrate/20130120142249_create_customers.rb @@ -0,0 +1,19 @@ +class CreateCustomers < ActiveRecord::Migration + def change + create_table :customers do |t| + t.string "first_name", :null => false + t.string "last_name", :null => false + t.string "addrStreet1" + t.string "addrStreet2" + t.string "addrCity" + t.string "addrState" + t.string "addrZip" + t.string "phone" + t.string "email" + end + + add_index :customers, :phone, :unique => true + add_index :customers, :email, :unique => true + end + +end diff --git a/db/schema.rb b/db/schema.rb index 62957cf..244ac23 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20121229160809) do +ActiveRecord::Schema.define(:version => 20130120142249) do create_table "bike_actions", :force => true do |t| t.string "action", :limit => 128, :null => false @@ -64,6 +64,21 @@ ActiveRecord::Schema.define(:version => 20121229160809) do add_index "bikes", ["serial_number"], :name => "index_bikes_on_serial_number", :unique => true + create_table "customers", :force => true do |t| + t.string "first_name", :null => false + t.string "last_name", :null => false + t.string "addrStreet1" + t.string "addrStreet2" + t.string "addrCity" + t.string "addrState" + t.string "addrZip" + t.string "phone" + t.string "email" + end + + add_index "customers", ["email"], :name => "index_customers_on_email", :unique => true + add_index "customers", ["phone"], :name => "index_customers_on_phone", :unique => true + create_table "logs", :force => true do |t| t.integer "loggable_id" t.string "loggable_type" From 31935f6f7e2a75f495083c6746b474b681362c46 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sun, 20 Jan 2013 13:52:47 -0500 Subject: [PATCH 3/8] Nested attributes on Transactions isn't working so well --- app/components/transactions.rb | 50 ++++++++++++++++++++++++++++++++++ app/models/transaction.rb | 18 +++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/app/components/transactions.rb b/app/components/transactions.rb index 040230b..f202646 100644 --- a/app/components/transactions.rb +++ b/app/components/transactions.rb @@ -13,5 +13,55 @@ class Transactions < Netzke::Basepack::Grid } } ] + + end + + def default_fields_for_forms + bike_store = Bike.all.map { |b| [b.id, b.serial_number] } + user_store = User.all.map { |u| [u.id, u.to_s] } + [ + :amount, + :item, + { :name => :for_bike, :checkboxName => :bike_item, :inputValue => true, :title => "Selling a bike?", + :xtype => 'fieldset', :checkboxToggle => true, :collapsed => true, :items => [ + {:xtype => 'combo', :no_binding => true, :name => :bike_id, :title => 'Bike', :fieldLabel => 'Bike', :store => bike_store} + ] + }, + { + xtype: 'fieldcontainer', + fieldLabel: 'Customer Type', + defaultType: 'radiofield', + defaults: { + flex: 1 + }, + layout: 'hbox', + items: [ + { + no_binding: true, + boxLabel: 'Customer', + name: 'customer_type', + inputValue: 'Customer', + id: 'customer_radio' + }, + { + no_binding: true, + boxLabel: 'User', + name: 'customer_type', + inputValue: 'User', + id: 'user_radio' + } + ] + }, + { :name => :for_user, :checkboxName => :customer_type, :inputValue => true, :title => "Customer a User?", + :xtype => 'fieldset', :collapsible => true, :collapsed => true, :items => [ + {:xtype => 'combo', :no_binding => true, :name => :customer_id, :title => 'User', :fieldLabel => 'User', :store => user_store} + ] + }, + { :name => :for_customer, :checkboxName => :customer_type, :inputValue => true, :title => "New Customer?", + :xtype => 'fieldset', :collapsible => true, :collapsed => true, :items => [ + { :xtype => 'textfield', :no_binding => true, :name => 'customer[first_name]'}, + ] + } + ] end end diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 484e8f9..0afc26a 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -1,8 +1,24 @@ class Transaction < ActiveRecord::Base acts_as_loggable - attr_accessible :vendor_id, :customer_id, :customer_type, :bike_id, :amount, :item + + attr_accessible :vendor_id, :customer_id, :customer_type, :bike_id, :amount, :item, + :customer_attributes belongs_to :vendor, :class_name => 'User', :foreign_key => 'vendor_id' belongs_to :bike + belongs_to :customer + + accepts_nested_attributes_for :customer, allow_destroy: false + + before_save :check_customer_type + + def check_customer_type + puts "_________------------_________------------_________------------" + puts self.inspect + puts "_________------------_________------------_________------------" + end + def to_s + "#{amount} #{item} #{bike_id}" + end end From 1b7daa45ca5ba8def12ff971f6787a0d1ff9b0fc Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sun, 20 Jan 2013 14:57:43 -0500 Subject: [PATCH 4/8] Nested isn't working, another approach, add trans validations User a transactions border, select the customer from a view of users and customers --- app/components/transactions.rb | 55 +++++++------------ app/components/transactions_border.rb | 30 ++++++++++ .../javascripts/init_component.js | 17 ++++++ app/models/transaction.rb | 17 ++---- .../20121205043759_create_transactions.rb | 4 +- 5 files changed, 74 insertions(+), 49 deletions(-) create mode 100644 app/components/transactions_border.rb create mode 100644 app/components/transactions_border/javascripts/init_component.js diff --git a/app/components/transactions.rb b/app/components/transactions.rb index f202646..cad6825 100644 --- a/app/components/transactions.rb +++ b/app/components/transactions.rb @@ -2,7 +2,11 @@ class Transactions < Netzke::Basepack::Grid def configure(c) super c.model = "Transaction" - c.strong_default_attrs = { :vendor_id => controller.current_user.id } + c.strong_default_attrs = { + :vendor_id => controller.current_user.id, + :customer_id => session[:selected_user_id], + :customer_type => session[:selected_type] + } c.columns = [ :amount, :item, @@ -19,49 +23,28 @@ class Transactions < Netzke::Basepack::Grid def default_fields_for_forms bike_store = Bike.all.map { |b| [b.id, b.serial_number] } user_store = User.all.map { |u| [u.id, u.to_s] } + customer = User.find_by_id(session[:selected_user_id]) + customer = "No User Selected" if customer.nil? [ + { :no_binding => true, :xtype => 'label', :text => "Creating Transaction for: #{customer.to_s}"}, :amount, :item, { :name => :for_bike, :checkboxName => :bike_item, :inputValue => true, :title => "Selling a bike?", :xtype => 'fieldset', :checkboxToggle => true, :collapsed => true, :items => [ {:xtype => 'combo', :no_binding => true, :name => :bike_id, :title => 'Bike', :fieldLabel => 'Bike', :store => bike_store} ] - }, - { - xtype: 'fieldcontainer', - fieldLabel: 'Customer Type', - defaultType: 'radiofield', - defaults: { - flex: 1 - }, - layout: 'hbox', - items: [ - { - no_binding: true, - boxLabel: 'Customer', - name: 'customer_type', - inputValue: 'Customer', - id: 'customer_radio' - }, - { - no_binding: true, - boxLabel: 'User', - name: 'customer_type', - inputValue: 'User', - id: 'user_radio' - } - ] - }, - { :name => :for_user, :checkboxName => :customer_type, :inputValue => true, :title => "Customer a User?", - :xtype => 'fieldset', :collapsible => true, :collapsed => true, :items => [ - {:xtype => 'combo', :no_binding => true, :name => :customer_id, :title => 'User', :fieldLabel => 'User', :store => user_store} - ] - }, - { :name => :for_customer, :checkboxName => :customer_type, :inputValue => true, :title => "New Customer?", - :xtype => 'fieldset', :collapsible => true, :collapsed => true, :items => [ - { :xtype => 'textfield', :no_binding => true, :name => 'customer[first_name]'}, - ] } ] end + + js_configure do |c| + c.mixin :init_component + end + + endpoint :select_user do |params, this| + # store selected boss id in the session for this component's instance + session[:selected_user_id] = params[:user_id] + session[:selected_type] = 'User' + end + end diff --git a/app/components/transactions_border.rb b/app/components/transactions_border.rb new file mode 100644 index 0000000..c347975 --- /dev/null +++ b/app/components/transactions_border.rb @@ -0,0 +1,30 @@ +class TransactionsBorder < Netzke::Base + # Remember regions collapse state and size + include Netzke::Basepack::ItemPersistence + #users and customers components are required for the transactions form + component :transactions + component :users + component :customers + + def configure(c) + super + c.header = false + c.items = [ + { netzke_component: :transactions, region: :west, width: 300, split: true }, + { netzke_component: :users, region: :center, width: 300, split: true }, + { netzke_component: :customers, region: :east, width: 300, split: true } + ] + end + + js_configure do |c| + c.layout = :border + c.border = false + c.mixin :init_component + end + + endpoint :select_customer do |params, this| + session[:selected_customer_id] = params[:customer_id] + session[:selected_customer_type] = params[:customer_type] + end + +end diff --git a/app/components/transactions_border/javascripts/init_component.js b/app/components/transactions_border/javascripts/init_component.js new file mode 100644 index 0000000..7f2cd2d --- /dev/null +++ b/app/components/transactions_border/javascripts/init_component.js @@ -0,0 +1,17 @@ +{ + initComponent: function(){ + // calling superclass's initComponent + this.callParent(); + + // setting the 'rowclick' event + var user_view = this.getComponent('users').getView(); + var customer_view = this.getComponent('users').getView(); + user_view.on('itemclick', function(view, record){ + // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! + this.selectCustomer({customer_id: record.get('id'), customer_type: 'User'}); + }, this); + customer_view.on('itemclick', function(view, record){ + this.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'}); + }, this); + } +} diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 0afc26a..bdebc68 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -1,22 +1,17 @@ class Transaction < ActiveRecord::Base acts_as_loggable - attr_accessible :vendor_id, :customer_id, :customer_type, :bike_id, :amount, :item, - :customer_attributes + attr_accessible :vendor_id, :customer_id, :customer_type, :bike_id, :amount, :item belongs_to :vendor, :class_name => 'User', :foreign_key => 'vendor_id' belongs_to :bike belongs_to :customer - accepts_nested_attributes_for :customer, allow_destroy: false - - before_save :check_customer_type - - def check_customer_type - puts "_________------------_________------------_________------------" - puts self.inspect - puts "_________------------_________------------_________------------" - end + validates :vendor_id, :presence => true + validates :customer_id, :presence => { :message => "Choose a User or Customer"} + validates :customer_type, :presence => { :message => "Choose a User or Customer"} + validates :amount, :presence => true + validates :item, :presence => true def to_s "#{amount} #{item} #{bike_id}" diff --git a/db/migrate/20121205043759_create_transactions.rb b/db/migrate/20121205043759_create_transactions.rb index 827e7a8..bb325fa 100644 --- a/db/migrate/20121205043759_create_transactions.rb +++ b/db/migrate/20121205043759_create_transactions.rb @@ -2,8 +2,8 @@ class CreateTransactions < ActiveRecord::Migration def change create_table :transactions do |t| t.integer "vendor_id", :null => false - t.integer "customer_id" - t.integer "customer_type" + t.integer "customer_id", :null => false + t.integer "customer_type", :null => false t.integer "bike_id" t.integer "amount", :null => false t.string "item", :null => false From 2d51bd1d9a77560ba1292ae8482f6a9d0f131c91 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sun, 20 Jan 2013 16:14:53 -0500 Subject: [PATCH 5/8] Creating Transactions works -Need to scope transactions for users -Only Admins should be able to create transactions --- app/components/app_tab_panel.rb | 2 +- app/components/customers.rb | 10 ++++++++ app/components/transactions.rb | 24 +++++++++---------- .../javascripts/init_component.js | 4 +++- app/models/customer.rb | 12 +++++++++- app/models/transaction.rb | 2 +- .../20121205043759_create_transactions.rb | 2 +- db/schema.rb | 4 ++-- 8 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 app/components/customers.rb diff --git a/app/components/app_tab_panel.rb b/app/components/app_tab_panel.rb index d881e54..dddcc10 100644 --- a/app/components/app_tab_panel.rb +++ b/app/components/app_tab_panel.rb @@ -10,7 +10,7 @@ class AppTabPanel < Netzke::Basepack::TabPanel #all users # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items = [ :transactions, :bikes_border, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] + @@app_tab_panel_items = [ :transactions_border, :bikes_border, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] #for users if controller.current_user.user? diff --git a/app/components/customers.rb b/app/components/customers.rb new file mode 100644 index 0000000..d0e8a2c --- /dev/null +++ b/app/components/customers.rb @@ -0,0 +1,10 @@ +class Customers < Netzke::Basepack::Grid + def configure(c) + c.model = "Customer" + end + + #override with nil to remove actions + def default_bbar + [ :apply, :add_in_form, :search ] + end +end diff --git a/app/components/transactions.rb b/app/components/transactions.rb index cad6825..dcfcc27 100644 --- a/app/components/transactions.rb +++ b/app/components/transactions.rb @@ -4,8 +4,8 @@ class Transactions < Netzke::Basepack::Grid c.model = "Transaction" c.strong_default_attrs = { :vendor_id => controller.current_user.id, - :customer_id => session[:selected_user_id], - :customer_type => session[:selected_type] + :customer_id => session[:selected_customer_id], + :customer_type => session[:selected_customer_type] } c.columns = [ :amount, @@ -23,7 +23,13 @@ class Transactions < Netzke::Basepack::Grid def default_fields_for_forms bike_store = Bike.all.map { |b| [b.id, b.serial_number] } user_store = User.all.map { |u| [u.id, u.to_s] } - customer = User.find_by_id(session[:selected_user_id]) + customer = nil + if session[:selected_customer_type] == "User" + customer = User.find_by_id(session[:selected_customer_id]) + elsif session[:selected_customer_type] == "Customer" + customer = Customer.find_by_id(session[:selected_customer_id]) + end + customer = "No User Selected" if customer.nil? [ { :no_binding => true, :xtype => 'label', :text => "Creating Transaction for: #{customer.to_s}"}, @@ -37,14 +43,8 @@ class Transactions < Netzke::Basepack::Grid ] end - js_configure do |c| - c.mixin :init_component - end - - endpoint :select_user do |params, this| - # store selected boss id in the session for this component's instance - session[:selected_user_id] = params[:user_id] - session[:selected_type] = 'User' + #override with nil to remove actions + def default_bbar + [ :apply, :add_in_form, :search ] end - end diff --git a/app/components/transactions_border/javascripts/init_component.js b/app/components/transactions_border/javascripts/init_component.js index 7f2cd2d..da0c444 100644 --- a/app/components/transactions_border/javascripts/init_component.js +++ b/app/components/transactions_border/javascripts/init_component.js @@ -5,12 +5,14 @@ // setting the 'rowclick' event var user_view = this.getComponent('users').getView(); - var customer_view = this.getComponent('users').getView(); + var customer_view = this.getComponent('customers').getView(); user_view.on('itemclick', function(view, record){ // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! + console.log("user: " + record.get('id') ); this.selectCustomer({customer_id: record.get('id'), customer_type: 'User'}); }, this); customer_view.on('itemclick', function(view, record){ + console.log("user: " + record.get('id') ); this.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'}); }, this); } diff --git a/app/models/customer.rb b/app/models/customer.rb index bc47613..83c1c99 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -2,7 +2,17 @@ class Customer < ActiveRecord::Base attr_accessible :first_name, :last_name, :addrStreet1, :addrStreet2, :addrCity, :addrState, :addrZip, :phone, :email - has_many :transactions + has_many :transactions, :as => :customer + + validates :first_name, :presence => true + validates :last_name, :presence => true + #validates :addrStreet1, :presence => true + #validates :addrStreet2, :presence => true + #validates :addrCity, :presence => true + #validates :addrState, :presence => true + #validates :addrZip, :presence => true + #validates :phone, :presence => true + #validates :email, :presence => true def to_s "#{first_name} #{last_name}" diff --git a/app/models/transaction.rb b/app/models/transaction.rb index bdebc68..66e93f6 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -5,7 +5,7 @@ class Transaction < ActiveRecord::Base belongs_to :vendor, :class_name => 'User', :foreign_key => 'vendor_id' belongs_to :bike - belongs_to :customer + belongs_to :customer, :polymorphic => true validates :vendor_id, :presence => true validates :customer_id, :presence => { :message => "Choose a User or Customer"} diff --git a/db/migrate/20121205043759_create_transactions.rb b/db/migrate/20121205043759_create_transactions.rb index bb325fa..bba51db 100644 --- a/db/migrate/20121205043759_create_transactions.rb +++ b/db/migrate/20121205043759_create_transactions.rb @@ -3,7 +3,7 @@ class CreateTransactions < ActiveRecord::Migration create_table :transactions do |t| t.integer "vendor_id", :null => false t.integer "customer_id", :null => false - t.integer "customer_type", :null => false + t.string "customer_type", :null => false t.integer "bike_id" t.integer "amount", :null => false t.string "item", :null => false diff --git a/db/schema.rb b/db/schema.rb index 244ac23..f76382c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -104,8 +104,8 @@ ActiveRecord::Schema.define(:version => 20130120142249) do create_table "transactions", :force => true do |t| t.integer "vendor_id", :null => false - t.integer "customer_id" - t.integer "customer_type" + t.integer "customer_id", :null => false + t.string "customer_type", :null => false t.integer "bike_id" t.integer "amount", :null => false t.string "item", :null => false From 55d0b8f2f7824db1e54b383d02d7366179d391b7 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Wed, 23 Jan 2013 00:09:39 -0500 Subject: [PATCH 6/8] Some Transactions view adjustments -moved js to customers and users components, in order to use accordion. -Made the transaction form a little prettier --- app/components/app_tab_panel.rb | 2 +- app/components/bikes_border.rb | 1 + app/components/customers.rb | 11 +++++++++++ .../customers/javascripts/init_component.js | 11 +++++++++++ app/components/transactions.rb | 7 ++++++- app/components/transactions_border.rb | 11 +++++------ .../javascripts/init_component.js | 19 ------------------- app/components/users.rb | 14 +++++++++++++- .../users/javascripts/init_component.js | 11 +++++++++++ .../users_and_customers_accordian.rb | 10 ++++++++++ app/components/users_and_profiles_border.rb | 2 +- app/models/customer.rb | 2 ++ 12 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 app/components/customers/javascripts/init_component.js delete mode 100644 app/components/transactions_border/javascripts/init_component.js create mode 100644 app/components/users/javascripts/init_component.js create mode 100644 app/components/users_and_customers_accordian.rb diff --git a/app/components/app_tab_panel.rb b/app/components/app_tab_panel.rb index dddcc10..da91645 100644 --- a/app/components/app_tab_panel.rb +++ b/app/components/app_tab_panel.rb @@ -10,7 +10,7 @@ class AppTabPanel < Netzke::Basepack::TabPanel #all users # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items = [ :transactions_border, :bikes_border, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] + @@app_tab_panel_items = [ :transactions_border, {layout: :fit, wrappedComponent: :bikes_border, title: "Bikes"}, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] #for users if controller.current_user.user? diff --git a/app/components/bikes_border.rb b/app/components/bikes_border.rb index a3480dc..ab626da 100644 --- a/app/components/bikes_border.rb +++ b/app/components/bikes_border.rb @@ -6,6 +6,7 @@ class BikesBorder < Netzke::Base def configure(c) super + c.header = false c.title = "Bikes" c.items = [ { netzke_component: :bikes, region: :center, split: true }, diff --git a/app/components/customers.rb b/app/components/customers.rb index d0e8a2c..89a75c7 100644 --- a/app/components/customers.rb +++ b/app/components/customers.rb @@ -7,4 +7,15 @@ class Customers < Netzke::Basepack::Grid def default_bbar [ :apply, :add_in_form, :search ] end + + #needed for transactions customer selection + js_configure do |c| + c.mixin :init_component + end + + #needed for transactions customer selection + endpoint :select_customer do |params, this| + session[:selected_customer_id] = params[:customer_id] + session[:selected_customer_type] = params[:customer_type] + end end diff --git a/app/components/customers/javascripts/init_component.js b/app/components/customers/javascripts/init_component.js new file mode 100644 index 0000000..29aa00c --- /dev/null +++ b/app/components/customers/javascripts/init_component.js @@ -0,0 +1,11 @@ +{ + initComponent: function(){ + // calling superclass's initComponent + this.callParent(); + this.getView().on('itemclick', function(view, record){ + // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! + console.log("user: " + record.get('id') ); + this.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'}); + }, this); + } +} diff --git a/app/components/transactions.rb b/app/components/transactions.rb index dcfcc27..0246f39 100644 --- a/app/components/transactions.rb +++ b/app/components/transactions.rb @@ -15,6 +15,11 @@ class Transactions < Netzke::Basepack::Grid user = rec.vendor user.nil? ? "" : "#{user.first_name} #{user.last_name}" } + }, + { :name => :customer, :getter => lambda { |rec| + user = rec.customer + user.nil? ? "" : "#{user.first_name} #{user.last_name}" + } } ] @@ -32,7 +37,7 @@ class Transactions < Netzke::Basepack::Grid customer = "No User Selected" if customer.nil? [ - { :no_binding => true, :xtype => 'label', :text => "Creating Transaction for: #{customer.to_s}"}, + { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Creating Transaction for:", :value => "#{customer.to_s}"}, :amount, :item, { :name => :for_bike, :checkboxName => :bike_item, :inputValue => true, :title => "Selling a bike?", diff --git a/app/components/transactions_border.rb b/app/components/transactions_border.rb index c347975..29bf7c9 100644 --- a/app/components/transactions_border.rb +++ b/app/components/transactions_border.rb @@ -1,18 +1,17 @@ class TransactionsBorder < Netzke::Base # Remember regions collapse state and size include Netzke::Basepack::ItemPersistence - #users and customers components are required for the transactions form component :transactions - component :users - component :customers + #users and customers components are required for the transactions form + component :users_and_customers_accordian def configure(c) super c.header = false + c.title = "Transactions" c.items = [ - { netzke_component: :transactions, region: :west, width: 300, split: true }, - { netzke_component: :users, region: :center, width: 300, split: true }, - { netzke_component: :customers, region: :east, width: 300, split: true } + { netzke_component: :transactions, region: :center, height: 300, split: true }, + { netzke_component: :users_and_customers_accordian, region: :south, height: 300, split: true } ] end diff --git a/app/components/transactions_border/javascripts/init_component.js b/app/components/transactions_border/javascripts/init_component.js deleted file mode 100644 index da0c444..0000000 --- a/app/components/transactions_border/javascripts/init_component.js +++ /dev/null @@ -1,19 +0,0 @@ -{ - initComponent: function(){ - // calling superclass's initComponent - this.callParent(); - - // setting the 'rowclick' event - var user_view = this.getComponent('users').getView(); - var customer_view = this.getComponent('customers').getView(); - user_view.on('itemclick', function(view, record){ - // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! - console.log("user: " + record.get('id') ); - this.selectCustomer({customer_id: record.get('id'), customer_type: 'User'}); - }, this); - customer_view.on('itemclick', function(view, record){ - console.log("user: " + record.get('id') ); - this.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'}); - }, this); - } -} diff --git a/app/components/users.rb b/app/components/users.rb index e545993..5934bd2 100644 --- a/app/components/users.rb +++ b/app/components/users.rb @@ -1,6 +1,7 @@ class Users < Netzke::Basepack::Grid def configure(c) super + c.header = false c.model = "User" c.columns = [ @@ -15,6 +16,17 @@ class Users < Netzke::Basepack::Grid #override with nil to remove actions def default_bbar - [ :apply, :add_in_form ] + [ :apply, :add_in_form, :search ] + end + + #needed for transactions customer selection + js_configure do |c| + c.mixin :init_component + end + + #needed for transactions customer selection + endpoint :select_customer do |params, this| + session[:selected_customer_id] = params[:customer_id] + session[:selected_customer_type] = params[:customer_type] end end diff --git a/app/components/users/javascripts/init_component.js b/app/components/users/javascripts/init_component.js new file mode 100644 index 0000000..d330667 --- /dev/null +++ b/app/components/users/javascripts/init_component.js @@ -0,0 +1,11 @@ +{ + initComponent: function(){ + // calling superclass's initComponent + this.callParent(); + this.getView().on('itemclick', function(view, record){ + // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! + console.log("user: " + record.get('id') ); + this.selectCustomer({customer_id: record.get('id'), customer_type: 'User'}); + }, this); + } +} diff --git a/app/components/users_and_customers_accordian.rb b/app/components/users_and_customers_accordian.rb new file mode 100644 index 0000000..841aef7 --- /dev/null +++ b/app/components/users_and_customers_accordian.rb @@ -0,0 +1,10 @@ +class UsersAndCustomersAccordian < Netzke::Basepack::Accordion + component :customers + component :users + + def configure(c) + c.prevent_header = true + c.items = [ :customers, :users ] + super + end +end diff --git a/app/components/users_and_profiles_border.rb b/app/components/users_and_profiles_border.rb index 11b6209..e91cb5a 100644 --- a/app/components/users_and_profiles_border.rb +++ b/app/components/users_and_profiles_border.rb @@ -9,7 +9,7 @@ class UsersAndProfilesBorder < Netzke::Base super c.header = false c.items = [ - { netzke_component: :users, region: :center, width: 300, split: true }, + { netzke_component: :users, header: "Users", region: :center, width: 300, split: true }, { netzke_component: :user_profiles, region: :south, height: 150, split: true}, { netzke_component: :user_logs, region: :east, split: true} ] diff --git a/app/models/customer.rb b/app/models/customer.rb index 83c1c99..90d8673 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -14,6 +14,8 @@ class Customer < ActiveRecord::Base #validates :phone, :presence => true #validates :email, :presence => true + self.per_page = 15 + def to_s "#{first_name} #{last_name}" end From 873bccb0307e67a5d31c5eeb325fb7a871f7f262 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sat, 2 Feb 2013 14:08:42 -0500 Subject: [PATCH 7/8] Completed adding transactions --- app/components/app_tab_panel.rb | 24 ++++++- app/components/bike_logs.rb | 1 + app/components/transaction_logs.rb | 67 +++++++++++++++++++ app/components/transactions.rb | 13 +++- app/components/transactions_border.rb | 9 +-- .../javascripts/init_component.js | 14 ++++ app/components/user_logs.rb | 1 + app/components/user_transactions.rb | 40 +++++++++++ app/components/user_transactions_border.rb | 27 ++++++++ .../javascripts/init_component.js | 14 ++++ .../acts_as_loggable/transaction_action.rb | 5 +- 11 files changed, 203 insertions(+), 12 deletions(-) create mode 100644 app/components/transaction_logs.rb create mode 100644 app/components/transactions_border/javascripts/init_component.js create mode 100644 app/components/user_transactions.rb create mode 100644 app/components/user_transactions_border.rb create mode 100644 app/components/user_transactions_border/javascripts/init_component.js diff --git a/app/components/app_tab_panel.rb b/app/components/app_tab_panel.rb index da91645..1b92ebb 100644 --- a/app/components/app_tab_panel.rb +++ b/app/components/app_tab_panel.rb @@ -10,17 +10,35 @@ class AppTabPanel < Netzke::Basepack::TabPanel #all users # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items = [ :transactions_border, {layout: :fit, wrappedComponent: :bikes_border, title: "Bikes"}, {layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"}] + @@app_tab_panel_items = [ { layout: :fit, + wrappedComponent: :bikes_border, + title: "Bikes"}, + { layout: :fit, + wrappedComponent: :brands_and_models_border, + title: "Brands/Models"} + ] #for users if controller.current_user.user? # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items.concat [{ layout: :fit, wrappedComponent: :user_profile_border, title: "Profile"}] + @@app_tab_panel_items.concat [{ layout: :fit, + wrappedComponent: :user_profile_border, + title: "Profile"}, + { layout: :fit, + wrappedComponent: :user_transactions_border, + title: "Transactions"} + ] end #for admins if controller.current_user.admin? # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items.concat [{ layout: :fit, wrappedComponent: :users_and_profiles_border, title: "Users/Profiles"}, :logs] + @@app_tab_panel_items.concat [{ layout: :fit, + wrappedComponent: :users_and_profiles_border, + title: "Users/Profiles"}, + { layout: :fit, + wrappedComponent: :transactions_border, + title: "Transactions"}, + :logs] end @@app_tab_panel_items.each do |item| diff --git a/app/components/bike_logs.rb b/app/components/bike_logs.rb index 9564af4..9c0b1fe 100644 --- a/app/components/bike_logs.rb +++ b/app/components/bike_logs.rb @@ -44,6 +44,7 @@ class BikeLogs < Netzke::Basepack::Grid { :name => :start_date}, { :name => :end_date}, { :name => :description}, + #had to hack acts_as_loggable/log.rb to get this to work { :name => :bike_action__action, :field_label => 'Action'} ] end diff --git a/app/components/transaction_logs.rb b/app/components/transaction_logs.rb new file mode 100644 index 0000000..7cbdc4e --- /dev/null +++ b/app/components/transaction_logs.rb @@ -0,0 +1,67 @@ +class TransactionLogs < Netzke::Basepack::Grid + + def configure(c) + super + + c.model = "ActsAsLoggable::Log" + c.title = "Transaction Payments" + c.data_store = {auto_load: false} + c.scope = lambda { |rel| rel.where(:loggable_type => 'Transaction',:loggable_id => session[:selected_transaction_id]);} + c.strong_default_attrs = { + :loggable_type => 'Transaction', + :loggable_id => session[:selected_transaction_id], + :log_action_type => 'ActsAsLoggable::TransactionAction', + :logger_type => 'User', + :logger_id => controller.current_user.id, + :start_date => Time.now.to_formatted_s(:db), + :end_date => Time.now.to_formatted_s(:db) + } + + c.columns = [ + { :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db), :text => 'Date' }, + { :name => :description, :text => "Amount"} , + { :name => :transaction_action__action, :text => 'Method'}, + { :name => :logged_by, :getter => lambda{ |rec| + user = User.find_by_id(rec.logger_id) + user.nil? ? "" : "#{user.first_name} #{user.last_name}" + }, + :text => "Processed by" + } + ] + + if controller.current_user.user? + c.prohibit_update = true + c.prohibit_create = true + c.prohibit_delete = true + end + + end + + def default_fields_for_forms + customer = nil + item = nil + if session[:selected_transaction_id] + trans = Transaction.find_by_id(session[:selected_transaction_id]) + customer = trans.customer + item = trans.item + end + customer = "No Customer Selected" if customer.nil? + item = "No Item Selected" if item.nil? + [ + { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Payment from:", :value => "#{customer.to_s}"}, + { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Payment for:", :value => "#{item.to_s}"}, + { :name => :description, :xtype => 'numberfield', :field_label => 'Amount'}, + #had to hack acts_as_loggable/log.rb to get this to work + { :name => :transaction_action__action, :field_label => 'Payment Method'} + ] + end + + + #override with nil to remove actions + def default_bbar + bbar = [ :search ] + bbar.concat [ :apply, :add_in_form ] if not controller.current_user.user? + bbar + end + +end diff --git a/app/components/transactions.rb b/app/components/transactions.rb index 0246f39..4fe60bd 100644 --- a/app/components/transactions.rb +++ b/app/components/transactions.rb @@ -20,9 +20,10 @@ class Transactions < Netzke::Basepack::Grid user = rec.customer user.nil? ? "" : "#{user.first_name} #{user.last_name}" } - } + }, + :created_at ] - + end def default_fields_for_forms @@ -34,7 +35,7 @@ class Transactions < Netzke::Basepack::Grid elsif session[:selected_customer_type] == "Customer" customer = Customer.find_by_id(session[:selected_customer_id]) end - + customer = "No User Selected" if customer.nil? [ { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Creating Transaction for:", :value => "#{customer.to_s}"}, @@ -52,4 +53,10 @@ class Transactions < Netzke::Basepack::Grid def default_bbar [ :apply, :add_in_form, :search ] end +=begin + #needed for transaction selection + js_configure do |c| + c.mixin :init_component + end +=end end diff --git a/app/components/transactions_border.rb b/app/components/transactions_border.rb index 29bf7c9..b66296f 100644 --- a/app/components/transactions_border.rb +++ b/app/components/transactions_border.rb @@ -2,6 +2,7 @@ class TransactionsBorder < Netzke::Base # Remember regions collapse state and size include Netzke::Basepack::ItemPersistence component :transactions + component :transaction_logs #users and customers components are required for the transactions form component :users_and_customers_accordian @@ -11,6 +12,7 @@ class TransactionsBorder < Netzke::Base c.title = "Transactions" c.items = [ { netzke_component: :transactions, region: :center, height: 300, split: true }, + { netzke_component: :transaction_logs, region: :east, width: 300, split: true }, { netzke_component: :users_and_customers_accordian, region: :south, height: 300, split: true } ] end @@ -21,9 +23,8 @@ class TransactionsBorder < Netzke::Base c.mixin :init_component end - endpoint :select_customer do |params, this| - session[:selected_customer_id] = params[:customer_id] - session[:selected_customer_type] = params[:customer_type] + endpoint :select_transaction do |params, this| + session[:selected_transaction_id] = params[:transaction_id] end - + end diff --git a/app/components/transactions_border/javascripts/init_component.js b/app/components/transactions_border/javascripts/init_component.js new file mode 100644 index 0000000..5d41919 --- /dev/null +++ b/app/components/transactions_border/javascripts/init_component.js @@ -0,0 +1,14 @@ +{ + initComponent: function(){ + // calling superclass's initComponent + this.callParent(); + + // setting the 'rowclick' event + var view = this.getComponent('transactions').getView(); + view.on('itemclick', function(view, record){ + // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! + this.selectTransaction({transaction_id: record.get('id')}); + this.getComponent('transaction_logs').getStore().load(); + }, this); + } +} diff --git a/app/components/user_logs.rb b/app/components/user_logs.rb index c5dfbbf..ee0aebd 100644 --- a/app/components/user_logs.rb +++ b/app/components/user_logs.rb @@ -58,6 +58,7 @@ class UserLogs < Netzke::Basepack::Grid { :name => :start_date}, { :name => :end_date}, { :name => :description}, + #had to hack acts_as_loggable/log.rb to get this to work { :name => :user_action__action, :field_label => 'Action', :value => action_id}, { :name => :for_bike, :checkboxName => :copy_log, :inputValue => true, :title => "Copy description to a Bike's History?", :xtype => 'fieldset', :checkboxToggle => true, :collapsed => true, :items => [ {:xtype => 'combo', :no_binding => true, :name => :copy_id, :title => 'Bike', :fieldLabel => 'Bike', :store => bike_store, :value => bike_id} diff --git a/app/components/user_transactions.rb b/app/components/user_transactions.rb new file mode 100644 index 0000000..78688a3 --- /dev/null +++ b/app/components/user_transactions.rb @@ -0,0 +1,40 @@ +class UserTransactions < Netzke::Basepack::Grid + + def configure(c) + super + + c.model = "Transaction" + c.title = "Transactions" + c.scope = lambda { |rel| rel.where(:customer_id => controller.current_user.id, :customer_type => 'User');} + c.data_store = { auto_load: true } + c.columns = [ + :amount, + :item, + { :name => :bike__serial_number}, + { :name => :vendor, :getter => lambda { |rec| + user = rec.vendor + user.nil? ? "" : "#{user.first_name} #{user.last_name}" + } + }, + { :name => :customer, :getter => lambda { |rec| + user = rec.customer + user.nil? ? "" : "#{user.first_name} #{user.last_name}" + } + }, + :created_at + ] + + if controller.current_user.user? + c.prohibit_update = true + c.prohibit_create = true + c.prohibit_delete = true + end + end + + #override with nil to remove actions + def default_bbar + bbar = [ :search ] + bbar.concat [ :apply, :add_in_form ] if not controller.current_user.user? + bbar + end +end diff --git a/app/components/user_transactions_border.rb b/app/components/user_transactions_border.rb new file mode 100644 index 0000000..0b50dd1 --- /dev/null +++ b/app/components/user_transactions_border.rb @@ -0,0 +1,27 @@ +class UserTransactionsBorder < Netzke::Base + # Remember regions collapse state and size + include Netzke::Basepack::ItemPersistence + component :user_transactions + component :transaction_logs + + def configure(c) + super + c.header = false + c.title = "Transactions" + c.items = [ + { netzke_component: :user_transactions, region: :center, height: 300, split: true }, + { netzke_component: :transaction_logs, region: :south, height: 300, split: true } + ] + end + + js_configure do |c| + c.layout = :border + c.border = false + c.mixin :init_component + end + + endpoint :select_transaction do |params, this| + session[:selected_transaction_id] = params[:transaction_id] + end + +end diff --git a/app/components/user_transactions_border/javascripts/init_component.js b/app/components/user_transactions_border/javascripts/init_component.js new file mode 100644 index 0000000..8266a14 --- /dev/null +++ b/app/components/user_transactions_border/javascripts/init_component.js @@ -0,0 +1,14 @@ +{ + initComponent: function(){ + // calling superclass's initComponent + this.callParent(); + + // setting the 'rowclick' event + var view = this.getComponent('user_transactions').getView(); + view.on('itemclick', function(view, record){ + // The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server! + this.selectTransaction({transaction_id: record.get('id')}); + this.getComponent('transaction_logs').getStore().load(); + }, this); + } +} diff --git a/app/models/acts_as_loggable/transaction_action.rb b/app/models/acts_as_loggable/transaction_action.rb index f4a2307..fbf95b7 100644 --- a/app/models/acts_as_loggable/transaction_action.rb +++ b/app/models/acts_as_loggable/transaction_action.rb @@ -1,7 +1,8 @@ class ActsAsLoggable::TransactionAction < ActiveRecord::Base attr_accessible :action - - belongs_to :bike + + has_many :logs + #belongs_to :bike def to_s self.action From 1fbf183603a70c4254eb71e0be6257efb0528661 Mon Sep 17 00:00:00 2001 From: Jason Denney Date: Sat, 2 Feb 2013 14:26:51 -0500 Subject: [PATCH 8/8] Use latest acts_as_loggable, switch to not wrapping bikes_border because, netzke? --- Gemfile.lock | 4 ++-- app/components/app_tab_panel.rb | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c896874..2afb47b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,8 @@ GIT remote: git@github.com:spacemunkay/acts_as_loggable.git - revision: fd2c276abad00567a294a1a841dce9861e240c82 + revision: 6033fe5a44878bb374f73fe473fed9a3396ddc74 specs: - acts_as_loggable (0.0.6) + acts_as_loggable (0.0.7) activerecord (>= 3.0) activesupport (~> 3.0) diff --git a/app/components/app_tab_panel.rb b/app/components/app_tab_panel.rb index 1b92ebb..6b346a6 100644 --- a/app/components/app_tab_panel.rb +++ b/app/components/app_tab_panel.rb @@ -10,9 +10,7 @@ class AppTabPanel < Netzke::Basepack::TabPanel #all users # (had to use hash for borders to get the title to display properly) - @@app_tab_panel_items = [ { layout: :fit, - wrappedComponent: :bikes_border, - title: "Bikes"}, + @@app_tab_panel_items = [ :bikes_border, { layout: :fit, wrappedComponent: :brands_and_models_border, title: "Brands/Models"} @@ -49,7 +47,6 @@ class AppTabPanel < Netzke::Basepack::TabPanel end end - c.active_tab = 0 c.prevent_header = true c.tbar = [:sign_out] c.items = @@app_tab_panel_items