From e6134722d4e5b55860e18cfc7793f851bdda74ef Mon Sep 17 00:00:00 2001 From: Captain Future Date: Sun, 17 Apr 2011 16:26:36 +0200 Subject: [PATCH] boom --- .gitignore | 11 + Gemfile | 35 +++ Gemfile.lock | 217 ++++++++++++++++++ LICENSE | 21 ++ README.textile | 114 +++++++++ Rakefile | 75 ++++++ Versionfile | 7 + app/controllers/admin/digitals_controller.rb | 12 + app/controllers/digitals_controller.rb | 16 ++ app/models/digital.rb | 10 + app/models/digital_link.rb | 27 +++ app/models/line_item_decorator.rb | 22 ++ app/models/order_decorator.rb | 20 ++ app/models/variant_decorator.rb | 20 ++ app/views/admin/digitals/_digital.html.erb | 5 + app/views/admin/digitals/_form.html.erb | 35 +++ app/views/admin/digitals/index.html.erb | 20 ++ app/views/checkout/_delivery.html.erb | 5 + app/views/checkout/_delivery_digital.html.erb | 12 + .../checkout/_delivery_original.html.erb | 32 +++ app/views/order_mailer/confirm_email.text.erb | 36 +++ config/locales/en.yml | 12 + config/routes.rb | 11 + db/migrate/20110410134726_create_digitals.rb | 30 +++ doc/tables.png | Bin 0 -> 98091 bytes lib/spree_digital.rb | 17 ++ lib/spree_digital_hooks.rb | 11 + lib/tasks/install.rake | 18 ++ lib/tasks/spree_digital.rake | 1 + spec/factories.rb | 6 + spec/factories/digital_factory.rb | 3 + spec/factories/digital_link_factory.rb | 4 + spec/models/digital_link_spec.rb | 98 ++++++++ spec/models/digital_spec.rb | 25 ++ spec/models/line_item_spec.rb | 33 +++ spec/models/order_spec.rb | 54 +++++ spec/spec_helper.rb | 61 +++++ spree_digital.gemspec | 15 ++ spree_digital.tmproj | 48 ++++ 39 files changed, 1199 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 LICENSE create mode 100644 README.textile create mode 100644 Rakefile create mode 100644 Versionfile create mode 100644 app/controllers/admin/digitals_controller.rb create mode 100644 app/controllers/digitals_controller.rb create mode 100644 app/models/digital.rb create mode 100644 app/models/digital_link.rb create mode 100644 app/models/line_item_decorator.rb create mode 100644 app/models/order_decorator.rb create mode 100644 app/models/variant_decorator.rb create mode 100644 app/views/admin/digitals/_digital.html.erb create mode 100644 app/views/admin/digitals/_form.html.erb create mode 100644 app/views/admin/digitals/index.html.erb create mode 100644 app/views/checkout/_delivery.html.erb create mode 100644 app/views/checkout/_delivery_digital.html.erb create mode 100644 app/views/checkout/_delivery_original.html.erb create mode 100644 app/views/order_mailer/confirm_email.text.erb create mode 100644 config/locales/en.yml create mode 100644 config/routes.rb create mode 100644 db/migrate/20110410134726_create_digitals.rb create mode 100644 doc/tables.png create mode 100644 lib/spree_digital.rb create mode 100644 lib/spree_digital_hooks.rb create mode 100644 lib/tasks/install.rake create mode 100644 lib/tasks/spree_digital.rake create mode 100644 spec/factories.rb create mode 100644 spec/factories/digital_factory.rb create mode 100644 spec/factories/digital_link_factory.rb create mode 100644 spec/models/digital_link_spec.rb create mode 100644 spec/models/digital_spec.rb create mode 100644 spec/models/line_item_spec.rb create mode 100644 spec/models/order_spec.rb create mode 100644 spec/spec_helper.rb create mode 100644 spree_digital.gemspec create mode 100644 spree_digital.tmproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b2f717 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +\#* +*~ +.#* +.DS_Store +.idea +.project +tmp +nbproject +*.swp +spec/test_app +.tmproj \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..fef476b --- /dev/null +++ b/Gemfile @@ -0,0 +1,35 @@ +source 'http://rubygems.org' + +#gem 'spree_core', :path => '../spree/core' +#gem 'spree_digital', :path => 'spree_digital' +#gem "sqlite3-ruby" +# +#group :test do +# gem 'rspec-rails', '= 2.5.0' +# gem 'factory_girl', '= 1.3.3' +# gem 'factory_girl_rails', '= 1.0.1' +# gem 'rcov' +# gem 'shoulda' +# gem 'faker' +# if RUBY_VERSION < "1.9" +# gem "ruby-debug" +# else +# gem "ruby-debug19" +# end +#end +# +#group :cucumber do +# gem 'cucumber-rails' +# gem 'database_cleaner', '= 0.6.7.RC' +# gem 'nokogiri' +# gem 'capybara', '= 0.4.1.2' +# gem 'factory_girl', '= 1.3.3' +# gem 'factory_girl_rails', '= 1.0.1' +# gem 'faker' +# gem 'launchy' +# if RUBY_VERSION < "1.9" +# gem "ruby-debug" +# else +# gem "ruby-debug19" +# end +#end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..8b6a18c --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,217 @@ +PATH + remote: /Users/Future/Sites/Rails/Projekte/spree/core + specs: + spree_core (0.60.99) + activemerchant (= 1.12.0) + acts_as_list (= 0.1.2) + faker (= 0.9.5) + highline (= 1.5.1) + jquery-rails (= 0.2.6) + meta_search (= 1.0.1) + nested_set (= 1.6.4) + paperclip (= 2.3.8) + rails (= 3.0.6) + rd_find_by_param (= 0.1.1) + rd_resource_controller + rd_unobtrusive_date_picker (= 0.1.0) + state_machine (= 0.9.4) + stringex (= 1.0.3) + will_paginate (= 3.0.pre2) + +PATH + remote: . + specs: + spree_digital (0.60.99) + spree_core (>= 0.60.99) + +GEM + remote: http://rubygems.org/ + specs: + abstract (1.0.0) + actionmailer (3.0.6) + actionpack (= 3.0.6) + mail (~> 2.2.15) + actionpack (3.0.6) + activemodel (= 3.0.6) + activesupport (= 3.0.6) + builder (~> 2.1.2) + erubis (~> 2.6.6) + i18n (~> 0.5.0) + rack (~> 1.2.1) + rack-mount (~> 0.6.14) + rack-test (~> 0.5.7) + tzinfo (~> 0.3.23) + activemerchant (1.12.0) + activesupport (>= 2.3.8) + braintree (>= 2.0.0) + builder (>= 2.0.0) + activemodel (3.0.6) + activesupport (= 3.0.6) + builder (~> 2.1.2) + i18n (~> 0.5.0) + activerecord (3.0.6) + activemodel (= 3.0.6) + activesupport (= 3.0.6) + arel (~> 2.0.2) + tzinfo (~> 0.3.23) + activeresource (3.0.6) + activemodel (= 3.0.6) + activesupport (= 3.0.6) + activesupport (3.0.6) + acts_as_list (0.1.2) + arel (2.0.9) + braintree (2.9.1) + builder + builder (2.1.2) + capybara (0.4.1.2) + celerity (>= 0.7.9) + culerity (>= 0.2.4) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (>= 0.0.27) + xpath (~> 0.1.3) + celerity (0.8.9) + childprocess (0.1.8) + ffi (~> 1.0.6) + columnize (0.3.2) + configuration (1.2.0) + cucumber (0.10.2) + builder (>= 2.1.2) + diff-lcs (>= 1.1.2) + gherkin (>= 2.3.5) + json (>= 1.4.6) + term-ansicolor (>= 1.0.5) + cucumber-rails (0.4.1) + cucumber (>= 0.10.1) + nokogiri (>= 1.4.4) + rack-test (>= 0.5.7) + culerity (0.2.15) + database_cleaner (0.6.7.RC) + diff-lcs (1.1.2) + erubis (2.6.6) + abstract (>= 1.0.0) + factory_girl (1.3.3) + factory_girl_rails (1.0.1) + factory_girl (~> 1.3) + railties (>= 3.0.0) + faker (0.9.5) + i18n (~> 0.4) + ffi (1.0.7) + rake (>= 0.8.7) + gherkin (2.3.5) + json (>= 1.4.6) + highline (1.5.1) + i18n (0.5.0) + jquery-rails (0.2.6) + rails (~> 3.0) + thor (~> 0.14.4) + json (1.5.1) + json_pure (1.5.1) + launchy (0.4.0) + configuration (>= 0.0.5) + rake (>= 0.8.1) + linecache (0.43) + mail (2.2.15) + activesupport (>= 2.3.6) + i18n (>= 0.4.0) + mime-types (~> 1.16) + treetop (~> 1.4.8) + meta_search (1.0.1) + actionpack (~> 3.0.2) + activerecord (~> 3.0.2) + activesupport (~> 3.0.2) + arel (~> 2.0.2) + mime-types (1.16) + nested_set (1.6.4) + activerecord (>= 3.0.0) + railties (>= 3.0.0) + nokogiri (1.4.4) + paperclip (2.3.8) + activerecord + activesupport + polyglot (0.3.1) + rack (1.2.2) + rack-mount (0.6.14) + rack (>= 1.0.0) + rack-test (0.5.7) + rack (>= 1.0) + rails (3.0.6) + actionmailer (= 3.0.6) + actionpack (= 3.0.6) + activerecord (= 3.0.6) + activeresource (= 3.0.6) + activesupport (= 3.0.6) + bundler (~> 1.0) + railties (= 3.0.6) + railties (3.0.6) + actionpack (= 3.0.6) + activesupport (= 3.0.6) + rake (>= 0.8.7) + thor (~> 0.14.4) + rake (0.8.7) + rcov (0.9.9) + rd_find_by_param (0.1.1) + activerecord (~> 3.0) + activesupport (~> 3.0) + rd_resource_controller (1.0.1) + rd_unobtrusive_date_picker (0.1.0) + rspec (2.5.0) + rspec-core (~> 2.5.0) + rspec-expectations (~> 2.5.0) + rspec-mocks (~> 2.5.0) + rspec-core (2.5.1) + rspec-expectations (2.5.0) + diff-lcs (~> 1.1.2) + rspec-mocks (2.5.0) + rspec-rails (2.5.0) + actionpack (~> 3.0) + activesupport (~> 3.0) + railties (~> 3.0) + rspec (~> 2.5.0) + ruby-debug (0.10.4) + columnize (>= 0.1) + ruby-debug-base (~> 0.10.4.0) + ruby-debug-base (0.10.4) + linecache (>= 0.3) + rubyzip (0.9.4) + selenium-webdriver (0.1.4) + childprocess (>= 0.1.7) + ffi (>= 1.0.7) + json_pure + rubyzip + shoulda (2.11.3) + sqlite3 (1.3.3) + sqlite3-ruby (1.3.3) + sqlite3 (>= 1.3.3) + state_machine (0.9.4) + stringex (1.0.3) + term-ansicolor (1.0.5) + thor (0.14.6) + treetop (1.4.9) + polyglot (>= 0.3.1) + tzinfo (0.3.26) + will_paginate (3.0.pre2) + xpath (0.1.3) + nokogiri (~> 1.3) + +PLATFORMS + ruby + +DEPENDENCIES + capybara (= 0.4.1.2) + cucumber-rails + database_cleaner (= 0.6.7.RC) + factory_girl (= 1.3.3) + factory_girl_rails (= 1.0.1) + faker + launchy + nokogiri + rcov + rspec-rails (= 2.5.0) + ruby-debug + shoulda + spree_core! + spree_digital! + sqlite3-ruby diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..82bf74f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011 funkensturm. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.textile b/README.textile new file mode 100644 index 0000000..3c6fadb --- /dev/null +++ b/README.textile @@ -0,0 +1,114 @@ +h2. Spree Digital + +This is a spree extension to enable downloadable products. The design goal is to keep it robust. It should survive future spree versions out of the box. + +NOTE: This is still under development, but since things were falling into place, I thought I'd publish it. + +h3. Introduction + +The idea is simple. You attach a file to a Product (or a Variant of this Product) and when people buy it, they will receive a link via email where they can download it once. There are a few assumptions that spree_digital (currently) makes and it's important to be aware of them. These might change, but since I programmed digital_spree over night, this is what you get ;) + +* The table structure of spree_core is not touched. Spree_digital lives parallel to spree_core and does not do any changes to your existing database, except adding two new tables. +* The download links will be sent via email in the order confirmation (or "resend" from the admin section). The links do *not* appear in the order "overview" that the customer sees. +* There should only be "live" payments. Once the order is checked-out, the download links will immediately be sent (i.e. in the order confirmation). +* You should define a shipping method called "download" and it should be cost-free. Spree_digital will use that one when all products in the cart are digital +* One may buy several items of the same digital product in one cart. The customer will simply receive several links by doing so. This allows customer's to legally purchase multiple copies of the same product and maybe give one away to a friend. +* The links will only work 3 times (but we tell the customer that it works only once). After 24 hours the links are deactivated. This should keep you reasonably free from complaints of people who are not capable of appropriately clicking on a link. They can try a whole day long, 3 times per link. The file should really be downloadable for weird customers. I understand that this is a little bit security by obscurity, but it's better than other solutions that I've seen. +* The file @views/order_mailer/confirm_email.text.erb@ is the only thing that should need customization. But since I assume you do that anyway, it doesn't hurt to do it when you're using spree_digital. The reason is that the download links are added to the confirmation email to the customer. +* A purchased product can be downloaded even if you disable the product immediately. You would have to remove the attached file in your admin section to prevent people from downloading purchased products. + +h3. Installation + +Add something like this to your @Gemfile@ in your brand new Rails 3 application: + +
+  gem 'spree'
+  gem 'spree_social', :git => 'git://github.com/funkensturm/spree_digital.git', :branch => 'master'
+
+ +If you prefer to use specific versions, feel free to do so. This configuration, for instance, determines some versions manually: + +
+  gem 'rails', '= 3.0.5'
+  gem 'spree', '= 0.50.0'
+  gem 'spree_social', :git => 'git://github.com/funkensturm/spree_digital.git', :branch => 'master'
+
+ +The following terminal commands are corresponding to the spree README at "github.com/spree/spree":http://github.com/spree/spree and are needed to bring up spree: + +
+  bundle install
+  rails g spree:site
+  rake spree:install
+  rake db:migrate
+
+ +Of course you may already have a spree application running. But *either way* you will have to run these two commands at this point: + +
+  rake spree_digital:install   # This one will copy the migration file from spree_digital to your rails_root/db/migrate
+  rake db:migrate
+
+ +This should be it. You might want to populate your store with sample data like so: + +
+  rake spree_sample:install
+  rake db:seed
+  rake db:sample
+
+ +h4. Important Notice + +You should go to the spree admin section and create a shipping method that has the word @download@ somehow in its name (it should be cost-free, but it doesn't have to). It will be detected by spree_digital. Otherwise your customer will be forced to choose something like "UPS" even if they purchase only downloadable products. + +h3. Usage + +... + + +h1. Developer Section + +h3. Table Diagram + + + +h3. Installation (for Developers) + +Get the spree framework and spree_digital extension for it: + +
+  git clone git://github.com/spree/spree.git
+  git clone git://github.com/funkensturm/spree_digital
+
+ +Go into the spree directory and run the bundle command: + +
+  cd spree
+  bundle install
+
+ +Go into the spree_digital directory and do the same: + +NOTE: At this point you may need to uncomment the stuff in the @Gemfile@ before you can start developing and testing! + +
+  cd spree_digital
+  bundle install
+
+ +Bring up the test application (you only need to do this whenever you fiddle around with the migrations) and then you can run the tests as you please. + +
+  rake test_app
+  rake spec
+
+ +This link may be very helpful to you: "http://github.com/spree/spree":http://github.com/spree/spree + +h3. License + +Copyright (c) 2011 funkensturm. +Released under the MIT License +See "LICENSE":LICENSE \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..e5bd00a --- /dev/null +++ b/Rakefile @@ -0,0 +1,75 @@ +require 'rubygems' +require 'rake' +require 'rake/testtask' +require 'rake/packagetask' +require 'rake/gempackagetask' + +gemfile = File.expand_path('../spec/test_app/Gemfile', __FILE__) +if File.exists?(gemfile) && (%w(spec cucumber).include?(ARGV.first.to_s) || ARGV.size == 0) + require 'bundler' + ENV['BUNDLE_GEMFILE'] = gemfile + Bundler.setup + + require 'rspec' + require 'rspec/core/rake_task' + RSpec::Core::RakeTask.new + + require 'cucumber/rake/task' + Cucumber::Rake::Task.new do |t| + t.cucumber_opts = %w{--format progress} + end +end + +desc "Default Task" +task :default => [:spec, :cucumber ] + +spec = eval(File.read('spree_digital.gemspec')) + +Rake::GemPackageTask.new(spec) do |p| + p.gem_spec = spec +end + +desc "Release to gemcutter" +task :release => :package do + require 'rake/gemcutter' + Rake::Gemcutter::Tasks.new(spec).define + Rake::Task['gem:push'].invoke +end + +desc "Default Task" +task :default => [ :spec ] + +desc "Regenerates a rails 3 app for testing" +task :test_app do + require '../spree/lib/generators/spree/test_app_generator' + class SpreeDigitalTestAppGenerator < Spree::Generators::TestAppGenerator + + def install_gems + inside "test_app" do + run 'rake spree_core:install' + run 'rake spree_digital:install' + end + end + + def migrate_db + run_migrations + end + + protected + def full_path_for_local_gems + <<-gems +gem 'spree_core', :path => \'#{File.join(File.dirname(__FILE__), "../spree/", "core")}\' +gem 'spree_digital', :path => \'#{File.dirname(__FILE__)}\' + gems + end + + end + SpreeDigitalTestAppGenerator.start +end + +namespace :test_app do + desc 'Rebuild test and cucumber databases' + task :rebuild_dbs do + system("cd spec/test_app && rake db:drop db:migrate RAILS_ENV=test && rake db:drop db:migrate RAILS_ENV=cucumber") + end +end diff --git a/Versionfile b/Versionfile new file mode 100644 index 0000000..d5a23f3 --- /dev/null +++ b/Versionfile @@ -0,0 +1,7 @@ +# This file is used to designate compatibilty with different versions of Spree +# Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details + +# Currently this works with these both: + +"0.60.x" => { :branch => "master" } +"0.50.x" => { :branch => "master" } \ No newline at end of file diff --git a/app/controllers/admin/digitals_controller.rb b/app/controllers/admin/digitals_controller.rb new file mode 100644 index 0000000..33fbba6 --- /dev/null +++ b/app/controllers/admin/digitals_controller.rb @@ -0,0 +1,12 @@ +class Admin::DigitalsController < Admin::BaseController + + resource_controller + + index.before do + @product = Product.find_by_permalink(params[:product_id]) + end + + create.wants.html { redirect_to admin_product_digitals_url(@product) } + destroy.wants.html { redirect_to admin_product_digitals_url(@product) } + +end diff --git a/app/controllers/digitals_controller.rb b/app/controllers/digitals_controller.rb new file mode 100644 index 0000000..4a42470 --- /dev/null +++ b/app/controllers/digitals_controller.rb @@ -0,0 +1,16 @@ +class DigitalsController < Spree::BaseController + + ssl_required :show + + def show + link = DigitalLink.find_by_secret(params[:secret]) + if link.present? and link.digital.attachment.present? + attachment = link.digital.attachment + if link.authorize! and File.file?(attachment.path) + send_file attachment.path :filename => attachment.original_filename, :type => attachment.content_type and return + end + end + render :unauthorized + end + +end diff --git a/app/models/digital.rb b/app/models/digital.rb new file mode 100644 index 0000000..79d8c0d --- /dev/null +++ b/app/models/digital.rb @@ -0,0 +1,10 @@ +class Digital < ActiveRecord::Base + + belongs_to :variant + has_many :digital_links, :dependent => :destroy + + has_attached_file :attachment, :path => ":rails_root/private/digitals/:id/:basename.:extension" + + # TODO: Limit the attachment to one single file. Paperclip supports many by default :/ + +end \ No newline at end of file diff --git a/app/models/digital_link.rb b/app/models/digital_link.rb new file mode 100644 index 0000000..813ae00 --- /dev/null +++ b/app/models/digital_link.rb @@ -0,0 +1,27 @@ +class DigitalLink < ActiveRecord::Base + + belongs_to :digital + belongs_to :line_item + + before_validation :set_defaults, :on => :create + + # Can this link stil be used? It is valid if it's less than 24 hours old and was not accessed more than 3 times + def authorizable? + self.created_at > 1.day.ago and self.access_counter < 3 + end + + # This method should be called when a download is initiated. + # It returns +true+ or +false+ depending on whether the authorization is granted. + def authorize! + authorizable? && increment!(:access_counter) ? true : false + end + + private + + # Populating the secret automatically and zero'ing the access_counter (otherwise it might turn out to be NULL) + def set_defaults + self.secret = SecureRandom.hex(15) + self.access_counter = 0 + end + +end \ No newline at end of file diff --git a/app/models/line_item_decorator.rb b/app/models/line_item_decorator.rb new file mode 100644 index 0000000..b073c03 --- /dev/null +++ b/app/models/line_item_decorator.rb @@ -0,0 +1,22 @@ +LineItem.class_eval do + + has_many :digital_links + + after_save :create_digital_links, :if => :digital? + + # Is this item digital? + def digital? + variant.digital? + end + + private + + # Create the download link for this item if it is digital. + def create_digital_links + digital_links.delete_all + self.quantity.times do + digital_links.create!(:digital => variant.digital) + end + end + +end \ No newline at end of file diff --git a/app/models/order_decorator.rb b/app/models/order_decorator.rb new file mode 100644 index 0000000..2386868 --- /dev/null +++ b/app/models/order_decorator.rb @@ -0,0 +1,20 @@ +Order.class_eval do + + # Are all products/variants of this Order to be downloaded by the customer? + def digital? + line_items.map { |item| return false unless item.digital? } + true + end + + # Determine which method to use for shipping of digital products. + def digital_shipping_method + rates = rate_hash + # If there is a shipping method has "Download" in its name then we take that one. + rates.each { |rate| return rate if rate[:name].downcase.include?('download') } + # Other than that, we take the first one that we find that doesn't cost anything. + rates.each { |rate| return rate if rate[:cost] == 0 } + # Well, at this point we have a problem. No shipping method is cost-free or called "download". + nil + end + +end \ No newline at end of file diff --git a/app/models/variant_decorator.rb b/app/models/variant_decorator.rb new file mode 100644 index 0000000..bf07ceb --- /dev/null +++ b/app/models/variant_decorator.rb @@ -0,0 +1,20 @@ +Variant.class_eval do + + has_one :digital, :dependent => :destroy + after_save :destroy_digital, :if => :deleted? + + # Is this variant to be downloaded by the customer? + def digital? + digital.present? + end + + private + + # Spree never deleted Digitals, that's why ":dependent => :destroy" won't work on Digital. + # We need to delete the Digital manually here as soon as the Variant is nullified. + # Otherwise you'll have orphan Digitals (and their attached files!) associated with unused Variants. + def destroy_digital + digital.destroy + end + +end \ No newline at end of file diff --git a/app/views/admin/digitals/_digital.html.erb b/app/views/admin/digitals/_digital.html.erb new file mode 100644 index 0000000..284453c --- /dev/null +++ b/app/views/admin/digitals/_digital.html.erb @@ -0,0 +1,5 @@ +<% if digital.attachment_file_name.present? %> + <%= digital.attachment_file_name %> (<%= number_to_human_size(digital.attachment_file_size) %>) +<% else %> + <%=t 'broken_file' %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/digitals/_form.html.erb b/app/views/admin/digitals/_form.html.erb new file mode 100644 index 0000000..6cf9bb2 --- /dev/null +++ b/app/views/admin/digitals/_form.html.erb @@ -0,0 +1,35 @@ +
+
+ <%= form_for(:digital, :url => { :controller => 'digitals', :action => 'create' }, :html => { :multipart => true }) do |f| %> +
+ <%= Variant.human_name %> "<%= variant.options_text %>" + + <%= f.field_container :current_file do %> + <%=t 'current_file' %>:
+ <% if variant.digital? %> + <%= render variant.digital %><%= %> + <% else %> + <%=t 'none' %> + <% end %> + <% end %> + +

+ <% if variant.digital? %> + <%= link_to t("delete_file"), admin_product_digital_url(:id => variant.digital.id), :confirm => t('delete_file_cofirmation', :filename => variant.digital.attachment_file_name), :method => :delete %> + <% else %> + + <%= f.field_container :file do %> + <%= f.label :file, t("new_file") %> *
+ <%= f.file_field :attachment %> + <% end %> + + <%= hidden_field_tag 'digital[variant_id]', variant.id %> + + <%= button t("upload") %> + <% end %> +

+ +
+ <% end %> +
+

\ No newline at end of file diff --git a/app/views/admin/digitals/index.html.erb b/app/views/admin/digitals/index.html.erb new file mode 100644 index 0000000..2fca15b --- /dev/null +++ b/app/views/admin/digitals/index.html.erb @@ -0,0 +1,20 @@ +<%= render :partial => 'admin/shared/product_sub_menu' %> +<%= render :partial => 'admin/shared/product_tabs', :locals => {:current => "Digital Versions"} %> + +<% if @product.has_variants? %> + + <% for variant in @product.variants do %> + <%= render 'form', :variant => variant %> + <% end %> + +<% else %> + This product has no variants. + + <% if @product.master.digital? %> + A digital version of this product currently exists: + <%= render @product.master.digital %> + <% end %> + + <%= render 'form', :variant => @product.master %> + +<% end %> \ No newline at end of file diff --git a/app/views/checkout/_delivery.html.erb b/app/views/checkout/_delivery.html.erb new file mode 100644 index 0000000..2a6c89d --- /dev/null +++ b/app/views/checkout/_delivery.html.erb @@ -0,0 +1,5 @@ +<%# + This is basically a switch that will render the appropriate "delivery choice" partial. + When there are no physical items at all, there should be no different shipping methods to choose. +%> +<%= render @order.digital? && @order.digital_shipping_method.present? ? 'delivery_digital' : 'delivery_original' %> \ No newline at end of file diff --git a/app/views/checkout/_delivery_digital.html.erb b/app/views/checkout/_delivery_digital.html.erb new file mode 100644 index 0000000..8a48847 --- /dev/null +++ b/app/views/checkout/_delivery_digital.html.erb @@ -0,0 +1,12 @@ +
+ <%= t("shipping_method") %> + + <%= radio_button :order, :shipping_method_id, @order.digital_shipping_method[:id] %> + <%==t 'digital_shipping', :email => current_user.email %> (<%= number_to_currency @order.digital_shipping_method[:cost] %>) + + +
+ +
+ "/> +
diff --git a/app/views/checkout/_delivery_original.html.erb b/app/views/checkout/_delivery_original.html.erb new file mode 100644 index 0000000..2c4becb --- /dev/null +++ b/app/views/checkout/_delivery_original.html.erb @@ -0,0 +1,32 @@ +<%# + NOTE: The code below is an exact duplication of `spree_core/views/checkout/_delivery.html.erb“ + We overwrote the original so we retain access to it by cloning it here. + Feel free to update the code below according to the original if needed! +%> + +
+ <%= t("shipping_method") %> +
+
+

+ <% @order.rate_hash.each do |shipping_method| %> + <% next if shipping_method[:id] == @order.digital_shipping_method[:id] %> +
+ <% end %> +

+
+ <% if Spree::Config[:shipping_instructions] && @order.rate_hash.present? %> +

+ <%= form.label :special_instructions, t("shipping_instructions") %>
+ <%= form.text_area :special_instructions, :cols => 40, :rows => 7 %> +

+ <% end %> +
+
+ +
+ "/> +
\ No newline at end of file diff --git a/app/views/order_mailer/confirm_email.text.erb b/app/views/order_mailer/confirm_email.text.erb new file mode 100644 index 0000000..3fa1d50 --- /dev/null +++ b/app/views/order_mailer/confirm_email.text.erb @@ -0,0 +1,36 @@ +Dear Customer, + +Please review and retain the following order information for your records. + +============================================================ +Order Summary +============================================================ +<% for item in @order.line_items %> +<%= item.variant.sku %> <%=item.variant.product.name%> <%= variant_options(item.variant) %> (<%=item.quantity%>) @ <%= number_to_currency item.price %> = <%= number_to_currency(item.price * item.quantity) %> +<% end %> +============================================================ +Subtotal: <%= number_to_currency @order.item_total %> +<% @order.adjustments.each do |adjustment| %> +<%= "#{adjustment.label}: #{number_to_currency adjustment.amount}"%> +<% end %> +Order Total: <%= number_to_currency @order.total %> + +============================================================ +Download links for digital products +============================================================ + +ATTENTION! Each link will only work a SINGLE TIME! + Also, they will only work WITHIN 24 HOURS! + +<% for item in @order.line_items %> +<% if item.digital? %> +<%= item.variant.name %>: +<% for link in item.digital_links %> +<%= digital_url :protocol => 'https', :host => "yourdomainxygoeshere.com", :secret => link.secret %> +<% end %> + +<% end %> +<% end %> +============================================================ + +Thank you for your business. diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..4fc0c04 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,12 @@ +en: + digital_versions: Digital Versions + + current_file: Current File + new_file: New File + upload: Upload + delete_file: Delete this file + broken_file: Warning! this file is broken + delete_file_cofirmation: Are you sure you want to delete the file %{filename}? + + digital_shipping: Delivery per email to %{email} + \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..5c0677a --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,11 @@ +Rails.application.routes.draw do + + namespace :admin do + resources :products do + resources :digitals + end + end + + get '/digital/:secret', :to => 'digitals#show', :via => :get, :as => 'digital', :constraints => { :secret => /[a-zA-Z0-9]{30}/ } + +end \ No newline at end of file diff --git a/db/migrate/20110410134726_create_digitals.rb b/db/migrate/20110410134726_create_digitals.rb new file mode 100644 index 0000000..15f5271 --- /dev/null +++ b/db/migrate/20110410134726_create_digitals.rb @@ -0,0 +1,30 @@ +class CreateDigitals < ActiveRecord::Migration + + def self.up + create_table :digitals do |t| + t.integer :variant_id + t.string :attachment_file_name + t.string :attachment_content_type + t.integer :attachment_file_size + t.timestamps + end + add_index :digitals, :variant_id + + create_table :digital_links, :force => true do |t| + t.integer :digital_id + t.integer :line_item_id + t.string :secret + t.integer :access_counter + t.timestamps + end + add_index :digital_links, :digital_id + add_index :digital_links, :line_item_id + add_index :digital_links, :secret + end + + def self.down + drop_table :digitals + drop_table :digital_links + end + +end diff --git a/doc/tables.png b/doc/tables.png new file mode 100644 index 0000000000000000000000000000000000000000..052ee8e13fea7d0384e461e4409a8dc6de7c7ad0 GIT binary patch literal 98091 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

P|3?fC`73z_-MiF@ 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 literal 0 HcmV?d00001 diff --git a/lib/spree_digital.rb b/lib/spree_digital.rb new file mode 100644 index 0000000..146666f --- /dev/null +++ b/lib/spree_digital.rb @@ -0,0 +1,17 @@ +require 'spree_core' +require 'spree_digital_hooks' + +module SpreeDigital + class Engine < Rails::Engine + + config.autoload_paths += %W(#{config.root}/lib) + + def self.activate + Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c| + Rails.env.production? ? require(c) : load(c) + end + end + + config.to_prepare &method(:activate).to_proc + end +end diff --git a/lib/spree_digital_hooks.rb b/lib/spree_digital_hooks.rb new file mode 100644 index 0000000..fbc4f8b --- /dev/null +++ b/lib/spree_digital_hooks.rb @@ -0,0 +1,11 @@ +class SpreeDigitalHooks < Spree::ThemeSupport::HookListener + + insert_after :admin_product_tabs do + <<-END + > + <%= link_to t("digital_versions"), admin_product_digitals_path(@product) %> + + END + end + +end \ No newline at end of file diff --git a/lib/tasks/install.rake b/lib/tasks/install.rake new file mode 100644 index 0000000..bb5f853 --- /dev/null +++ b/lib/tasks/install.rake @@ -0,0 +1,18 @@ +namespace :spree_digital do + + desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)" + task :install do + Rake::Task['spree_digital:install:migrations'].invoke + end + + namespace :install do + + desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)" + task :migrations do + source = File.join(File.dirname(__FILE__), '..', '..', 'db') + destination = File.join(Rails.root, 'db') + Spree::FileUtilz.mirror_files(source, destination) + end + + end +end \ No newline at end of file diff --git a/lib/tasks/spree_digital.rake b/lib/tasks/spree_digital.rake new file mode 100644 index 0000000..2c5c4e2 --- /dev/null +++ b/lib/tasks/spree_digital.rake @@ -0,0 +1 @@ +# add custom rake tasks here \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb new file mode 100644 index 0000000..c0ae53a --- /dev/null +++ b/spec/factories.rb @@ -0,0 +1,6 @@ +require 'factory_girl' + +Dir["#{File.dirname(__FILE__)}/factories/**"].each do |f| + fp = File.expand_path(f) + require fp +end diff --git a/spec/factories/digital_factory.rb b/spec/factories/digital_factory.rb new file mode 100644 index 0000000..3c77261 --- /dev/null +++ b/spec/factories/digital_factory.rb @@ -0,0 +1,3 @@ +Factory.define :digital do |f| + f.variant { |p| p.association(:variant) } +end \ No newline at end of file diff --git a/spec/factories/digital_link_factory.rb b/spec/factories/digital_link_factory.rb new file mode 100644 index 0000000..fea0395 --- /dev/null +++ b/spec/factories/digital_link_factory.rb @@ -0,0 +1,4 @@ +Factory.define :digital_link do |f| + f.digital { |p| p.association(:digital) } + f.line_item { |p| p.association(:line_item) } +end \ No newline at end of file diff --git a/spec/models/digital_link_spec.rb b/spec/models/digital_link_spec.rb new file mode 100644 index 0000000..1d4d18f --- /dev/null +++ b/spec/models/digital_link_spec.rb @@ -0,0 +1,98 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe DigitalLink do + + context 'validation' do + it { should belong_to(:digital) } + it { should belong_to(:line_item) } + it { should have_valid_factory(:digital_link) } + end + + context "#create" do + it "should have an appropriately long secret" do + Factory(:digital_link).secret.length.should == 30 + end + + it "should have the access counter being an Integer on zero" do + Factory(:digital_link).access_counter.should == 0 + end + end + + context "#update" do + it "should not change the secret when updated" do + digital_link = Factory(:digital_link) + secret = digital_link.secret + digital_link.increment(:access_counter).save + digital_link.secret.should == secret + end + + it "should enforce to have an associated digital" do + link = Factory(:digital_link) + lambda { link.update_attributes!(:digital => nil) }.should raise_error(ActiveRecord::RecordInvalid) + end + + it "should not allow an empty or too short secret" do + link = Factory(:digital_link) + lambda { link.update_attributes!(:secret => nil) }.should raise_error(ActiveRecord::RecordInvalid) + lambda { link.update_attributes!(:secret => 'x' * 25) }.should raise_error(ActiveRecord::RecordInvalid) + end + end + + #context "authorization" do + # it "should increment the counter using #authorize!" do + # link = Factory(:digital_link) + # link.authorize! + # link.access_counter.should == 1 + # end + # + # it "should not be #authorized? when the access_counter is too high" do + # link = Factory(:digital_link) + # link.stub(:access_counter => 2) + # link.authorized?.should be_true + # link.stub(:access_counter => 3) + # link.authorized?.should be_false + # end + # + # it "should not be #authorize! when the access_counter is too high" do + # link = Factory(:digital_link) + # link.stub(:access_counter => 2) + # link.authorize!.should be_true + # link.stub(:access_counter => 3) + # link.authorize!.should be_false + # end + # + # it "should not be #authorized? when the created_at date is too far in the past" do + # link = Factory(:digital_link) + # link.authorized?.should be_true + # link.stub(:created_at => 23.hours.ago) + # link.authorized?.should be_true + # link.stub(:created_at => 25.hours.ago) + # link.authorized?.should be_false + # end + # + # it "should not be #authorize! when the created_at date is too far in the past" do + # link = Factory(:digital_link) + # link.authorize!.should be_true + # link.stub(:created_at => 23.hours.ago) + # link.authorize!.should be_true + # link.stub(:created_at => 25.hours.ago) + # link.authorize!.should be_false + # end + # + # it "should not be #authorized? when both access_counter and created_at are invalid" do + # link = Factory(:digital_link) + # link.authorized?.should be_true + # link.stub(:access_counter => 3, :created_at => 25.hours.ago) + # link.authorized?.should be_false + # end + # + # it "should not be #authorize! when both access_counter and created_at are invalid" do + # link = Factory(:digital_link) + # link.authorize!.should be_true + # link.stub(:access_counter => 3, :created_at => 25.hours.ago) + # link.authorize!.should be_false + # end + #end + +end + diff --git a/spec/models/digital_spec.rb b/spec/models/digital_spec.rb new file mode 100644 index 0000000..9d7cb41 --- /dev/null +++ b/spec/models/digital_spec.rb @@ -0,0 +1,25 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe Digital do + + context 'validation' do + it { should belong_to(:variant) } + it { should have_valid_factory(:digital) } + end + + context "#create" do + + end + + context "#destroy" do + #it "should destroy associated digital_links" do + # digital = Factory(:digital) + # 3.times { digital.digital_links.create! :order => Factory(:order) } + # DigitalLink.count.should == 3 + # digital.destroy + # DigitalLink.count.should == 0 + #end + end + +end + diff --git a/spec/models/line_item_spec.rb b/spec/models/line_item_spec.rb new file mode 100644 index 0000000..f0d6c8e --- /dev/null +++ b/spec/models/line_item_spec.rb @@ -0,0 +1,33 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe LineItem do + + context "#save" do + it "should create one link for a single digital Variant" do + digital_variant = Factory(:variant, :digital => Factory(:digital)) + line_item = Factory(:line_item, :variant => digital_variant) + links = digital_variant.digital.digital_links + links.all.size.should == 1 + links.first.line_item.should == line_item + end + + it "should create a link for each quantity of a digital Variant, even when quantity changes later" do + digital_variant = Factory(:variant, :digital => Factory(:digital)) + line_item = Factory(:line_item, :variant => digital_variant, :quantity => 5) + links = digital_variant.digital.digital_links + links.all.size.should == 5 + links.each { |link| link.line_item.should == line_item } + # quantity update + line_item.quantity = 8 + line_item.save + links = digital_variant.digital.digital_links + links.all.size.should == 8 + links.each { |link| link.line_item.should == line_item } + end + end + +end + + + + diff --git a/spec/models/order_spec.rb b/spec/models/order_spec.rb new file mode 100644 index 0000000..4784f87 --- /dev/null +++ b/spec/models/order_spec.rb @@ -0,0 +1,54 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe Order do + + context 'validation' do + it { should have_valid_factory(:order) } + end + + context "#add_variant" do + it "should add digital Variants of quantity 1 to an order" do + order = Factory(:order) + order.add_variant variant1 = Factory(:variant, :digital => Factory(:digital)) + order.add_variant variant2 = Factory(:variant, :digital => Factory(:digital)) + order.add_variant variant3 = Factory(:variant, :digital => Factory(:digital)) + order.line_items.first.variant.should == variant1 + order.line_items.second.variant.should == variant2 + order.line_items.third.variant.should == variant3 + end + + it "should handle quantity higher than 1 when adding one specific digital Variant" do + order = Factory(:order) + digital_variant = Factory(:variant, :digital => Factory(:digital)) + order.add_variant digital_variant, 3 + order.line_items.first.quantity.should == 3 + order.add_variant digital_variant, 2 + order.line_items.first.quantity.should == 5 + end + end + + context "line_item analysis" do + it "should understand that all products are digital" do + order = Factory(:order) + 3.times do + order.add_variant Factory(:variant, :digital => Factory(:digital)) + end + order.digital?.should be_true + order.add_variant Factory(:variant, :digital => Factory(:digital)), 4 + order.digital?.should be_true + end + + it "should understand that not all products are digital" do + order = Factory(:order) + 3.times do + order.add_variant Factory(:variant, :digital => Factory(:digital)) + end + order.add_variant Factory(:variant) # this is the analog product + order.digital?.should be_false + order.add_variant Factory(:variant, :digital => Factory(:digital)), 4 + order.digital?.should be_false + end + end + +end + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..ad92fa0 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,61 @@ +require File.expand_path("../factories", __FILE__) + + + +######################################################################## +# NOTE: The rest of file is the same as spree/core/spec/spec_helper.rb # +######################################################################## + + + + + + + +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. +ENV["RAILS_ENV"] ||= 'test' +require File.expand_path("../test_app/config/environment", __FILE__) +require 'rspec/rails' + +# Requires supporting files with custom matchers and macros, etc, +# in ./support/ and its subdirectories. +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} + +require 'spree_core/testing_support/factories' + +RSpec.configure do |config| + # == Mock Framework + # + # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: + # + # config.mock_with :mocha + # config.mock_with :flexmock + # config.mock_with :rr + config.mock_with :rspec + + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + #config.include Devise::TestHelpers, :type => :controller + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, comment the following line or assign false + # instead of true. + config.use_transactional_fixtures = true +end + +@configuration ||= AppConfiguration.find_or_create_by_name("Default configuration") + +PAYMENT_STATES = Payment.state_machine.states.keys unless defined? PAYMENT_STATES +SHIPMENT_STATES = Shipment.state_machine.states.keys unless defined? SHIPMENT_STATES +ORDER_STATES = Order.state_machine.states.keys unless defined? ORDER_STATES + +# Usage: +# +# context "factory" do +# it { should have_valid_factory(:address) } +# end +RSpec::Matchers.define :have_valid_factory do |factory_name| + match do |model| + Factory(factory_name).new_record?.should be_false + end +end diff --git a/spree_digital.gemspec b/spree_digital.gemspec new file mode 100644 index 0000000..34d8cc7 --- /dev/null +++ b/spree_digital.gemspec @@ -0,0 +1,15 @@ +Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = 'spree_digital' + s.version = '0.60.99' + s.summary = '' + s.description = 'This gem is supposed to be used in connection with spree_core. It was tested with spree_core 0.66.99 but it might work with newer versions as well.' + s.author = 'funkensturm.' + s.homepage = 'http://www.funkensturm.com' + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.require_path = 'lib' + s.requirements << 'none' + s.required_ruby_version = '>= 1.8.7' + s.add_dependency('spree_core') +end \ No newline at end of file diff --git a/spree_digital.tmproj b/spree_digital.tmproj new file mode 100644 index 0000000..7546494 --- /dev/null +++ b/spree_digital.tmproj @@ -0,0 +1,48 @@ + + + + + currentDocument + Gemfile + documents + + + expanded + + name + spree_digital + regexFolderFilter + !.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$ + sourceDirectory + + + + fileHierarchyDrawerWidth + 262 + metaData + + Gemfile + + caret + + column + 19 + line + 4 + + firstVisibleColumn + 0 + firstVisibleLine + 0 + + + openDocuments + + Gemfile + + showFileHierarchyDrawer + + windowFrame + {{8, 81}, {992, 680}} + +