mirror of
https://github.com/fspc/BikeShed-1.git
synced 2026-09-17 00:41:38 -04:00
Compare commits
95
Commits
v0.0.0
...
0.0.1-vpede
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed1f2e6be4 | ||
|
|
852a00881e | ||
|
|
8cc72c9f48 | ||
|
|
90b3043d67 | ||
|
|
2ad9fab243 | ||
|
|
43db139dc7 | ||
|
|
2b72094f00 | ||
|
|
1aa3b16636 | ||
|
|
af05d1a0c6 | ||
|
|
076a59ab45 | ||
|
|
1075c1a5b3 | ||
|
|
65708e743d | ||
|
|
731d0ed3da | ||
|
|
592049b0e6 | ||
|
|
c73d5f955a | ||
|
|
966c36b563 | ||
|
|
20a350adf2 | ||
|
|
bca0903862 | ||
|
|
5212011256 | ||
|
|
ea79c167eb | ||
|
|
85129dccaa | ||
|
|
eeefe25227 | ||
|
|
d0b2144b28 | ||
|
|
3ba443397e | ||
|
|
4a67ebe77e | ||
|
|
cda94cf955 | ||
|
|
1f9bd4f3a0 | ||
|
|
490c9d84b6 | ||
|
|
84ed8503d1 | ||
|
|
75f4a7980b | ||
|
|
16cda6aa86 | ||
|
|
de338276c0 | ||
|
|
25808eb27a | ||
|
|
d983647e29 | ||
|
|
cb4763c172 | ||
|
|
3d6f698fb9 | ||
|
|
f7ce96152b | ||
|
|
4c8f74acf2 | ||
|
|
c2b8a13db2 | ||
|
|
77d7fad3ce | ||
|
|
3bea39b53a | ||
|
|
4eae374aa9 | ||
|
|
dc60630d2d | ||
|
|
6e92d343a5 | ||
|
|
2ceb744925 | ||
|
|
b27d682517 | ||
|
|
ba0f84a97c | ||
|
|
9300ef83d1 | ||
|
|
4aed82cf80 | ||
|
|
83bdaf5973 | ||
|
|
d94d747373 | ||
|
|
da176e00ba | ||
|
|
f17c168d1d | ||
|
|
5e042c2577 | ||
|
|
bceac0543a | ||
|
|
3faa19bc0c | ||
|
|
bbba67d7d5 | ||
|
|
6cbe0f8b57 | ||
|
|
86ada003d6 | ||
|
|
9a78478f1a | ||
|
|
8d8058dea0 | ||
|
|
93b8e3b055 | ||
|
|
cfeb6fd1d2 | ||
|
|
ec5db646a0 | ||
|
|
de266e72d9 | ||
|
|
67c51068cc | ||
|
|
8c6513099d | ||
|
|
47f616b7b0 | ||
|
|
087325c444 | ||
|
|
3c4e5c21c2 | ||
|
|
69c01b8225 | ||
|
|
0aa9c16dbd | ||
|
|
e491c0530c | ||
|
|
3599cc2bbb | ||
|
|
cecb3b1a32 | ||
|
|
611b1b1151 | ||
|
|
5e80c8866a | ||
|
|
835e73ea97 | ||
|
|
cb2acd19ba | ||
|
|
ee12bfee8a | ||
|
|
4d008163e1 | ||
|
|
06856f115c | ||
|
|
a9fb3487a1 | ||
|
|
869b67d3e4 | ||
|
|
cd4f891c95 | ||
|
|
71a4bb0af4 | ||
|
|
f1214ab7e6 | ||
|
|
aaa6fda90c | ||
|
|
4a7751959c | ||
|
|
028a45702e | ||
|
|
1a8b9c9247 | ||
|
|
4e7f3a1761 | ||
|
|
a6b41b5560 | ||
|
|
4d7634605c | ||
|
|
cf922be1b1 |
@@ -7,5 +7,6 @@ tmp/
|
|||||||
.rbenv-version
|
.rbenv-version
|
||||||
.DS_Store
|
.DS_Store
|
||||||
public/extjs
|
public/extjs
|
||||||
|
public/assets
|
||||||
public/images/icons
|
public/images/icons
|
||||||
config/database.yml
|
config/database.yml
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ group :development, :test do
|
|||||||
gem 'rspec-rails', '~> 2.8.1'
|
gem 'rspec-rails', '~> 2.8.1'
|
||||||
gem 'factory_girl_rails', '~> 1.2'
|
gem 'factory_girl_rails', '~> 1.2'
|
||||||
gem 'pry', '~> 0.9.8'
|
gem 'pry', '~> 0.9.8'
|
||||||
|
gem 'faker'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
|||||||
+9
-6
@@ -1,6 +1,6 @@
|
|||||||
GIT
|
GIT
|
||||||
remote: https://github.com/spacemunkay/acts_as_loggable.git
|
remote: https://github.com/spacemunkay/acts_as_loggable.git
|
||||||
revision: 49e264849ed9018445fb999cacfc55e1e28d7faa
|
revision: 8484dc1f7a58699705c5ffb593ebdf700a9f374a
|
||||||
specs:
|
specs:
|
||||||
acts_as_loggable (0.0.7)
|
acts_as_loggable (0.0.7)
|
||||||
activerecord (>= 3.0)
|
activerecord (>= 3.0)
|
||||||
@@ -77,6 +77,8 @@ GEM
|
|||||||
factory_girl_rails (1.7.0)
|
factory_girl_rails (1.7.0)
|
||||||
factory_girl (~> 2.6.0)
|
factory_girl (~> 2.6.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
|
faker (1.2.0)
|
||||||
|
i18n (~> 0.5)
|
||||||
ffi (1.6.0)
|
ffi (1.6.0)
|
||||||
formatador (0.2.4)
|
formatador (0.2.4)
|
||||||
gherkin (2.11.6)
|
gherkin (2.11.6)
|
||||||
@@ -122,13 +124,13 @@ GEM
|
|||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
method_source (0.8.1)
|
method_source (0.8.1)
|
||||||
mime-types (1.22)
|
mime-types (1.22)
|
||||||
multi_json (1.7.2)
|
multi_json (1.8.2)
|
||||||
netzke-basepack (0.8.2)
|
netzke-basepack (0.8.4)
|
||||||
netzke-core (~> 0.8.2)
|
netzke-core (~> 0.8.2)
|
||||||
netzke-cancan (0.8.2)
|
netzke-cancan (0.8.2)
|
||||||
cancan
|
cancan
|
||||||
netzke-core
|
netzke-core
|
||||||
netzke-core (0.8.3)
|
netzke-core (0.8.4)
|
||||||
execjs
|
execjs
|
||||||
uglifier
|
uglifier
|
||||||
nokogiri (1.5.9)
|
nokogiri (1.5.9)
|
||||||
@@ -207,8 +209,8 @@ GEM
|
|||||||
less-rails (~> 2.2.2)
|
less-rails (~> 2.2.2)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
therubyracer (~> 0.10.1)
|
therubyracer (~> 0.10.1)
|
||||||
tzinfo (0.3.37)
|
tzinfo (0.3.38)
|
||||||
uglifier (1.3.0)
|
uglifier (2.1.2)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
multi_json (~> 1.0, >= 1.0.2)
|
multi_json (~> 1.0, >= 1.0.2)
|
||||||
warden (1.1.1)
|
warden (1.1.1)
|
||||||
@@ -231,6 +233,7 @@ DEPENDENCIES
|
|||||||
decent_exposure (~> 1.0.1)
|
decent_exposure (~> 1.0.1)
|
||||||
devise (~> 2.0.4)
|
devise (~> 2.0.4)
|
||||||
factory_girl_rails (~> 1.2)
|
factory_girl_rails (~> 1.2)
|
||||||
|
faker
|
||||||
guard-rspec
|
guard-rspec
|
||||||
guard-spork
|
guard-spork
|
||||||
haml-rails (~> 0.3.4)
|
haml-rails (~> 0.3.4)
|
||||||
|
|||||||
@@ -1,3 +1,25 @@
|
|||||||
|
# About
|
||||||
|
A web application for bicycle collectives to track bicycles, bicycle work history, volunteer hours, volunteer work history, and volunteers currently in the shop.
|
||||||
|
|
||||||
|
See an overview video of what it looks like and how it works here: https://www.youtube.com/watch?v=0-JjM6d9nK4.
|
||||||
|
|
||||||
|
## Instructions/Guides
|
||||||
|
|
||||||
|
### Adding a User
|
||||||
|
To add a user, a user must sign themselves up from the initial login screen. An admin can later log in to grant that user admin privileges afterward, if desired.
|
||||||
|
|
||||||
|
### Adding a Bike
|
||||||
|
How to add a bike to the database: https://www.youtube.com/watch?v=1IchWUdMQ90.
|
||||||
|
|
||||||
|
## Views
|
||||||
|
The app has two different views. One for "core" volunteers which I consider admins, and another for "customer" volunteers which I consider users. Because of the Netzke/ExtJS framework I used, the current UI is non-intuitive and I feel like is only adequate for admins who can take the time to learn the system. I'm in the process of designing a simpler mobile friendly UI with the essential functionality that's intended for users.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
Currently, at the Velocipede collective we have it running on a computer in the shop on the local network. The reason for this, is so that it's only accessible from within the shop. I'm weighing out different methods for ensuring that users can only log in from within the shop (and not from home), such as a shop password that only admins can see and would make visible from within the physical bike shop. I also don't have to worry about security issues while the app is in development. In the future, I'd like to see the app hosted much like http://freehub.bikekitchen.org/.
|
||||||
|
|
||||||
|
## Ideas
|
||||||
|
At Velocipede, with a mobile friendly UI for users, I'm hoping we can get donations of old, unused smart phones, connected via local wifi, that can be used as stations to log a volunteer's work and hours. They can be secured by gluing cables into the earphone jacks to deter theft if necessary. This might be another way that the collective can promote reuse of materials.
|
||||||
|
|
||||||
# Developer Setup
|
# Developer Setup
|
||||||
|
|
||||||
1. use rvm
|
1. use rvm
|
||||||
@@ -5,6 +27,8 @@
|
|||||||
1. `gem install bundler`
|
1. `gem install bundler`
|
||||||
1. `bundle`
|
1. `bundle`
|
||||||
1. Install Postgres (Mac OSX instructions below)
|
1. Install Postgres (Mac OSX instructions below)
|
||||||
|
1. Copy over DB config: `cp config/database.yml.example config/database.yml`
|
||||||
|
1. Update config with your database (velocipede), user (velocipede), and password.
|
||||||
1. `rake db:create db:migrate`
|
1. `rake db:create db:migrate`
|
||||||
1. `rake db:seed`
|
1. `rake db:seed`
|
||||||
1. Download extJS 4.1 (A version of 4.1 is hosted here: http://my.jasondenney.com/extjs-4.1.1.zip) Latest versions at http://www.sencha.com/products/extjs. Unzip and place where ever you like.
|
1. Download extJS 4.1 (A version of 4.1 is hosted here: http://my.jasondenney.com/extjs-4.1.1.zip) Latest versions at http://www.sencha.com/products/extjs. Unzip and place where ever you like.
|
||||||
@@ -19,8 +43,6 @@
|
|||||||
1. Start Postgres `pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start`
|
1. Start Postgres `pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start`
|
||||||
1. Create your PG user `createuser -d -P velocipede`
|
1. Create your PG user `createuser -d -P velocipede`
|
||||||
1. Create your database `createdb -U velocipede --owner=velocipede velocipede`
|
1. Create your database `createdb -U velocipede --owner=velocipede velocipede`
|
||||||
1. Copy over DB config: `cp config/database.yml.example config/database.yml`
|
|
||||||
1. Update config with your database (velocipede), user (velocipede), and password.
|
|
||||||
|
|
||||||
# Optional
|
# Optional
|
||||||
Add icons
|
Add icons
|
||||||
@@ -28,11 +50,6 @@
|
|||||||
1. Download icons from http://www.famfamfam.com/lab/icons/silk/
|
1. Download icons from http://www.famfamfam.com/lab/icons/silk/
|
||||||
1. Link to the icons under `public/images/icons`: (From app root) `ln -s /MY/PATH/famfamfam_silk_icons/icons public/images/icons`
|
1. Link to the icons under `public/images/icons`: (From app root) `ln -s /MY/PATH/famfamfam_silk_icons/icons public/images/icons`
|
||||||
|
|
||||||
## Mailcatcher
|
|
||||||
|
|
||||||
Use mailcatcher to see what emails look like in development.
|
|
||||||
Follow the instructions from http://mailcatcher.me/ to create an rvm wrapper so you don't install it all over your gemsets
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
Velocipede is released under the MIT license (http://opensource.org/licenses/MIT)
|
Velocipede is released under the MIT license (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,232 @@ Ext.Ajax.on('requestexception', function(conn, response, options) {
|
|||||||
if (response.status === 401) { window.location = '/users/sign_in'; }
|
if (response.status === 401) { window.location = '/users/sign_in'; }
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
//Override default netzke time entry field
|
||||||
|
Ext.define('Ext.ux.form.field.DateTime', {
|
||||||
|
extend:'Ext.form.FieldContainer',
|
||||||
|
mixins:{
|
||||||
|
field:'Ext.form.field.Field'
|
||||||
|
},
|
||||||
|
alias: 'widget.xdatetime',
|
||||||
|
|
||||||
|
//configurables
|
||||||
|
|
||||||
|
combineErrors: true,
|
||||||
|
msgTarget: 'under',
|
||||||
|
layout: 'hbox',
|
||||||
|
readOnly: false,
|
||||||
|
|
||||||
|
dateFormat: 'Y-m-d',
|
||||||
|
dateSubmitFormat: 'Y-m-d',
|
||||||
|
timeFormat: 'H:i:s',
|
||||||
|
timeSubmitFormat: 'H:i:s',
|
||||||
|
dateConfig:{},
|
||||||
|
timeConfig:{},
|
||||||
|
|
||||||
|
|
||||||
|
// properties
|
||||||
|
|
||||||
|
dateValue: null, // Holds the actual date
|
||||||
|
|
||||||
|
dateField: null,
|
||||||
|
|
||||||
|
hourField: null,
|
||||||
|
minuteField: null,
|
||||||
|
ampmField: null,
|
||||||
|
|
||||||
|
initComponent: function(){
|
||||||
|
var me = this
|
||||||
|
,i = 0
|
||||||
|
,key
|
||||||
|
,tab;
|
||||||
|
|
||||||
|
me.items = me.items || [];
|
||||||
|
|
||||||
|
me.dateField = Ext.create('Ext.form.field.Date', Ext.apply({
|
||||||
|
format:me.dateFormat,
|
||||||
|
flex:1,
|
||||||
|
isFormField:false, //exclude from field query's
|
||||||
|
submitValue:false,
|
||||||
|
submitFormat: me.dateSubmitFormat,
|
||||||
|
readOnly: me.readOnly
|
||||||
|
}, me.dateConfig));
|
||||||
|
me.items.push(me.dateField);
|
||||||
|
|
||||||
|
me.hourField = Ext.create('Ext.form.field.Number', {
|
||||||
|
maxWidth: 25,
|
||||||
|
allowBlank: false,
|
||||||
|
allowOnlyWhitespace: false,
|
||||||
|
blankText: "Hour cannot be blank.",
|
||||||
|
allowDecimals: false,
|
||||||
|
maxValue: 12,
|
||||||
|
minValue: 1,
|
||||||
|
maxLength: 2,
|
||||||
|
enforceMaxLength: 2,
|
||||||
|
hideTrigger: true,
|
||||||
|
submitValue:false,
|
||||||
|
flex:1,
|
||||||
|
fieldStyle: "text-align:right;",
|
||||||
|
isFormField:false, //exclude from field query's
|
||||||
|
});
|
||||||
|
me.items.push(me.hourField);
|
||||||
|
|
||||||
|
me.colon = Ext.create('Ext.draw.Text', {
|
||||||
|
text: ':',
|
||||||
|
padding: '3 3 0 3'
|
||||||
|
});
|
||||||
|
me.items.push(me.colon);
|
||||||
|
|
||||||
|
me.minuteField = Ext.create('Ext.form.field.Text', {
|
||||||
|
maxWidth: 30,
|
||||||
|
allowBlank: false,
|
||||||
|
allowOnlyWhitespace: false,
|
||||||
|
blankText: "Minutes cannot be blank.",
|
||||||
|
regex: /[012345]\d/,
|
||||||
|
maxLength: 2,
|
||||||
|
enforceMaxLength: 2,
|
||||||
|
submitValue:false,
|
||||||
|
flex:1,
|
||||||
|
isFormField:false, //exclude from field query's
|
||||||
|
});
|
||||||
|
me.items.push(me.minuteField);
|
||||||
|
|
||||||
|
|
||||||
|
me.ampmField = Ext.create('Ext.form.ComboBox', {
|
||||||
|
maxWidth: 45,
|
||||||
|
value: 'PM',
|
||||||
|
store: ['AM', 'PM'],
|
||||||
|
forceSelection: true,
|
||||||
|
flex:1,
|
||||||
|
editable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
me.items.push(me.ampmField);
|
||||||
|
|
||||||
|
for (; i < me.items.length; i++) {
|
||||||
|
me.items[i].on('focus', Ext.bind(me.onItemFocus, me));
|
||||||
|
me.items[i].on('blur', Ext.bind(me.onItemBlur, me));
|
||||||
|
me.items[i].on('specialkey', function(field, event){
|
||||||
|
key = event.getKey();
|
||||||
|
tab = key == event.TAB;
|
||||||
|
|
||||||
|
if (tab && me.focussedItem == me.dateField) {
|
||||||
|
event.stopEvent();
|
||||||
|
me.timeField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
me.fireEvent('specialkey', field, event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
me.callParent();
|
||||||
|
|
||||||
|
// this dummy is necessary because Ext.Editor will not check whether an inputEl is present or not
|
||||||
|
this.inputEl = {
|
||||||
|
dom: document.createElement('div'),
|
||||||
|
swallowEvent:function(){}
|
||||||
|
};
|
||||||
|
|
||||||
|
me.initField();
|
||||||
|
},
|
||||||
|
|
||||||
|
focus:function(){
|
||||||
|
this.callParent(arguments);
|
||||||
|
this.dateField.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
onItemFocus:function(item){
|
||||||
|
if (this.blurTask){
|
||||||
|
this.blurTask.cancel();
|
||||||
|
}
|
||||||
|
this.focussedItem = item;
|
||||||
|
},
|
||||||
|
|
||||||
|
onItemBlur:function(item, e){
|
||||||
|
var me = this;
|
||||||
|
if (item != me.focussedItem){ return; }
|
||||||
|
// 100ms to focus a new item that belongs to us, otherwise we will assume the user left the field
|
||||||
|
me.blurTask = new Ext.util.DelayedTask(function(){
|
||||||
|
me.fireEvent('blur', me, e);
|
||||||
|
});
|
||||||
|
me.blurTask.delay(100);
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function(){
|
||||||
|
var value = null
|
||||||
|
,date = this.dateField.getSubmitValue()
|
||||||
|
,time = null
|
||||||
|
,format;
|
||||||
|
|
||||||
|
hour = this.hourField.getValue();
|
||||||
|
minute = this.minuteField.getValue();
|
||||||
|
ampm = this.ampmField.getValue();
|
||||||
|
time = Ext.Date.parse(hour + " " + minute + " " + ampm, 'g i A');
|
||||||
|
time = Ext.Date.format(time, this.timeSubmitFormat);
|
||||||
|
|
||||||
|
if (date){
|
||||||
|
if (time){
|
||||||
|
format = this.getFormat();
|
||||||
|
value = Ext.Date.parse(date + ' ' + time, format);
|
||||||
|
} else {
|
||||||
|
value = this.dateField.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSubmitValue: function(){
|
||||||
|
// var value = this.getValue();
|
||||||
|
// return value ? Ext.Date.format(value, this.dateTimeFormat) : null;
|
||||||
|
|
||||||
|
var me = this
|
||||||
|
,format = me.getFormat()
|
||||||
|
,value = me.getValue();
|
||||||
|
|
||||||
|
return value ? Ext.Date.format(value, format) : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
setValue: function(value){
|
||||||
|
if (Ext.isString(value) || Ext.isDate(value)){
|
||||||
|
|
||||||
|
if( Ext.isDate(value)){
|
||||||
|
dt = value;
|
||||||
|
}else{
|
||||||
|
dt = new Date(value);
|
||||||
|
value = Ext.Date.parse(value, this.getFormat()); //this.dateTimeFormat
|
||||||
|
}
|
||||||
|
this.dateField.setValue(value);
|
||||||
|
|
||||||
|
hour = Ext.Date.format(dt, 'g');
|
||||||
|
minute = Ext.Date.format(dt, 'i');
|
||||||
|
ampm = Ext.Date.format(dt, 'A');
|
||||||
|
|
||||||
|
this.hourField.setValue(hour);
|
||||||
|
this.minuteField.setRawValue(minute);
|
||||||
|
this.ampmField.setValue(ampm);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getFormat: function(){
|
||||||
|
value = (this.dateField.submitFormat || this.dateField.format) + " " + (this.timeSubmitFormat || this.timeFormat);
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Bug? A field-mixin submits the data from getValue, not getSubmitValue
|
||||||
|
getSubmitData: function(){
|
||||||
|
var me = this
|
||||||
|
,data = null;
|
||||||
|
|
||||||
|
if (!me.disabled && me.submitValue && !me.isFileUpload()) {
|
||||||
|
data = {};
|
||||||
|
data[me.getName()] = '' + me.getSubmitValue();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ext.define('Ext.ux.form.field.ColorCombo', {
|
Ext.define('Ext.ux.form.field.ColorCombo', {
|
||||||
extend:'Ext.form.FieldContainer',
|
extend:'Ext.form.FieldContainer',
|
||||||
mixins:{
|
mixins:{
|
||||||
|
|||||||
@@ -19,11 +19,7 @@ class AppTabPanel < Netzke::Basepack::TabPanel
|
|||||||
|
|
||||||
#all users
|
#all users
|
||||||
# (had to use hash for borders to get the title to display properly)
|
# (had to use hash for borders to get the title to display properly)
|
||||||
@@app_tab_panel_items = [ :bikes_border,
|
@@app_tab_panel_items = [ :bikes_border ]
|
||||||
{ layout: :fit,
|
|
||||||
wrappedComponent: :brands_and_models_border,
|
|
||||||
title: "Brands/Models"}
|
|
||||||
]
|
|
||||||
|
|
||||||
#for users only
|
#for users only
|
||||||
if not controller.current_user.role?(:admin)
|
if not controller.current_user.role?(:admin)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ class BikeBrands < Netzke::Basepack::Grid
|
|||||||
super
|
super
|
||||||
c.model = "BikeBrand"
|
c.model = "BikeBrand"
|
||||||
c.title = "Brands"
|
c.title = "Brands"
|
||||||
|
c.force_fit = true
|
||||||
|
|
||||||
c.prohibit_update = true if cannot? :update, BikeBrand
|
c.prohibit_update = true if cannot? :update, BikeBrand
|
||||||
c.prohibit_create = true if cannot? :create, BikeBrand
|
c.prohibit_create = true if cannot? :create, BikeBrand
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ class BikeLogs < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.model = "ActsAsLoggable::Log"
|
c.model = "ActsAsLoggable::Log"
|
||||||
c.title = "Bike History"
|
c.title = "Bike History"
|
||||||
|
c.force_fit = true
|
||||||
c.data_store = {auto_load: false}
|
c.data_store = {auto_load: false}
|
||||||
c.scope = lambda { |rel| rel.where(:loggable_type => 'Bike',:loggable_id => session[:selected_bike_id]);}
|
c.scope = lambda { |rel| rel.where(:loggable_type => 'Bike',:loggable_id => session[:selected_bike_id]);}
|
||||||
c.strong_default_attrs = {
|
c.strong_default_attrs = {
|
||||||
@@ -18,12 +19,9 @@ class BikeLogs < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.columns = [
|
c.columns = [
|
||||||
{ :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
|
{ :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
|
||||||
{ :name => :end_date, :hidden => true, :default_value => Time.now.to_formatted_s(:db) },
|
{ :name => :end_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
|
||||||
{ :name => :hours, :getter => lambda { |rec| (rec.end_date - rec.start_date)/3600 }, :sorting_scope => :sort_by_duration},
|
|
||||||
:description,
|
:description,
|
||||||
{ :name => :bike_action__action, :text => 'Action'},
|
{ :name => :bike_action__action, :text => 'Action', :default_value => ::ActsAsLoggable::BikeAction.first.id},
|
||||||
{ :name => :created_at, :read_only => true},
|
|
||||||
{ :name => :updated_at, :read_only => true},
|
|
||||||
{ :name => :logged_by, :getter => lambda{ |rec|
|
{ :name => :logged_by, :getter => lambda{ |rec|
|
||||||
user = User.find_by_id(rec.logger_id)
|
user = User.find_by_id(rec.logger_id)
|
||||||
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
||||||
@@ -48,10 +46,9 @@ class BikeLogs < Netzke::Basepack::Grid
|
|||||||
def default_fields_for_forms
|
def default_fields_for_forms
|
||||||
[
|
[
|
||||||
{ :name => :start_date},
|
{ :name => :start_date},
|
||||||
{ :name => :end_date},
|
|
||||||
{ :name => :description},
|
{ :name => :description},
|
||||||
#had to hack acts_as_loggable/log.rb to get this to work
|
#had to hack acts_as_loggable/log.rb to get this to work
|
||||||
{ :name => :bike_action__action, :field_label => 'Action'}
|
{ :name => :bike_action__action, :field_label => 'Action', :min_chars => 1 }
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
class BikeLogsAndTasksAccordian < Netzke::Basepack::Accordion
|
|
||||||
component :bike_logs
|
|
||||||
component :tasks
|
|
||||||
|
|
||||||
def configure(c)
|
|
||||||
c.prevent_header = true
|
|
||||||
c.items = [ :bike_logs, :tasks ]
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class BikeLowerTabs < Netzke::Basepack::TabPanel
|
||||||
|
component :bike_logs
|
||||||
|
component :tasks
|
||||||
|
component :brands_and_models_border
|
||||||
|
|
||||||
|
def configure(c)
|
||||||
|
c.prevent_header = true
|
||||||
|
c.items = [ :bike_logs, :tasks,
|
||||||
|
{netzke_component: :brands_and_models_border, title: "Brands and Models"} ]
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,6 +4,7 @@ class BikeModels < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.model = "BikeModel"
|
c.model = "BikeModel"
|
||||||
c.title = "Models"
|
c.title = "Models"
|
||||||
|
c.force_fit = true
|
||||||
c.data_store = {auto_load: false}
|
c.data_store = {auto_load: false}
|
||||||
c.scope = lambda { |rel| rel.where(:bike_brand_id => session[:selected_bike_brand_id]);}
|
c.scope = lambda { |rel| rel.where(:bike_brand_id => session[:selected_bike_brand_id]);}
|
||||||
c.strong_default_attrs = {
|
c.strong_default_attrs = {
|
||||||
|
|||||||
+23
-14
@@ -2,11 +2,15 @@ class Bikes < Netzke::Basepack::Grid
|
|||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
c.model = "Bike"
|
c.model = "Bike"
|
||||||
|
c.force_fit = true
|
||||||
|
|
||||||
|
# columns with :id set, have :min_chars set in init_component
|
||||||
|
# See: http://stackoverflow.com/questions/17738962/netzke-grid-filtering
|
||||||
c.columns = [
|
c.columns = [
|
||||||
{ :name => :shop_id, :text => 'Shop ID'},
|
{ :name => :shop_id, :text => 'Shop ID', :default_value => Bike.last.id.to_i + 1},
|
||||||
:serial_number,
|
:serial_number,
|
||||||
{ :name => :bike_brand__brand, :text => 'Brand' },
|
{ :id => :bike_brand__brand, :name => :bike_brand__brand, :text => 'Brand'},
|
||||||
{ :name => :bike_model__model, :text => 'Model',
|
{ :name => :model, :text => 'Model',
|
||||||
:scope => lambda { |rel|
|
:scope => lambda { |rel|
|
||||||
if session[:selected_bike_brand_id]
|
if session[:selected_bike_brand_id]
|
||||||
rel.where(:bike_brand_id => session[:selected_bike_brand_id])
|
rel.where(:bike_brand_id => session[:selected_bike_brand_id])
|
||||||
@@ -16,20 +20,25 @@ class Bikes < Netzke::Basepack::Grid
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
#needs to have type :action or else won't work in grid, because... netzke
|
#needs to have type :action or else won't work in grid, because... netzke
|
||||||
{ :name => "color", :text => "Frame Color", :type => :action, :editor => { :xtype => "xcolorcombo"}, :renderer => :color_block},
|
{ :name => "color", :text => "Frame Color", :type => :action, :editor => { :xtype => "xcolorcombo"}, :renderer => :color_block,
|
||||||
{ :name => :bike_style__style, :text => 'Style' },
|
:default_value => '000000'},
|
||||||
|
{ :id => :bike_style__style, :name => :bike_style__style, :text => 'Style', :default_value => BikeStyle.first.id},
|
||||||
{ :name => :seat_tube_height, :text => 'Seat Tube (in)'},
|
{ :name => :seat_tube_height, :text => 'Seat Tube (in)'},
|
||||||
{ :name => :top_tube_length, :text => 'Top Tube (in)'},
|
{ :name => :top_tube_length, :text => 'Top Tube (in)'},
|
||||||
{ :name => :wheel_size, :text => 'Wheel Size (in)'},
|
{ :name => :bike_wheel_size__display_string, :text => 'Wheel Size'},
|
||||||
:value,
|
:value,
|
||||||
{ :name => :bike_condition__condition, :text => 'Condition'},
|
{ :id => :bike_condition__condition, :name => :bike_condition__condition, :text => 'Condition', :default_value => BikeCondition.first.id},
|
||||||
{ :name => :bike_status__status, :text => 'Status'},
|
{ :id => :bike_purpose__purpose, :name => :bike_purpose__purpose, :text => 'Purpose', :default_value => BikePurpose.first.id},
|
||||||
{ :name => :owner, :getter => lambda { |rec|
|
{ :name => :owner, :getter => lambda { |rec|
|
||||||
user = rec.owner
|
user = rec.owner
|
||||||
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Default the sorting to ASC on shop_id
|
||||||
|
c.data_store.sorters = [{ property: 'shop_id', direction: 'ASC' }]
|
||||||
|
|
||||||
@bike = Bike.all
|
@bike = Bike.all
|
||||||
c.prohibit_update = true if cannot? :update, @bike
|
c.prohibit_update = true if cannot? :update, @bike
|
||||||
c.prohibit_create = true if cannot? :create, @bike
|
c.prohibit_create = true if cannot? :create, @bike
|
||||||
@@ -38,18 +47,18 @@ class Bikes < Netzke::Basepack::Grid
|
|||||||
def default_fields_for_forms
|
def default_fields_for_forms
|
||||||
# :field_label MUST be defined in order for search to work
|
# :field_label MUST be defined in order for search to work
|
||||||
[
|
[
|
||||||
|
{ :name => :bike_brand__brand, :field_label => 'Brand', :min_chars => 1 },
|
||||||
|
{ :name => :model, :field_label => 'Model'},
|
||||||
{ :name => :shop_id, :field_label => 'Shop ID'},
|
{ :name => :shop_id, :field_label => 'Shop ID'},
|
||||||
{ :name => :serial_number, :field_label => 'Serial Number'},
|
{ :name => :serial_number, :field_label => 'Serial Number'},
|
||||||
{ :name => :bike_brand__brand, :field_label => 'Brand' },
|
|
||||||
{ :name => :bike_model__model, :field_label => 'Model'},
|
|
||||||
{ :name => "color", :xtype => "xcolorcombo"},
|
{ :name => "color", :xtype => "xcolorcombo"},
|
||||||
{ :name => :bike_style__style, :field_label => 'Style' },
|
{ :name => :bike_style__style, :field_label => 'Style', :min_chars => 1},
|
||||||
{ :name => :seat_tube_height, :field_label => 'Seat Tube (in)'},
|
{ :name => :seat_tube_height, :field_label => 'Seat Tube (in)'},
|
||||||
{ :name => :top_tube_length, :field_label => 'Top Tube (in)'},
|
{ :name => :top_tube_length, :field_label => 'Top Tube (in)'},
|
||||||
{ :name => :wheel_size, :field_label => 'Wheel Size (in)'},
|
{ :name => :bike_wheel_size__display_string, :field_label => 'Wheel Size'},
|
||||||
{ :name => :value, :field_label => 'Value'},
|
{ :name => :value, :field_label => 'Value'},
|
||||||
{ :name => :bike_condition__condition, :field_label => 'Condition'},
|
{ :name => :bike_condition__condition, :field_label => 'Condition', :min_chars => 1},
|
||||||
{ :name => :bike_status__status, :field_label => 'Status'}
|
{ :name => :bike_purpose__purpose, :field_label => 'Purpose', :min_chars => 1}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
#override with nil to remove actions
|
#override with nil to remove actions
|
||||||
|
|||||||
@@ -3,6 +3,16 @@
|
|||||||
// calling superclass's initComponent
|
// calling superclass's initComponent
|
||||||
this.callParent();
|
this.callParent();
|
||||||
|
|
||||||
|
//due to Netzke bug, :min_chars attribute doesn't work
|
||||||
|
var min_char_columns = [
|
||||||
|
"bike_brand__brand",
|
||||||
|
"bike_style__style",
|
||||||
|
"bike_condition__condition",
|
||||||
|
"bike_purpose__purpose"]
|
||||||
|
Ext.each(min_char_columns, function(column, index) {
|
||||||
|
Ext.ComponentManager.get(column).editor.minChars = 1;
|
||||||
|
});
|
||||||
|
|
||||||
// setting the 'rowclick' event
|
// setting the 'rowclick' event
|
||||||
var view = this.getView();
|
var view = this.getView();
|
||||||
view.on('itemclick', function(view, record){
|
view.on('itemclick', function(view, record){
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class BikesBorder < Netzke::Base
|
|||||||
# Remember regions collapse state and size
|
# Remember regions collapse state and size
|
||||||
include Netzke::Basepack::ItemPersistence
|
include Netzke::Basepack::ItemPersistence
|
||||||
component :bikes
|
component :bikes
|
||||||
component :bike_logs_and_tasks_accordian
|
component :bike_lower_tabs
|
||||||
|
|
||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
@@ -10,7 +10,7 @@ class BikesBorder < Netzke::Base
|
|||||||
c.title = "Bikes"
|
c.title = "Bikes"
|
||||||
c.items = [
|
c.items = [
|
||||||
{ netzke_component: :bikes, region: :center, split: true },
|
{ netzke_component: :bikes, region: :center, split: true },
|
||||||
{ netzke_component: :bike_logs_and_tasks_accordian, region: :south, height: 300, split: true}
|
{ netzke_component: :bike_lower_tabs, region: :south, height: 300, split: true}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,30 @@
|
|||||||
|
|
||||||
// setting the 'rowclick' event
|
// setting the 'rowclick' event
|
||||||
var view = this.getComponent('bikes').getView();
|
var view = this.getComponent('bikes').getView();
|
||||||
|
|
||||||
|
//disable until a bike is clicked
|
||||||
|
var bike_logs_comp = this.queryById('bike_logs');
|
||||||
|
if( bike_logs_comp){
|
||||||
|
bike_logs_comp.disable();
|
||||||
|
}
|
||||||
|
var bike_tasks_comp = this.queryById('tasks');
|
||||||
|
if( bike_tasks_comp ){
|
||||||
|
bike_tasks_comp.disable();
|
||||||
|
}
|
||||||
|
|
||||||
view.on('itemclick', function(view, record){
|
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!
|
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
|
||||||
this.selectBike({bike_id: record.get('id')});
|
this.selectBike({bike_id: record.get('id')});
|
||||||
if( this.queryById('bike_logs') ){
|
// query for these components again, can change if not visible because of accordian
|
||||||
this.queryById('bike_logs').getStore().load();
|
var bike_logs_comp = this.queryById('bike_logs');
|
||||||
|
var bike_tasks_comp = this.queryById('tasks');
|
||||||
|
if( bike_logs_comp ){
|
||||||
|
bike_logs_comp.getStore().load();
|
||||||
|
bike_logs_comp.enable();
|
||||||
}
|
}
|
||||||
if( this.queryById('tasks') ){
|
if( bike_tasks_comp ){
|
||||||
this.queryById('tasks').getStore().load();
|
bike_tasks_comp.getStore().load();
|
||||||
|
bike_tasks_comp.enable();
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class CheckIns < Netzke::Basepack::Grid
|
|||||||
super
|
super
|
||||||
c.header = false
|
c.header = false
|
||||||
c.model = "ActsAsLoggable::Log"
|
c.model = "ActsAsLoggable::Log"
|
||||||
|
c.force_fit = true
|
||||||
c.scope = lambda { |rel| rel.where(:log_action_type => ::ActsAsLoggable::UserAction).
|
c.scope = lambda { |rel| rel.where(:log_action_type => ::ActsAsLoggable::UserAction).
|
||||||
where(:loggable_type => "User").
|
where(:loggable_type => "User").
|
||||||
where(:log_action_id => ::ActsAsLoggable::UserAction.find_by_action("CHECKIN")).
|
where(:log_action_id => ::ActsAsLoggable::UserAction.find_by_action("CHECKIN")).
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
class Customers < Netzke::Basepack::Grid
|
class Customers < Netzke::Basepack::Grid
|
||||||
def configure(c)
|
def configure(c)
|
||||||
c.model = "Customer"
|
c.model = "Customer"
|
||||||
|
c.force_fit = true
|
||||||
end
|
end
|
||||||
|
|
||||||
#override with nil to remove actions
|
#override with nil to remove actions
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
this.callParent();
|
this.callParent();
|
||||||
this.getView().on('itemclick', function(view, record){
|
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!
|
// 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.selectCustomer({customer_id: record.get('id'), customer_type: 'Customer'});
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class Logs < Netzke::Basepack::Grid
|
|||||||
super
|
super
|
||||||
c.header = false
|
c.header = false
|
||||||
c.model = "ActsAsLoggable::Log"
|
c.model = "ActsAsLoggable::Log"
|
||||||
|
c.force_fit = true
|
||||||
c.columns = [
|
c.columns = [
|
||||||
:loggable_id,
|
:loggable_id,
|
||||||
:loggable_type,
|
:loggable_type,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ class Tasks < Netzke::Basepack::Grid
|
|||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
|
|
||||||
|
#disable by default, will be enabled once bike is clicked
|
||||||
|
c.disabled = true
|
||||||
task_list_id = nil
|
task_list_id = nil
|
||||||
if session[:selected_bike_id]
|
if session[:selected_bike_id]
|
||||||
task_list_id = Bike.find_by_id(session[:selected_bike_id]).task_list.id
|
task_list_id = Bike.find_by_id(session[:selected_bike_id]).task_list.id
|
||||||
@@ -9,6 +11,7 @@ class Tasks < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.header = false
|
c.header = false
|
||||||
c.model = "Task"
|
c.model = "Task"
|
||||||
|
c.force_fit = true
|
||||||
c.scope = lambda{ |rel|
|
c.scope = lambda{ |rel|
|
||||||
if session[:selected_bike_id]
|
if session[:selected_bike_id]
|
||||||
rel.where(:task_list_id => Bike.find_by_id(session[:selected_bike_id]).task_list.id)
|
rel.where(:task_list_id => Bike.find_by_id(session[:selected_bike_id]).task_list.id)
|
||||||
@@ -21,9 +24,9 @@ class Tasks < Netzke::Basepack::Grid
|
|||||||
:task_list_id => task_list_id
|
:task_list_id => task_list_id
|
||||||
}
|
}
|
||||||
c.columns = [
|
c.columns = [
|
||||||
|
:done,
|
||||||
:task,
|
:task,
|
||||||
:notes,
|
:notes
|
||||||
:done
|
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -31,9 +34,9 @@ class Tasks < Netzke::Basepack::Grid
|
|||||||
fields = []
|
fields = []
|
||||||
fields << { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "No Bike Selected", :value => "Select a Bike First!"}
|
fields << { :no_binding => true, :xtype => 'displayfield', :fieldLabel => "No Bike Selected", :value => "Select a Bike First!"}
|
||||||
fields.concat( [
|
fields.concat( [
|
||||||
|
:done,
|
||||||
:task,
|
:task,
|
||||||
:notes,
|
:notes
|
||||||
:done
|
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class TransactionLogs < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.model = "ActsAsLoggable::Log"
|
c.model = "ActsAsLoggable::Log"
|
||||||
c.title = "Transaction Payments"
|
c.title = "Transaction Payments"
|
||||||
|
c.force_fit = true
|
||||||
c.data_store = {auto_load: false}
|
c.data_store = {auto_load: false}
|
||||||
c.scope = lambda { |rel| rel.where(:loggable_type => 'Transaction',:loggable_id => session[:selected_transaction_id]);}
|
c.scope = lambda { |rel| rel.where(:loggable_type => 'Transaction',:loggable_id => session[:selected_transaction_id]);}
|
||||||
c.strong_default_attrs = {
|
c.strong_default_attrs = {
|
||||||
@@ -20,7 +21,7 @@ class TransactionLogs < Netzke::Basepack::Grid
|
|||||||
c.columns = [
|
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 => :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 => :description, :text => "Amount"} ,
|
||||||
{ :name => :transaction_action__action, :text => 'Method'},
|
{ :name => :transaction_action__action, :text => 'Method', :default_value => ::ActsAsLoggable::TransactionAction.first.id},
|
||||||
{ :name => :logged_by, :getter => lambda{ |rec|
|
{ :name => :logged_by, :getter => lambda{ |rec|
|
||||||
user = User.find_by_id(rec.logger_id)
|
user = User.find_by_id(rec.logger_id)
|
||||||
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
||||||
@@ -49,7 +50,7 @@ class TransactionLogs < Netzke::Basepack::Grid
|
|||||||
{ :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Payment for:", :value => "#{item.to_s}"},
|
{ :no_binding => true, :xtype => 'displayfield', :fieldLabel => "Payment for:", :value => "#{item.to_s}"},
|
||||||
{ :name => :description, :xtype => 'numberfield', :field_label => 'Amount'},
|
{ :name => :description, :xtype => 'numberfield', :field_label => 'Amount'},
|
||||||
#had to hack acts_as_loggable/log.rb to get this to work
|
#had to hack acts_as_loggable/log.rb to get this to work
|
||||||
{ :name => :transaction_action__action, :field_label => 'Payment Method'}
|
{ :name => :transaction_action__action, :field_label => 'Payment Method', :min_chars => 1}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ class Transactions < Netzke::Basepack::Grid
|
|||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
c.model = "Transaction"
|
c.model = "Transaction"
|
||||||
|
c.force_fit = true
|
||||||
c.strong_default_attrs = {
|
c.strong_default_attrs = {
|
||||||
:vendor_id => controller.current_user.id,
|
:vendor_id => controller.current_user.id,
|
||||||
:customer_id => session[:selected_customer_id],
|
:customer_id => session[:selected_customer_id],
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ class TransactionsBorder < Netzke::Base
|
|||||||
component :transactions
|
component :transactions
|
||||||
component :transaction_logs
|
component :transaction_logs
|
||||||
#users and customers components are required for the transactions form
|
#users and customers components are required for the transactions form
|
||||||
component :users_and_customers_accordian
|
component :users_and_customers_lower_tabs
|
||||||
|
|
||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
@@ -13,7 +13,7 @@ class TransactionsBorder < Netzke::Base
|
|||||||
c.items = [
|
c.items = [
|
||||||
{ netzke_component: :transactions, region: :center, height: 300, split: true },
|
{ netzke_component: :transactions, region: :center, height: 300, split: true },
|
||||||
{ netzke_component: :transaction_logs, region: :east, width: 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 }
|
{ netzke_component: :users_and_customers_lower_tabs, region: :south, height: 300, split: true }
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,19 @@
|
|||||||
|
|
||||||
// setting the 'rowclick' event
|
// setting the 'rowclick' event
|
||||||
var view = this.getComponent('transactions').getView();
|
var view = this.getComponent('transactions').getView();
|
||||||
|
|
||||||
|
if( this.queryById('transaction_logs')){
|
||||||
|
this.queryById('transaction_logs').disable();
|
||||||
|
}
|
||||||
|
|
||||||
view.on('itemclick', function(view, record){
|
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!
|
// 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.selectTransaction({transaction_id: record.get('id')});
|
||||||
this.getComponent('transaction_logs').getStore().load();
|
this.getComponent('transaction_logs').getStore().load();
|
||||||
|
|
||||||
|
if( this.queryById('transaction_logs')){
|
||||||
|
this.queryById('transaction_logs').enable();
|
||||||
|
}
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class UserAndProfilesLowerTabs < Netzke::Basepack::TabPanel
|
||||||
|
component :user_profiles
|
||||||
|
component :user_logs
|
||||||
|
component :user_stats
|
||||||
|
|
||||||
|
def configure(c)
|
||||||
|
c.prevent_header = true
|
||||||
|
c.items = [ :user_logs,
|
||||||
|
{ netzke_component: :user_profiles, title: "User Profiles" },
|
||||||
|
{ netzke_component: :user_stats, title: "User Stats" }]
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -34,18 +34,17 @@ class UserLogs < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.model = "ActsAsLoggable::Log"
|
c.model = "ActsAsLoggable::Log"
|
||||||
c.title = "User Timesheet"
|
c.title = "User Timesheet"
|
||||||
|
c.force_fit = true
|
||||||
c.data_store = user_log_data_store
|
c.data_store = user_log_data_store
|
||||||
c.scope = user_log_scope
|
c.scope = user_log_scope
|
||||||
c.strong_default_attrs = user_log_strong_default_attrs
|
c.strong_default_attrs = user_log_strong_default_attrs
|
||||||
|
|
||||||
c.columns = [
|
c.columns = [
|
||||||
{ :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
|
{ :name => :start_date, :format => "g:ia - D, M j - Y", :width => 165, :default_value => Time.now.to_formatted_s(:db) },
|
||||||
{ :name => :end_date, :hidden => true, :default_value => Time.now.to_formatted_s(:db) },
|
{ :name => :end_date, :format => "g:ia - D, M j - Y", :default_value => Time.now.to_formatted_s(:db) },
|
||||||
{ :name => :hours, :getter => lambda { |rec| (rec.end_date - rec.start_date)/3600 }, :sorting_scope => :sort_by_duration},
|
{ :name => :hours, :getter => lambda { |rec| (rec.end_date - rec.start_date)/3600 }, :sorting_scope => :sort_by_duration},
|
||||||
:description,
|
:description,
|
||||||
{ :name => :user_action__action, :text => 'Action', :default_value => ::ActsAsLoggable::UserAction.all.first.id },
|
{ :id => :user_action__action, :name => :user_action__action, :text => 'Action', :default_value => ::ActsAsLoggable::UserAction.all.first.id },
|
||||||
:created_at,
|
|
||||||
:updated_at,
|
|
||||||
{ :name => :logged_by, :getter => lambda{ |rec|
|
{ :name => :logged_by, :getter => lambda{ |rec|
|
||||||
user = User.find_by_id(rec.logger_id)
|
user = User.find_by_id(rec.logger_id)
|
||||||
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
||||||
@@ -65,7 +64,7 @@ class UserLogs < Netzke::Basepack::Grid
|
|||||||
{ :name => :end_date},
|
{ :name => :end_date},
|
||||||
{ :name => :description},
|
{ :name => :description},
|
||||||
#had to hack acts_as_loggable/log.rb to get this to work
|
#had to hack acts_as_loggable/log.rb to get this to work
|
||||||
{ :name => :user_action__action, :field_label => 'Action'},
|
{ :name => :user_action__action, :field_label => 'Action', :min_chars => 1},
|
||||||
{ :name => :for_bike, :checkboxName => :copy_log, :inputValue => true, :title => "Copy description to a Bike's History?", :xtype => 'fieldset', :checkboxToggle => true, :collapsed => true, :items => [
|
{ :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}
|
{:xtype => 'combo', :no_binding => true, :name => :copy_id, :title => 'Bike', :fieldLabel => 'Bike', :store => bike_store, :value => bike_id}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
initComponent: function(){
|
||||||
|
// calling superclass's initComponent
|
||||||
|
this.callParent();
|
||||||
|
|
||||||
|
//due to Netzke bug, :min_chars attribute doesn't work
|
||||||
|
var min_char_columns = [
|
||||||
|
"user_action__purpose"]
|
||||||
|
Ext.each(min_char_columns, function(column, index) {
|
||||||
|
Ext.ComponentManager.get(column).editor.minChars = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ class UserProfiles < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.model = "UserProfile"
|
c.model = "UserProfile"
|
||||||
c.title = "Profile"
|
c.title = "Profile"
|
||||||
|
c.force_fit = true
|
||||||
c.data_store = user_profiles_data_store
|
c.data_store = user_profiles_data_store
|
||||||
c.scope = user_profiles_scope
|
c.scope = user_profiles_scope
|
||||||
c.strong_default_attrs = user_profile_strong_default_attrs
|
c.strong_default_attrs = user_profile_strong_default_attrs
|
||||||
|
|||||||
@@ -2,16 +2,18 @@ class UserRoleJoins < Netzke::Basepack::Grid
|
|||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
c.model = "UserRoleJoin"
|
c.model = "UserRoleJoin"
|
||||||
|
c.force_fit = true
|
||||||
c.header = false
|
c.header = false
|
||||||
c.title = "User Roles"
|
c.title = "User Roles"
|
||||||
|
c.data_store.sorters = [{ :property => :user__username, :direction => :ASC}]
|
||||||
c.columns = [
|
c.columns = [
|
||||||
{ :name => :user__username, :text => "Username"},
|
{ :name => :user__username, :text => "Username", :read_only => true},
|
||||||
{ :name => :name, :getter => lambda{ |rec|
|
{ :name => :name, :getter => lambda{ |rec|
|
||||||
user = User.find_by_id(rec.user_id)
|
user = User.find_by_id(rec.user_id)
|
||||||
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
user.nil? ? "" : "#{user.first_name} #{user.last_name}"
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{ :name => :role__role, :text => "Role"},
|
{ :name => :role__role, :text => "Role", :default_value => Role.exists? ? Role.first.id : nil},
|
||||||
:created_at,
|
:created_at,
|
||||||
:updated_at,
|
:updated_at,
|
||||||
:ends ]
|
:ends ]
|
||||||
@@ -19,7 +21,7 @@ class UserRoleJoins < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
def default_fields_for_forms
|
def default_fields_for_forms
|
||||||
[
|
[
|
||||||
{ :name => :user__username, :field_label => 'Username' },
|
{ :name => :user__full_name, :field_label => 'Name'},
|
||||||
{ :name => :role__role, :field_label => 'Role' },
|
{ :name => :role__role, :field_label => 'Role' },
|
||||||
{ :name => :ends }
|
{ :name => :ends }
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class UserStats < Netzke::Base
|
|||||||
|
|
||||||
private
|
private
|
||||||
def user
|
def user
|
||||||
controller.current_user
|
User.find_by_id(session[:selected_user_id]) || controller.current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class UserTransactions < Netzke::Basepack::Grid
|
|||||||
|
|
||||||
c.model = "Transaction"
|
c.model = "Transaction"
|
||||||
c.title = "Transactions"
|
c.title = "Transactions"
|
||||||
|
c.force_fit = true
|
||||||
c.scope = lambda { |rel| rel.where(:customer_id => controller.current_user.id, :customer_type => 'User');}
|
c.scope = lambda { |rel| rel.where(:customer_id => controller.current_user.id, :customer_type => 'User');}
|
||||||
c.data_store = { auto_load: true }
|
c.data_store = { auto_load: true }
|
||||||
c.columns = [
|
c.columns = [
|
||||||
|
|||||||
@@ -5,10 +5,18 @@
|
|||||||
|
|
||||||
// setting the 'rowclick' event
|
// setting the 'rowclick' event
|
||||||
var view = this.getComponent('user_transactions').getView();
|
var view = this.getComponent('user_transactions').getView();
|
||||||
|
|
||||||
|
if( this.queryById('transaction_logs')){
|
||||||
|
this.queryById('transaction_logs').disable();
|
||||||
|
}
|
||||||
view.on('itemclick', function(view, record){
|
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!
|
// 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.selectTransaction({transaction_id: record.get('id')});
|
||||||
this.getComponent('transaction_logs').getStore().load();
|
this.getComponent('transaction_logs').getStore().load();
|
||||||
|
|
||||||
|
if( this.queryById('transaction_logs')){
|
||||||
|
this.queryById('transaction_logs').enable();
|
||||||
|
}
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ class Users < Netzke::Basepack::Grid
|
|||||||
super
|
super
|
||||||
c.header = false
|
c.header = false
|
||||||
c.model = "User"
|
c.model = "User"
|
||||||
|
c.force_fit = true
|
||||||
|
|
||||||
c.columns = [
|
c.columns = [
|
||||||
:username,
|
{ :name => :username, :read_only => true },
|
||||||
:first_name,
|
:first_name,
|
||||||
:last_name,
|
:last_name,
|
||||||
:email,
|
:email,
|
||||||
:bike__shop_id
|
{ :text => "Bike - Shop ID", :id => :bike__shop_id, :name => :bike__shop_id, :default_value => Bike.exists? ? Bike.first.id : nil }
|
||||||
]
|
]
|
||||||
|
|
||||||
c.columns << :reset if can? :manage, User
|
c.columns << :reset if can? :manage, User
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
initComponent: function(){
|
initComponent: function(){
|
||||||
// calling superclass's initComponent
|
// calling superclass's initComponent
|
||||||
this.callParent();
|
this.callParent();
|
||||||
|
|
||||||
|
//due to Netzke bug, :min_chars attribute doesn't work
|
||||||
|
var min_char_columns = ["bike__shop_id"]
|
||||||
|
Ext.each(min_char_columns, function(column, index) {
|
||||||
|
Ext.ComponentManager.get(column).editor.minChars = 1;
|
||||||
|
});
|
||||||
|
|
||||||
this.getView().on('itemclick', function(view, record){
|
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!
|
// 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.selectCustomer({customer_id: record.get('id'), customer_type: 'User'});
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
class UsersAndCustomersAccordian < Netzke::Basepack::Accordion
|
class UsersAndCustomersLowerTabs < Netzke::Basepack::TabPanel
|
||||||
component :customers
|
component :customers
|
||||||
component :users
|
component :users
|
||||||
|
|
||||||
def configure(c)
|
def configure(c)
|
||||||
c.prevent_header = true
|
c.prevent_header = true
|
||||||
c.items = [ :customers, :users ]
|
c.items = [ :users, :customers ]
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2,16 +2,14 @@ class UsersAndProfilesBorder < Netzke::Base
|
|||||||
# Remember regions collapse state and size
|
# Remember regions collapse state and size
|
||||||
include Netzke::Basepack::ItemPersistence
|
include Netzke::Basepack::ItemPersistence
|
||||||
component :users
|
component :users
|
||||||
component :user_profiles
|
component :user_and_profiles_lower_tabs
|
||||||
component :user_logs
|
|
||||||
|
|
||||||
def configure(c)
|
def configure(c)
|
||||||
super
|
super
|
||||||
c.header = false
|
c.header = false
|
||||||
c.items = [
|
c.items = [
|
||||||
{ netzke_component: :users, header: "Users", region: :center, width: 350, split: true },
|
{ netzke_component: :users, header: "Users", region: :center, width: 350, split: true },
|
||||||
{ netzke_component: :user_profiles, region: :south, height: 150, split: true},
|
{ netzke_component: :user_and_profiles_lower_tabs, region: :south, height: 300, split: true}
|
||||||
{ netzke_component: :user_logs, region: :east, split: true}
|
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,48 @@
|
|||||||
initComponent: function(){
|
initComponent: function(){
|
||||||
// calling superclass's initComponent
|
// calling superclass's initComponent
|
||||||
this.callParent();
|
this.callParent();
|
||||||
var stats = this.getComponent('user_stats');
|
var stats = this.queryById('user_stats');
|
||||||
if (stats != undefined){
|
if (stats != undefined){
|
||||||
stats.updateStats();
|
stats.updateStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( this.queryById('user_profiles')){
|
||||||
|
this.queryById('user_profiles').disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this.queryById('user_logs')){
|
||||||
|
this.queryById('user_logs').disable();
|
||||||
|
//update user stats
|
||||||
|
var store = this.queryById('user_logs').getStore()
|
||||||
|
store.on('load', function (store, records, operation, success){
|
||||||
|
if( this.queryById('user_stats') ){
|
||||||
|
this.queryById('user_stats').updateStats();
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
if( this.queryById('user_stats') ){
|
||||||
|
this.queryById('user_stats').disable();
|
||||||
|
}
|
||||||
|
|
||||||
// setting the 'rowclick' event
|
// setting the 'rowclick' event
|
||||||
var view = this.getComponent('users').getView();
|
var view = this.getComponent('users').getView();
|
||||||
view.on('itemclick', function(view, record){
|
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!
|
// The beauty of using Ext.Direct: calling 3 endpoints in a row, which results in a single call to the server!
|
||||||
this.selectUser({user_id: record.get('id')});
|
this.selectUser({user_id: record.get('id')});
|
||||||
this.getComponent('user_profiles').getStore().load();
|
|
||||||
this.getComponent('user_logs').getStore().load();
|
if( this.queryById('user_profiles')){
|
||||||
|
this.queryById('user_profiles').getStore().load();
|
||||||
|
this.queryById('user_profiles').enable();
|
||||||
|
}
|
||||||
|
if( this.queryById('user_logs')){
|
||||||
|
this.queryById('user_logs').getStore().load();
|
||||||
|
this.queryById('user_logs').enable();
|
||||||
|
}
|
||||||
|
if( this.queryById('user_stats') ){
|
||||||
|
this.queryById('user_stats').updateStats();
|
||||||
|
this.queryById('user_stats').enable();
|
||||||
|
}
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-18
@@ -1,43 +1,37 @@
|
|||||||
class Bike < ActiveRecord::Base
|
class Bike < ActiveRecord::Base
|
||||||
acts_as_loggable
|
acts_as_loggable
|
||||||
attr_accessible :shop_id, :serial_number, :bike_brand_id, :bike_model_id, :color, :bike_style_id, :seat_tube_height,
|
attr_accessible :shop_id, :serial_number, :bike_brand_id, :model, :color, :bike_style_id, :seat_tube_height,
|
||||||
:top_tube_length, :wheel_size, :value, :bike_condition_id, :bike_status_id
|
:top_tube_length, :bike_wheel_size_id, :value, :bike_condition_id, :bike_purpose_id
|
||||||
|
|
||||||
has_many :transactions
|
has_many :transactions
|
||||||
|
|
||||||
has_one :owner, :class_name => 'User'
|
has_one :owner, :class_name => 'User'
|
||||||
has_one :task_list, :as => :item, :dependent => :destroy
|
has_one :task_list, :as => :item, :dependent => :destroy
|
||||||
belongs_to :bike_brand
|
belongs_to :bike_brand
|
||||||
belongs_to :bike_model
|
|
||||||
belongs_to :bike_style
|
belongs_to :bike_style
|
||||||
belongs_to :bike_condition
|
belongs_to :bike_condition
|
||||||
belongs_to :bike_status
|
belongs_to :bike_purpose
|
||||||
|
belongs_to :bike_wheel_size
|
||||||
|
|
||||||
validates :shop_id, :presence => true, :uniqueness => true, :length => { :minimum => 3 }
|
validates :shop_id, :presence => true, :uniqueness => true, :numericality => { :only_integer => true }
|
||||||
validates :serial_number, :uniqueness => true, :length => { :minimum => 3 }
|
validates :serial_number, :length => { :minimum => 3 }
|
||||||
|
validates :model, :length => { :maximum => 50 }
|
||||||
validates :bike_brand_id, :presence => true
|
validates :bike_brand_id, :presence => true
|
||||||
validates :bike_model_id, :presence => true
|
|
||||||
validates :color, :presence => true
|
validates :color, :presence => true
|
||||||
validates :bike_style_id, :presence => true
|
validates :bike_style_id, :presence => true
|
||||||
validates :seat_tube_height, :presence => true
|
validates :seat_tube_height, :presence => true
|
||||||
validates :top_tube_length, :presence => true
|
validates :bike_wheel_size_id, :presence => true
|
||||||
validates :wheel_size, :presence => true
|
|
||||||
#validates :value, :presence => true
|
|
||||||
validates :bike_condition_id, :presence => true
|
validates :bike_condition_id, :presence => true
|
||||||
validates :bike_status_id, :presence => true
|
validates :bike_purpose_id, :presence => true
|
||||||
|
|
||||||
self.per_page = 15
|
self.per_page = 15
|
||||||
|
|
||||||
after_save :create_task_list
|
after_create :create_task_list
|
||||||
|
|
||||||
def brand
|
def brand
|
||||||
self.bike_brand
|
self.bike_brand
|
||||||
end
|
end
|
||||||
|
|
||||||
def model
|
|
||||||
self.bike_model
|
|
||||||
end
|
|
||||||
|
|
||||||
def style
|
def style
|
||||||
self.bike_style
|
self.bike_style
|
||||||
end
|
end
|
||||||
@@ -46,8 +40,12 @@ class Bike < ActiveRecord::Base
|
|||||||
self.bike_condition
|
self.bike_condition
|
||||||
end
|
end
|
||||||
|
|
||||||
def status
|
def purpose
|
||||||
self.bike_status
|
self.bike_purpose
|
||||||
|
end
|
||||||
|
|
||||||
|
def wheel_size
|
||||||
|
self.bike_wheel_size
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
class BikeModel < ActiveRecord::Base
|
class BikeModel < ActiveRecord::Base
|
||||||
attr_accessible :model, :bike_brand_id
|
attr_accessible :model, :bike_brand_id
|
||||||
|
|
||||||
has_many :bikes
|
|
||||||
belongs_to :bike_brand
|
belongs_to :bike_brand
|
||||||
|
|
||||||
default_scope order('model ASC')
|
default_scope order('model ASC')
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class BikePurpose < ActiveRecord::Base
|
||||||
|
attr_accessible :purpose
|
||||||
|
|
||||||
|
belongs_to :bike
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
self.purpose
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
class BikeStatus < ActiveRecord::Base
|
|
||||||
attr_accessible :status
|
|
||||||
|
|
||||||
belongs_to :bike
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
self.status
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
class BikeWheelSize < ActiveRecord::Base
|
||||||
|
belongs_to :bike
|
||||||
|
|
||||||
|
def display_string
|
||||||
|
result = []
|
||||||
|
result << "#{twmm}-#{rdmm}" unless twmm.blank? and rdmm.blank?
|
||||||
|
result << "#{rdin}x#{twin}" unless rdin.blank? and twin.blank?
|
||||||
|
result << "#{rdfr}x#{twfr}" unless rdfr.blank? and twfr.blank?
|
||||||
|
result << description unless description.blank?
|
||||||
|
result.join(" | ")
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{twmm}-#{rdmm} #{rdin}x#{twin} #{rdfr}x#{twfr} '#{description}' #{tire_common_score}"
|
||||||
|
end
|
||||||
|
end
|
||||||
+5
-2
@@ -20,6 +20,8 @@ class User < ActiveRecord::Base
|
|||||||
|
|
||||||
belongs_to :bike
|
belongs_to :bike
|
||||||
|
|
||||||
|
default_scope order('username ASC')
|
||||||
|
|
||||||
validates :first_name, :presence => true
|
validates :first_name, :presence => true
|
||||||
validates :last_name, :presence => true
|
validates :last_name, :presence => true
|
||||||
|
|
||||||
@@ -45,7 +47,8 @@ class User < ActiveRecord::Base
|
|||||||
### TODO methods below probably belong somewhere else
|
### TODO methods below probably belong somewhere else
|
||||||
|
|
||||||
def completed_build_bikes
|
def completed_build_bikes
|
||||||
status_id = BikeStatus.find_by_status("BUILDBIKE").id
|
#default BUILDBIKE/CLASS ID is 5
|
||||||
|
purpose_id = 5
|
||||||
Bike.find_by_sql("
|
Bike.find_by_sql("
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM bikes
|
FROM bikes
|
||||||
@@ -54,7 +57,7 @@ class User < ActiveRecord::Base
|
|||||||
FROM transactions
|
FROM transactions
|
||||||
WHERE customer_id = #{self.id}
|
WHERE customer_id = #{self.id}
|
||||||
) AS transactions ON bikes.id = transactions.bike_id
|
) AS transactions ON bikes.id = transactions.bike_id
|
||||||
WHERE bike_status_id = #{status_id}")
|
WHERE bike_purpose_id = #{purpose_id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_credits
|
def total_credits
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
%fieldset
|
%fieldset
|
||||||
= f.label :addrStreet1
|
.control-group
|
||||||
%br/
|
= f.label :addrStreet1, :class => "control-label"
|
||||||
= f.text_field :addrStreet1
|
.controls
|
||||||
%br/
|
= f.text_field :addrStreet1, :class => "control-label"
|
||||||
= f.label :addrStreet2
|
.control-group
|
||||||
%br/
|
= f.label :addrStreet2, :class => "control-label"
|
||||||
= f.text_field :addrStreet2
|
.controls
|
||||||
%br/
|
= f.text_field :addrStreet2, :class => "control-label"
|
||||||
= f.label :addrCity
|
.control-group
|
||||||
%br/
|
= f.label :addrCity, :class => "control-label"
|
||||||
= f.text_field :addrCity
|
.controls
|
||||||
%br/
|
= f.text_field :addrCity, :class => "control-label"
|
||||||
= f.label :addrState
|
.control-group
|
||||||
%br/
|
= f.label :addrState, :class => "control-label"
|
||||||
= f.text_field :addrState
|
.controls
|
||||||
%br/
|
= f.text_field :addrState, :class => "control-label"
|
||||||
= f.label :addrZip
|
.control-group
|
||||||
%br/
|
= f.label :addrZip, :class => "control-label"
|
||||||
= f.text_field :addrZip
|
.controls
|
||||||
%br/
|
= f.text_field :addrZip, :class => "control-label"
|
||||||
= f.label :phone
|
.control-group
|
||||||
%br/
|
= f.label :phone, :class => "control-label"
|
||||||
= f.text_field :phone
|
.controls
|
||||||
|
= f.text_field :phone, :class => "control-label"
|
||||||
|
|||||||
@@ -1,34 +1,36 @@
|
|||||||
= stylesheet_link_tag "bootstrap_and_overrides", :media => "all"
|
= stylesheet_link_tag "bootstrap_and_overrides", :media => "all"
|
||||||
%h2 Sign up
|
= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :class => "form-horizontal"}) do |f|
|
||||||
= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
|
|
||||||
= devise_error_messages!
|
= devise_error_messages!
|
||||||
%div
|
.controls
|
||||||
= f.label :username
|
%h2 Sign up
|
||||||
%br/
|
.control-group
|
||||||
= f.text_field :username
|
= f.label :username, :class => "control-label"
|
||||||
%div
|
.controls
|
||||||
= f.label :first_name
|
= f.text_field :username
|
||||||
%br/
|
.control-group
|
||||||
= f.text_field :first_name
|
= f.label :first_name, :class => "control-label"
|
||||||
%div
|
.controls
|
||||||
= f.label :last_name
|
= f.text_field :first_name
|
||||||
%br/
|
.control-group
|
||||||
= f.text_field :last_name
|
= f.label :last_name, :class => "control-label"
|
||||||
%div
|
.controls
|
||||||
= f.label :email
|
= f.text_field :last_name
|
||||||
%br/
|
.control-group
|
||||||
= f.email_field :email
|
= f.label :email, :class => "control-label"
|
||||||
%div
|
.controls
|
||||||
- profile_builder = resource.user_profiles.empty? ? resource.user_profiles.build : resource.user_profiles
|
= f.email_field :email
|
||||||
= f.fields_for :user_profiles, profile_builder do |builder|
|
- profile_builder = resource.user_profiles.empty? ? resource.user_profiles.build : resource.user_profiles
|
||||||
= render 'user_profile_fields', f: builder
|
= f.fields_for :user_profiles, profile_builder do |builder|
|
||||||
%div
|
= render 'user_profile_fields', f: builder
|
||||||
= f.label :password
|
.control-group
|
||||||
%br/
|
= f.label :password, :class => "control-label"
|
||||||
= f.password_field :password
|
.controls
|
||||||
%div
|
= f.password_field :password
|
||||||
= f.label :password_confirmation
|
.control-group
|
||||||
%br/
|
= f.label :password_confirmation, :class => "control-label"
|
||||||
= f.password_field :password_confirmation
|
.controls
|
||||||
%div= f.submit "Sign up"
|
= f.password_field :password_confirmation
|
||||||
|
.control-group
|
||||||
|
.controls
|
||||||
|
= f.submit "Sign up"
|
||||||
= render "links"
|
= render "links"
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
body {
|
body {
|
||||||
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
|
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
|
||||||
}
|
}
|
||||||
|
.x-boundlist-item {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
%body
|
%body
|
||||||
.container
|
.container
|
||||||
|
|||||||
@@ -223,7 +223,10 @@ Devise.setup do |config|
|
|||||||
end
|
end
|
||||||
|
|
||||||
#Check in the user if they sign in. (Devise uses Warden)
|
#Check in the user if they sign in. (Devise uses Warden)
|
||||||
Warden::Manager.after_authentication do |user,auth,opts|
|
Warden::Manager.after_set_user do |user,auth,opts|
|
||||||
|
# this essentially gets called after every netzke request, but alas,
|
||||||
|
# only using the after_authenticaion callback doesn't get fired after
|
||||||
|
# user creation.
|
||||||
user.checkin unless user.checked_in?
|
user.checkin unless user.checked_in?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class BikeConditionIdToInt < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
#for Postgres
|
||||||
|
connection.execute(%q{
|
||||||
|
alter table bikes
|
||||||
|
alter column bike_condition_id
|
||||||
|
type integer using cast(bike_condition_id as integer)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
#you really don't want to go back
|
||||||
|
change_column :bikes, :bike_condition_id, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class BikeStatusToPurpose < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
rename_column :bikes, :bike_status_id, :bike_purpose_id
|
||||||
|
rename_column :bike_statuses, :status, :purpose
|
||||||
|
rename_table :bike_statuses, :bike_purposes
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class AddModelToBike < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :bikes, :model, :string
|
||||||
|
change_column :bikes, :bike_model_id, :integer, :null => true
|
||||||
|
Bike.all.each do |bike|
|
||||||
|
bike.update_attribute(:model, BikeModel.find_by_id(bike['bike_model_id']).model )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
class ChangeBikeShopId < ActiveRecord::Migration
|
||||||
|
# We don't use change_column because we have arbitrary strings we
|
||||||
|
# need to strip the characters from to make the integer values
|
||||||
|
def up
|
||||||
|
bikes = Bike.all
|
||||||
|
remove_column :bikes, :shop_id
|
||||||
|
add_column :bikes, :shop_id, :integer, :unique => true
|
||||||
|
|
||||||
|
# deconflict shop ids
|
||||||
|
bikes.each do |bike|
|
||||||
|
new_id = bike.shop_id.gsub(/[^\d]/, '').to_i rescue 1
|
||||||
|
while bikes.map(&:shop_id).include? new_id
|
||||||
|
new_id += 1
|
||||||
|
end
|
||||||
|
bike.update_attribute(:shop_id, new_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
change_column :bikes, :shop_id, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
class CreateBikeWheelSizes < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
create_table(:bike_wheel_sizes) do |t|
|
||||||
|
t.integer :twmm
|
||||||
|
t.integer :rdmm
|
||||||
|
t.string :twin
|
||||||
|
t.string :rdin
|
||||||
|
t.string :twfr
|
||||||
|
t.string :rdfr
|
||||||
|
t.string :description
|
||||||
|
t.string :tire_common_score
|
||||||
|
end
|
||||||
|
|
||||||
|
#create the default undetermined wheel size record
|
||||||
|
BikeWheelSize.create( twmm: 0, rdmm: 0, rdin: 0, twin: 0, rdfr: 0, twfr: 0, description: "UNDETERMINED", tire_common_score: 0)
|
||||||
|
ActiveRecord::Base.connection.execute(IO.read(File.join(Rails.root, "db", "seed", "sql", "common_wheel_sizes.sql")))
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
drop_table :bike_wheel_sizes
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
class AlterBikeWheelToId < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :bikes, :bike_wheel_size_id, :integer
|
||||||
|
|
||||||
|
undetermined_id = BikeWheelSize.find_by_rdin("0")
|
||||||
|
Bike.find_each do |bike|
|
||||||
|
wheel_size = BikeWheelSize.find_by_rdin(bike['wheel_size'].to_s)
|
||||||
|
|
||||||
|
if wheel_size.nil?
|
||||||
|
wheel_size_id = undetermined_id
|
||||||
|
else
|
||||||
|
wheel_size_id = wheel_size.id
|
||||||
|
end
|
||||||
|
bike.update_attribute(:bike_wheel_size_id, wheel_size_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :bikes, :wheel_size
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
|
||||||
|
add_column :bikes, :wheel_size, :integer
|
||||||
|
|
||||||
|
Bike.find_each do |bike|
|
||||||
|
wheel_size = BikeWheelSize.find_by_id(bike['bike_wheel_size_id'])
|
||||||
|
bike.update_attribute(:wheel_size, wheel_size["rdin"].to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :bikes, :bike_wheel_size_id
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
+29
-19
@@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20130629152047) do
|
ActiveRecord::Schema.define(:version => 20131019170248) do
|
||||||
|
|
||||||
create_table "bike_actions", :force => true do |t|
|
create_table "bike_actions", :force => true do |t|
|
||||||
t.string "action", :limit => 128, :null => false
|
t.string "action", :limit => 128, :null => false
|
||||||
@@ -34,8 +34,8 @@ ActiveRecord::Schema.define(:version => 20130629152047) do
|
|||||||
t.integer "bike_brand_id", :null => false
|
t.integer "bike_brand_id", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "bike_statuses", :force => true do |t|
|
create_table "bike_purposes", :force => true do |t|
|
||||||
t.string "status", :null => false
|
t.string "purpose", :null => false
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
end
|
end
|
||||||
@@ -46,24 +46,34 @@ ActiveRecord::Schema.define(:version => 20130629152047) do
|
|||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "bikes", :force => true do |t|
|
create_table "bike_wheel_sizes", :force => true do |t|
|
||||||
t.string "serial_number"
|
t.integer "twmm"
|
||||||
t.integer "bike_brand_id", :null => false
|
t.integer "rdmm"
|
||||||
t.integer "bike_model_id", :null => false
|
t.string "twin"
|
||||||
t.string "color"
|
t.string "rdin"
|
||||||
t.integer "bike_style_id", :null => false
|
t.string "twfr"
|
||||||
t.float "seat_tube_height"
|
t.string "rdfr"
|
||||||
t.float "top_tube_length"
|
t.string "description"
|
||||||
t.integer "wheel_size"
|
t.string "tire_common_score"
|
||||||
t.float "value"
|
|
||||||
t.string "bike_condition_id", :null => false
|
|
||||||
t.integer "bike_status_id", :null => false
|
|
||||||
t.datetime "created_at", :null => false
|
|
||||||
t.datetime "updated_at", :null => false
|
|
||||||
t.string "shop_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "bikes", ["shop_id"], :name => "index_bikes_on_shop_id", :unique => true
|
create_table "bikes", :force => true do |t|
|
||||||
|
t.string "serial_number"
|
||||||
|
t.integer "bike_brand_id", :null => false
|
||||||
|
t.integer "bike_model_id"
|
||||||
|
t.string "color"
|
||||||
|
t.integer "bike_style_id", :null => false
|
||||||
|
t.float "seat_tube_height"
|
||||||
|
t.float "top_tube_length"
|
||||||
|
t.float "value"
|
||||||
|
t.integer "bike_condition_id", :null => false
|
||||||
|
t.integer "bike_purpose_id", :null => false
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
t.string "model"
|
||||||
|
t.integer "shop_id"
|
||||||
|
t.integer "bike_wheel_size_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "credit_conversions", :force => true do |t|
|
create_table "credit_conversions", :force => true do |t|
|
||||||
t.integer "conversion", :default => 1
|
t.integer "conversion", :default => 1
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
undetermined:
|
||||||
|
id: 1
|
||||||
|
purpose: UNDETERMINED
|
||||||
|
scrap:
|
||||||
|
id: 2
|
||||||
|
purpose: SCRAP
|
||||||
|
parts:
|
||||||
|
id: 3
|
||||||
|
purpose: PARTS
|
||||||
|
storage:
|
||||||
|
id: 4
|
||||||
|
purpose: STORAGE
|
||||||
|
buildbike:
|
||||||
|
id: 5
|
||||||
|
purpose: BUILDBIKE
|
||||||
|
sale:
|
||||||
|
id: 6
|
||||||
|
purpose: SALE
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
undetermined:
|
|
||||||
id: 1
|
|
||||||
status: UNDETERMINED
|
|
||||||
scrap:
|
|
||||||
id: 2
|
|
||||||
status: SCRAP
|
|
||||||
parts:
|
|
||||||
id: 3
|
|
||||||
status: PARTS
|
|
||||||
storage:
|
|
||||||
id: 4
|
|
||||||
status: STORAGE
|
|
||||||
buildbike:
|
|
||||||
id: 5
|
|
||||||
status: BUILDBIKE
|
|
||||||
sale:
|
|
||||||
id: 6
|
|
||||||
status: SALE
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (54,110,'8 1/2','2','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (62,203,'12','1/2 x 2 1/4','320 ','57','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,305,'16','1,75 [x 2]','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,369,'16','1 1/4','','','Moulton',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,355,'18','1,75 [ x 2]','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,406,'20','1 1/8','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,406,'20','1 3/8','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,406,'20','1,75 [ x 2]','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,507,'24','1,75 [ x 2]','600 ','50C','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,540,'24','1 3/8 A','600 ','35A','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (25,559,'26','1','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,559,'26','1,3','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,559,'26','1,5','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (40,559,'26','1,6','','','MTB',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (44,559,'26','1,6','','','City/trekking',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,559,'26','1,75 [ x 2]','650 ','50','City/Trekking',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (NULL,NULL,'26','1,9','','','MTB',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (50,'559','26','1,9','','','City/Trekking',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (NULL,NULL,'26','2','','','MTB',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (54,559,'26','2,1','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (57,559,'26','2,3 [2,125]','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (20,571,'','','650 ','20C','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (23,571,'','','650 ','23C','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,584,'26','1 1/8 x 1 1/2 B','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,584,'26','1 3/8 x 1 1/2 B','650 ','38A','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,590,'26','1 3/8','650 [','35] A','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (20,622,'','','700 ','20C','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (23,622,'','','700 ','23C','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (25,622,'','','700 ','25C','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,622,'28','1 5/8 x 1 3/8','700 ','28C [700C]','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,622,'28','1 1/4 x 1 3/4','700 ','32C [700C Course]','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (37,622,'28','1 3/8 x 1 5/8','700 ','37C [35C]','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (42,622,'28','1,6','700 ','42C [40C]','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (47,622,'28','1,75','700 ','47C [45C]','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (28,630,'27','1 1/8 [1 1/4 fifty]','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (32,630,'27','1 1/4','','','',1);
|
||||||
|
INSERT INTO bike_wheel_sizes (TWMM, RDMM,RDIN,TWIN,RDFR,TWFR,DESCRIPTION,tire_common_score) values (40,635,'28','1 1/2 [1 3/8]','700 ','38B [35B]','',1);
|
||||||
+17
-10
@@ -14,21 +14,28 @@ end
|
|||||||
|
|
||||||
#Load bike brands and models from sql
|
#Load bike brands and models from sql
|
||||||
if BikeBrand.all.empty? and BikeModel.all.empty?
|
if BikeBrand.all.empty? and BikeModel.all.empty?
|
||||||
sql_path = File.join(Rails.root, 'db', 'seed', 'sql', 'bike_brands_and_models.sql')
|
# Need to use DEFAULT instead of explicit IDs that are used in the sql file,
|
||||||
db_config = Rails.application.config.database_configuration[Rails.env]
|
# so that the PG table ID sequence is incremented
|
||||||
cmd = "psql #{db_config["database"]} < #{sql_path}"
|
#
|
||||||
system cmd
|
# Note the drop(1) which assumes we have a junk PRAGMA line at the top
|
||||||
|
load_statements = File.readlines(File.join(Rails.root, 'db', 'seed', 'sql', 'bike_brands_and_models.sql')).drop(1).map do |statement|
|
||||||
|
statement.sub(/VALUES\(\d+,/, 'VALUES(DEFAULT,')
|
||||||
|
end
|
||||||
|
ActiveRecord::Base.connection.execute(load_statements.join)
|
||||||
end
|
end
|
||||||
|
|
||||||
if Rails.env.development?
|
if Rails.env.development?
|
||||||
|
|
||||||
#create default admin user
|
#create default users
|
||||||
if User.all.empty?
|
if User.all.empty?
|
||||||
FactoryGirl.create(:user)
|
u = FactoryGirl.create(:user)
|
||||||
FactoryGirl.create(:staff)
|
FactoryGirl.create(:user_profile, user_id: u.id)
|
||||||
FactoryGirl.create(:bike_admin)
|
u = FactoryGirl.create(:staff)
|
||||||
FactoryGirl.create(:admin)
|
FactoryGirl.create(:user_profile, user_id: u.id)
|
||||||
FactoryGirl.create(:user_profile)
|
u = FactoryGirl.create(:bike_admin)
|
||||||
|
FactoryGirl.create(:user_profile, user_id: u.id)
|
||||||
|
u = FactoryGirl.create(:admin)
|
||||||
|
FactoryGirl.create(:user_profile, user_id: u.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
#create fake bikes
|
#create fake bikes
|
||||||
|
|||||||
+12
-14
@@ -2,21 +2,19 @@
|
|||||||
|
|
||||||
FactoryGirl.define do
|
FactoryGirl.define do
|
||||||
factory :bike do
|
factory :bike do
|
||||||
sequence :shop_id do |n|
|
sequence(:shop_id) {|n| n}
|
||||||
"Shop ID #{n}"
|
|
||||||
end
|
|
||||||
sequence :serial_number do |n|
|
sequence :serial_number do |n|
|
||||||
"S/N# #{n}"
|
"#{Faker::Code.isbn}-#{n}"
|
||||||
end
|
end
|
||||||
bike_brand_id 1
|
bike_brand_id { BikeBrand.all.sample.id }
|
||||||
bike_model_id 1
|
model { Faker::Commerce.product_name }
|
||||||
color "FFFFFF"
|
color { sprintf("%06X", Random.rand(16777215) ) }
|
||||||
bike_style_id 1
|
bike_style_id { BikeStyle.all.sample.id }
|
||||||
seat_tube_height 5
|
seat_tube_height { Random.rand(25) }
|
||||||
top_tube_length 6
|
top_tube_length { Random.rand(25) }
|
||||||
wheel_size 27
|
bike_wheel_size_id { BikeWheelSize.all.sample.id }
|
||||||
value 100
|
value { Random.rand(200) }
|
||||||
bike_condition_id 1
|
bike_condition_id { BikeCondition.all.sample.id }
|
||||||
bike_status_id 1
|
bike_purpose_id { BikePurpose.all.sample.id }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
FactoryGirl.define do
|
FactoryGirl.define do
|
||||||
factory :user_profile do
|
factory :user_profile do
|
||||||
user_id 1
|
user_id 1
|
||||||
addrStreet1 "Charles Street"
|
addrStreet1 { Faker::Address.street_address }
|
||||||
addrStreet2 "Apt #42"
|
addrStreet2 { Faker::Address.secondary_address }
|
||||||
addrCity "Baltimore"
|
addrCity { Faker::Address.city }
|
||||||
addrState "MD"
|
addrState { Faker::Address.state_abbr }
|
||||||
addrZip "21231"
|
addrZip { Faker::Address.zip_code }
|
||||||
phone "(410)8675309"
|
phone { Faker::PhoneNumber.cell_phone }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FactoryGirl.define do
|
FactoryGirl.define do
|
||||||
factory :user do
|
factory :user do
|
||||||
|
|
||||||
sequence(:username) { |n| "user_#{n}" }
|
sequence(:username) { |n| "user_#{n}" }
|
||||||
sequence(:email) { |n| "user_#{n}@example.com" }
|
sequence(:email) { |n| "user_#{n}@example.com" }
|
||||||
password 'password'
|
password 'password'
|
||||||
|
|||||||
Reference in New Issue
Block a user