From edfed2f82102783ac3749cfe3ab2d56acb126201 Mon Sep 17 00:00:00 2001 From: chandra Date: Thu, 12 Apr 2012 19:40:03 +0530 Subject: [PATCH] Before creating active admin models --- Gemfile | 1 + Gemfile.lock | 43 +++ app/admin/dashboards.rb | 44 +++ app/assets/javascripts/.bills.js.swp | Bin 0 -> 16384 bytes app/assets/javascripts/.products.js.swp | Bin 0 -> 12288 bytes app/assets/javascripts/active_admin.js | 1 + app/assets/javascripts/application.js | 2 + app/assets/javascripts/bills.js | 169 +++++++++++ app/assets/javascripts/bootstrap-modal.js | 210 ++++++++++++++ app/assets/javascripts/bootstrap-typeahead.js | 271 ++++++++++++++++++ app/assets/javascripts/products.js | 122 ++++++++ app/assets/stylesheets/active_admin.css.scss | 6 + app/assets/stylesheets/bills.css.scss | 3 + app/assets/stylesheets/products.css.scss | 8 + app/controllers/bills_controller.rb | 20 ++ app/controllers/products_controller.rb | 49 ++++ app/helpers/bills_helper.rb | 2 + app/helpers/products_helper.rb | 2 + app/models/admin_user.rb | 9 + app/models/bill.rb | 5 + app/models/billitem.rb | 2 + app/models/product.rb | 6 + app/views/bills/.new.html.erb.swp | Bin 0 -> 12288 bytes app/views/bills/new.html.erb | 40 +++ app/views/layouts/application.html.erb | 4 +- app/views/products/._product.html.erb.swp | Bin 0 -> 12288 bytes app/views/products/_product.html.erb | 8 + app/views/products/index.html.erb | 43 +++ app/views/products/products_list.html.erb | 21 ++ config/environments/.production.rb.swp | Bin 0 -> 12288 bytes config/initializers/active_admin.rb | 129 +++++++++ config/initializers/devise.rb | 223 ++++++++++++++ config/locales/devise.en.yml | 57 ++++ config/routes.rb | 68 +---- ...1606_rename_product_to_name_in_products.rb | 9 + ...0120412135404_devise_create_admin_users.rb | 52 ++++ .../20120412192412_create_admin_notes.rb | 16 ++ ...0412192413_move_admin_notes_to_comments.rb | 25 ++ db/schema.rb | 39 +++ public/index.html | 241 ---------------- test/fixtures/admin_users.yml | 11 + test/functional/bills_controller_test.rb | 7 + test/functional/products_controller_test.rb | 7 + test/unit/admin_user_test.rb | 7 + test/unit/helpers/bills_helper_test.rb | 4 + test/unit/helpers/products_helper_test.rb | 4 + 46 files changed, 1690 insertions(+), 300 deletions(-) create mode 100644 app/admin/dashboards.rb create mode 100644 app/assets/javascripts/.bills.js.swp create mode 100644 app/assets/javascripts/.products.js.swp create mode 100644 app/assets/javascripts/active_admin.js create mode 100644 app/assets/javascripts/bills.js create mode 100644 app/assets/javascripts/bootstrap-modal.js create mode 100644 app/assets/javascripts/bootstrap-typeahead.js create mode 100644 app/assets/javascripts/products.js create mode 100644 app/assets/stylesheets/active_admin.css.scss create mode 100644 app/assets/stylesheets/bills.css.scss create mode 100644 app/assets/stylesheets/products.css.scss create mode 100644 app/controllers/bills_controller.rb create mode 100644 app/controllers/products_controller.rb create mode 100644 app/helpers/bills_helper.rb create mode 100644 app/helpers/products_helper.rb create mode 100644 app/models/admin_user.rb create mode 100644 app/views/bills/.new.html.erb.swp create mode 100644 app/views/bills/new.html.erb create mode 100644 app/views/products/._product.html.erb.swp create mode 100644 app/views/products/_product.html.erb create mode 100644 app/views/products/index.html.erb create mode 100644 app/views/products/products_list.html.erb create mode 100644 config/environments/.production.rb.swp create mode 100644 config/initializers/active_admin.rb create mode 100644 config/initializers/devise.rb create mode 100644 config/locales/devise.en.yml create mode 100644 db/migrate/20120409041606_rename_product_to_name_in_products.rb create mode 100644 db/migrate/20120412135404_devise_create_admin_users.rb create mode 100644 db/migrate/20120412192412_create_admin_notes.rb create mode 100644 db/migrate/20120412192413_move_admin_notes_to_comments.rb create mode 100644 db/schema.rb delete mode 100644 public/index.html create mode 100644 test/fixtures/admin_users.yml create mode 100644 test/functional/bills_controller_test.rb create mode 100644 test/functional/products_controller_test.rb create mode 100644 test/unit/admin_user_test.rb create mode 100644 test/unit/helpers/bills_helper_test.rb create mode 100644 test/unit/helpers/products_helper_test.rb diff --git a/Gemfile b/Gemfile index f4bec0e..381c485 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,7 @@ group :assets do end gem 'jquery-rails' +gem 'activeadmin' # To use ActiveModel has_secure_password # gem 'bcrypt-ruby', '~> 3.0.0' diff --git a/Gemfile.lock b/Gemfile.lock index 932c5fe..068108f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,6 +14,17 @@ GEM rack-cache (~> 1.1) rack-test (~> 0.6.1) sprockets (~> 2.1.2) + activeadmin (0.4.0) + bourbon (>= 1.0.0) + devise (>= 1.1.2) + fastercsv + formtastic (>= 2.0.0) + inherited_resources (< 1.3.0) + jquery-rails (>= 1.0.0) + kaminari (>= 0.13.0) + meta_search (>= 0.9.2) + rails (>= 3.0.0) + sass (>= 3.1.0) activemodel (3.2.1) activesupport (= 3.2.1) builder (~> 3.0.0) @@ -29,6 +40,9 @@ GEM i18n (~> 0.6) multi_json (~> 1.0) arel (3.0.2) + bcrypt-ruby (3.0.1) + bourbon (1.3.6) + sass (>= 3.1) builder (3.0.0) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -37,22 +51,47 @@ GEM coffee-script-source execjs coffee-script-source (1.2.0) + devise (2.0.0) + bcrypt-ruby (~> 3.0) + orm_adapter (~> 0.0.3) + railties (~> 3.1) + warden (~> 1.1) erubis (2.7.0) execjs (1.3.0) multi_json (~> 1.0) + fastercsv (1.5.4) + formtastic (2.0.2) + rails (~> 3.0) + has_scope (0.5.1) hike (1.2.1) i18n (0.6.0) + inherited_resources (1.2.2) + has_scope (~> 0.5.0) + responders (~> 0.6.0) journey (1.0.3) jquery-rails (2.0.1) railties (>= 3.2.0, < 5.0) thor (~> 0.14) json (1.6.5) + kaminari (0.13.0) + actionpack (>= 3.0.0) + activesupport (>= 3.0.0) + railties (>= 3.0.0) mail (2.4.3) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) + meta_search (1.1.2) + actionpack (~> 3.1) + activerecord (~> 3.1) + activesupport (~> 3.1) + meta_search + polyamorous (~> 0.5.0) mime-types (1.17.2) multi_json (1.1.0) + orm_adapter (0.0.6) + polyamorous (0.5.0) + activerecord (~> 3.0) polyglot (0.3.3) rack (1.4.1) rack-cache (1.2) @@ -79,6 +118,7 @@ GEM rake (0.9.2.2) rdoc (3.12) json (~> 1.4) + responders (0.6.5) sass (3.1.15) sass-rails (3.2.4) railties (~> 3.2.0) @@ -98,11 +138,14 @@ GEM uglifier (1.2.3) execjs (>= 0.3.0) multi_json (>= 1.0.2) + warden (1.1.0) + rack (>= 1.0) PLATFORMS ruby DEPENDENCIES + activeadmin coffee-rails (~> 3.2.1) jquery-rails rails (= 3.2.1) diff --git a/app/admin/dashboards.rb b/app/admin/dashboards.rb new file mode 100644 index 0000000..5c8a3fc --- /dev/null +++ b/app/admin/dashboards.rb @@ -0,0 +1,44 @@ +ActiveAdmin::Dashboards.build do + + # Define your dashboard sections here. Each block will be + # rendered on the dashboard in the context of the view. So just + # return the content which you would like to display. + + # == Simple Dashboard Section + # Here is an example of a simple dashboard section + # + # section "Recent Posts" do + # ul do + # Post.recent(5).collect do |post| + # li link_to(post.title, admin_post_path(post)) + # end + # end + # end + + # == Render Partial Section + # The block is rendered within the context of the view, so you can + # easily render a partial rather than build content in ruby. + # + # section "Recent Posts" do + # div do + # render 'recent_posts' # => this will render /app/views/admin/dashboard/_recent_posts.html.erb + # end + # end + + # == Section Ordering + # The dashboard sections are ordered by a given priority from top left to + # bottom right. The default priority is 10. By giving a section numerically lower + # priority it will be sorted higher. For example: + # + # section "Recent Posts", :priority => 10 + # section "Recent User", :priority => 1 + # + # Will render the "Recent Users" then the "Recent Posts" sections on the dashboard. + + # == Conditionally Display + # Provide a method name or Proc object to conditionally render a section at run time. + # + # section "Membership Summary", :if => :memberships_enabled? + # section "Membership Summary", :if => Proc.new { current_admin_user.account.memberships.any? } + +end diff --git a/app/assets/javascripts/.bills.js.swp b/app/assets/javascripts/.bills.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..5e0bc1cfc6948da1957c849433c73ee30911fb94 GIT binary patch literal 16384 zcmeI3TWlOx8OIOdQkFC%y#T$4>ab2cv+;V@7urTkY$#MHL2hEzPAH1f)$GjK-7&K> z+qt+lu4z>QYASJgM{3mvTEyiEkdVR?Jb?O!pj8E^0wEr#P!&pvXraLW`{v?VCw6#2 zs+2R*&$~0{GT-@s=lf>n%(^pm`uKhF?#8UZc0h=w?>>I=(VJ()n>Pw!_buNEEh^b{ zv)64e7)HC+p~5d_9X1!kU`5$+)cmCDd9L3pKCR)fX+@Dj(TcTdMRw>8@x6m;QDf!m zXSk{fx`I~V+EgHkyOT%uiP@RyDH33;`Vo24ji;_nE%d0h0$KsBfL1^&pcT*xXa%$a z*Qf&VaF2KtW8agF|4jDzj%}as%=V9DpQpE#XS@1CE1(t73TOqi0$KsBfL1^&pcT*x zXa%$aT7kEr0+u6$`)(or`W_gE_y76x{~z`X@iO=Y_&N9yI0rn?1E)b9To3;Iej$De zE`V=>FM|l20OR1_`-J!{_#yZnI1hZ#1#R#-unbOu1#leP3EtQ%#6Q5x-~xCGtbqma zX>c#N6MPu#1()6@#P7h*z<0pcK?rD>cmmj97VHJDVL|9m-~xCWoChwj!Gqudumnzm1wh+oO;ipyMP;-0F;U6> zRyOe!J3L$J&yMfPj z(y}Dr7Oej*8+iSZ}+r8sH}*fnTljxeqq16>H6;E=vZ;IeE~eeYU`L zw)PuCD^z}L8gXdU8de;Krr|mU)jMb!4M%w@R&Dxa3ZDvfV3}ciuKjtVE(=@9&Sq2I z%hjbNsevThWH$^3GVUurB)C`CA13h`-x{d7svQglZd^UPbH{ezM}emrUeGg*<TublRK)D^hAXmBPtTd$T=m4lsl@bFbqOT!nI^|Lay~gI4K$igGeo_ zwV1|Fo@{hn-!To+w8c%zgI0BFSC>(2#Yt3`Tp{%snSd=+aT5BnYk8641L-s&X~$U8 z*y?zSgdYwSPQ=I3Ig`47ml-o^TsD`snMc!X%RU&())i-GN3^>^I51%EL36u1?IV%3GRy7}KbtnFDsZ;-se~`{IC2qzi0rGPP~bT-|a} z$~L$ZS{P<28FMf3VCWSQ!;xIb$br=uCQ*N@0!cxxd?>N}*p1g)WD@V7Zw_n}a-eg` zNXU~{=)%Y)^d)aX1$N-11@xs{;5uBNjirlsdKPNJ0o=OJiu(-;NVA566n*&skP|jU z9yoGDN)DoX94F880wDqyQ=rg*sE79Mg4K{OGXLl2OEXc)=ag>*XWG#!4Nv*KxR1iZ zI^3r?DrArHG)nu*qCG9-aisyzo)Mxv*fu$mvmoZi(8F{$t4E`u=lv&a!Ix>?(C= z<>M&wqwG_fHO6p$H!pONcP7&t(#go}`6z3;z$(n|gw1(MwN1X|q*;ahlL{s{&@lz* zGtZi7?#xnXeh{VG=lyirh*P5ElrRz%xXe_moYzpJ=#6_R$4KIG=4kM-%X%!=tc~_a z=9EGz?}x@mhl{SLUMa%L_2}?Oz0r^>sycZk5^D(=ba z66FXE5`$tH+y6L(9Y#>Hz8ly{)Y`g#-+saVEPL11E5(l_rAJRhs zUtcPff$J}DsJ5orNHRFTu9vHu=>x^(-K6(%Y*6{`l}3)M_&udFN<2Q~AzIwhoH^j(ik)#WOV+w{V~STp3u zWr$ZRW;i~zHv7ob+7W7<^=hnT+a!HXew6;K(;wQ+Hv>=dSf;a;**vqhezw^wtsB}k bEL;}rnmB8|Oqi_)V!d32zUA@KoDly7pz3?x literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/.products.js.swp b/app/assets/javascripts/.products.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..a89ac01131ac0f10ef87f15bcca55d3cd7747b58 GIT binary patch literal 12288 zcmeI2zmL-}6vqt%Qur-kVGHG|q|!Cz?u0<4EfQh?Bse5~OrXdlZgEMIkhp~k6$Zo~ zz{rLW3kwqyto#8CFu{bx&dP%L+DXcB0*)2kv-Gtc`@NUv&r65X`Nol}XV2TmycLGF zm$4_G95O-Nv@`px6J*vj(K5q>Y5!k#0RJw&d!11@12hJ&0dl-8QJ%ci+2W^Mm@5UVg=p?iZHKA?L zhh2=lfnGolq3h65Xa}?n`nHp?FVI`)74#UIK{uc?&_U=Ua(D;5hF(E0p%>6|Nayzm zqDBOW01+SpM1Tko0U|&I{&xbiS>pt=Oox8fV}}-r|wSlpAuzy-_~U zwt7!QxwuytEV$0$>iVo7$y_-NFU>?M;?OPEeKks>B1XB=C<9sAI}^B%>&N1bU+yA; z%H&`mGS>+r8QgMUZkJ8=i%9u62t=MYOd91wyFZQtC6m~g6k9s=%hOb}onfBDjyYVA z#7e}fSjLrLyn}1E)=v{WDEP zRc3nn2df|nD=R(yjg>XwnO&B^?%Ma54lX82mvaJKr$wKSBjxJa>EwAB`YNf4mZNF_ zUlwd}UI_$1A#B?OH-|)Q?Y^eqW?2{6GM#00T6xOjo_$S!V;yb>5iV_aYkG0X)*qQK zl^FRVl&WUm%tXIitJyN_);jerM!Vjt^*XY0lc;yo*!DUt3Gphj4p>?J4Bo72gdp{9 z^-zbS$*M@|53Z(A#?Q>=PUTV7d##w$G`9~ia8V?!%YTsF# wR`mtwwWZ~nK~=7qA2Q14d!V02TnX2?#unT#3C1IQAq_7RJe<1o;-m6E04P46(f|Me literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/active_admin.js b/app/assets/javascripts/active_admin.js new file mode 100644 index 0000000..d2b66c5 --- /dev/null +++ b/app/assets/javascripts/active_admin.js @@ -0,0 +1 @@ +//= require active_admin/base diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 9097d83..58ae75a 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,4 +12,6 @@ // //= require jquery //= require jquery_ujs +//= require jquery-ui +//= require underscore-min //= require_tree . diff --git a/app/assets/javascripts/bills.js b/app/assets/javascripts/bills.js new file mode 100644 index 0000000..c07a122 --- /dev/null +++ b/app/assets/javascripts/bills.js @@ -0,0 +1,169 @@ +$(document).ready( function(){ + + billitems_list = []; + + // Autocomplete + $('.code_autocomplete').on('focus', function(){ + $(this).autocomplete( + { + minLength:1, + source:'/products/code_autocomplete', + focus: function(event, ui){ + $('#code').val(ui.item.code); + $('#name').val(ui.item.name); + }, + change:function(event, ui){ + console.log(ui); + if(ui.item){ + $('#item_id').val(ui.item.id); + $('#code').val(ui.item.code); + $('#name').val(ui.item.name); + if ($('#price').val()== ""){ + $('#price').val(ui.item.price); + } + if ($('#quant').val()== ""){ + $('#quant').val(1); + } + } + } + } + ); + } +); +//billitem template +var billitem_tmpl = _.template("><%= code %><%= name %><%= price %><%= quantity %>Remove
"); + +// render bill items_list +function render_bill_items_list(){ + if (billitems_list.length){ + _.each(billitems_list, function(bi){ + $('#bill_area').append(billitem_tmpl(bi)); + });} +} +// Add to bill +function add_to_bill(){ + var billitem = { + _guid:Math.guid(), + id:$('#item_id').val(), + code:$('#code').val(), + name:$('#name').val(), + price:$('#price').val(), + quantity:$('#quant').val() + }; + $('#reset_billitem').trigger('click'); + billitems_list.push(billitem); + $('#bill_area').append(billitem_tmpl(billitem)); +} + +function calculate_total(){ + var total = _.reduce(billitems_list, function(tot, bi){ return tot+parseInt(bi.price)*parseInt(bi.quantity); }, 0); + $('#total strong').text(total); +} + +$('#add_item_2_bill').live('click', function(){ + if(parseInt($('#item_id').val())){ + add_to_bill(); + calculate_total(); + }else{ + alert('This product does not exist in the product database, please create it first.') + } +}); + +$('#reset_billitem').live('click', function(){ + _.each($('#bill_item_form .item'), function(it){ + $(it).val(''); + }); +}); + +$('#add_bill').live('click', function(evt){ + evt.preventDefault(); + if(billitems_list.length){ + $.ajax({ + url:"/bills", + data:{billitems:billitems_list}, + dataType:'json', + type:'POST', + success:function(data, textStatus, jqXHR){ + console.log(data); + if(data.success){ + $('#reset_bill').trigger('click'); + $('#reset_billitem').trigger('click'); + } + } + }); + }else{ + alert('No items were found in the bill please add some items.'); + } +}); + +// deleting items from the bill +$('.del_item').live('click',function(evt){ + evt.preventDefault(); + var ref = $($(this)[0]); + ref = ref.parent('.billitem').filter(':first'); + var guid = ref.attr("data-guid"); + ref.remove(); + billitems_list = _.reject(billitems_list, function(bi){return bi._guid == guid;}); + calculate_total(); +}); + +// Reset bill +$('#reset_bill').live('click', function(){ + $('.del_item').trigger('click'); +}); + +// external code +Math.guid = function(){ + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }).toUpperCase(); +}; + + +/* + // Updating subtotal on field change + function show_subtotal(){ + var price = parseInt($('#billitem_price').val()); + var numbers = parseInt($('#billitem_numbers').val()); + if (price && numbers){ + $('#subtotal').text("Subtotal : " + price*numbers) + } + } + + $('#bill_input_form #billitem_price').on('change', show_subtotal); + $('#bill_input_form #billitem_numbers').on('change', show_subtotal); + + // Respond on successful write to billitem & bill + $(function(){ + $('#bill_input_form') + .bind('ajax:success', function(e, data, status, xhr){ + if(data.success){ + $('#bill_table').append(bill_record(data)); + } + return false + }) + .bind('ajax:error', function(e, xhr, status, error){ + console.log("error json: "+ xhr.respomseText); + }) + + }) + + // debug + $('input[name="commit"]').on('click', function(){console.log('Triggered submit');}); + + // Delete a bill item from the bill + $('.delete_bill_item').on('click', function(){ + id = $(this).parent('tr').attr('id'); + this_record = $(this); + $.ajax({ + url:"/bills/"+id+"/destroy_item.json", + succeess:function(data){ + if(data.success){ + this_record.remove(); + } + } + }); + }); + */ +}) diff --git a/app/assets/javascripts/bootstrap-modal.js b/app/assets/javascripts/bootstrap-modal.js new file mode 100644 index 0000000..bceb303 --- /dev/null +++ b/app/assets/javascripts/bootstrap-modal.js @@ -0,0 +1,210 @@ +/* ========================================================= + * bootstrap-modal.js v2.0.1 + * http://twitter.github.com/bootstrap/javascript.html#modals + * ========================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + + +!function( $ ){ + + "use strict" + + /* MODAL CLASS DEFINITION + * ====================== */ + + var Modal = function ( content, options ) { + this.options = options + this.$element = $(content) + .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) + } + + Modal.prototype = { + + constructor: Modal + + , toggle: function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + , show: function () { + var that = this + + if (this.isShown) return + + $('body').addClass('modal-open') + + this.isShown = true + this.$element.trigger('show') + + escape.call(this) + backdrop.call(this, function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position + + that.$element + .show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + transition ? + that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) : + that.$element.trigger('shown') + + }) + } + + , hide: function ( e ) { + e && e.preventDefault() + + if (!this.isShown) return + + var that = this + this.isShown = false + + $('body').removeClass('modal-open') + + escape.call(this) + + this.$element + .trigger('hide') + .removeClass('in') + + $.support.transition && this.$element.hasClass('fade') ? + hideWithTransition.call(this) : + hideModal.call(this) + } + + } + + + /* MODAL PRIVATE METHODS + * ===================== */ + + function hideWithTransition() { + var that = this + , timeout = setTimeout(function () { + that.$element.off($.support.transition.end) + hideModal.call(that) + }, 500) + + this.$element.one($.support.transition.end, function () { + clearTimeout(timeout) + hideModal.call(that) + }) + } + + function hideModal( that ) { + this.$element + .hide() + .trigger('hidden') + + backdrop.call(this) + } + + function backdrop( callback ) { + var that = this + , animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('