app/controllers/plugins/ecommerce/front/checkout_controller.rb in camaleon_ecommerce-0.0.4 vs app/controllers/plugins/ecommerce/front/checkout_controller.rb in camaleon_ecommerce-1.1

- old
+ new

@@ -5,162 +5,214 @@ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License (GPLv3) for more details. =end class Plugins::Ecommerce::Front::CheckoutController < Plugins::Ecommerce::FrontController - + before_action :commerce_authenticate before_action :set_cart + before_action :set_payment, only: [:pay_by_stripe, :pay_by_bank_transfer, :pay_by_credit_card, :pay_by_authorize_net, :pay_by_paypal] def index - if @cart.products.size > 0 - @products = @cart.products - else - flash[:notice] = "Not found products." - redirect_to action: :cart_index + unless @cart.product_items.count > 0 + flash[:notice] = t('plugins.ecommerce.messages.cart_no_products', default: 'Not exist products in your cart') + return redirect_to action: :cart_index end - @ecommerce_bredcrumb << ["Checkout"] + @ecommerce_bredcrumb << [t('plugins.ecommerce.messages.checkout', default: 'Checkout')] end - def processing + def step_address + @cart.set_meta("billing_address", params[:order][:billing_address]) + @cart.set_meta("shipping_address", params[:order][:shipping_address]) + render nothing: true + end + def step_shipping + @cart.update_column(:shipping_method_id, params[:shipping_method]) + if params[:next_step].present? + render partial: plugin_view('partials/checkout/payments'), layout: false + else + render partial: plugin_view('partials/checkout/products_detail'), layout: false + end + end - @products = @cart.products - - total_weight = 0 - tax_total = 0 - sub_total = 0 - - pay_status = 'unpaid' - - @products.each do |product| - product = product.decorate - product_options = @cart.get_option("product_#{product.id}") - price = product_options[:price].to_f - qty = product_options[:qty].to_f - qty_real = product.get_field_value('ecommerce_qty').to_f - if qty_real < 1 - @cart.delete_option("product_#{product.id}") if qty < 1 + # free carts + def complete_free_order + if @cart.free_cart? + errors = ecommerce_verify_cart_errors(@cart) + if errors.present? + flash[:error] = errors.join('<br>') + redirect_to :back else - qty = qty_real if qty > qty_real - tax_product = product_options[:tax].to_f - tax_total += tax_product * qty - total_weight += product_options[:weight].to_f * product_options[:qty].to_f - sub_total += price * qty - product.update_field_value('ecommerce_qty', (qty_real - qty).to_i) + @cart.set_meta('free_order', true) + mark_order_like_received(@cart) + redirect_to plugins_ecommerce_orders_path end - end - - shipping_method = current_site.shipping_methods.find(params[:order][:payment][:shipping_method]) - weight_price = shipping_method.get_price_from_weight(total_weight) - - total = sub_total + tax_total + weight_price - - payment_amount = total - - coupon_total = '' - coupon_amount = 0 - if params[:order][:payment][:coupon_code].present? - coupon = current_site.coupons.find_valid_by_code(params[:order][:payment][:coupon_code]) - if coupon.present? - coupon = coupon.decorate - coupon_total = coupon.the_amount - opts = coupon.options - - case opts[:discount_type] - when 'free_ship' - pay_status = 'received' - coupon_amount = payment_amount - when 'percent' - coupon_amount = sub_total * opts[:amount].to_f / 100 - when 'money' - coupon_amount = opts[:amount].to_f - end - payment_amount = payment_amount - coupon_amount - end - end - - payment_amount = 0 if payment_amount < 0 - - order_id = Time.now.to_i - @order = current_site.orders.set_user(current_user).create(name: "Order #{order_id}", slug: order_id, status: pay_status) - details = params[:order][:details] - details[:received_at] = Time.now - @order.create_details(details) - @order.set_meta("products", @cart.options) - @order.set_meta("details", params[:order][:details]) - @order.set_meta("billing_address", params[:order][:billing_address]) - @order.set_meta("shipping_address", params[:order][:shipping_address]) - total = sub_total + tax_total + weight_price - @order.set_meta("payment", params[:order][:payment].merge({ - amount: payment_amount, - currency_code: current_site.currency_code, - total: total, - sub_total: sub_total, - tax_total: tax_total, - weight_price: weight_price, - coupon: coupon_total, - coupon_amount: coupon_amount - })) - - @cart.destroy - - if payment_amount > 0 - redirect_to plugins_ecommerce_order_select_payment_path(order: @order.slug) else - flash[:notice] = "Saved Orders." - redirect_to plugins_ecommerce_orders_path + flash[:error] = "Invalid complete payment" + redirect_to :back end end def cart_index - @products = @cart.products - @ecommerce_bredcrumb << ["Shopping Cart"] + @products = @cart.product_items.decorate + @ecommerce_bredcrumb << [t('plugins.ecommerce.messages.shopping_cart', default: 'Shopping cart')] end + def res_coupon + code = params[:code].to_s.downcase + res = @cart.discount_for(code) + if res[:error].present? + render inline: commerce_coupon_error_message(res[:error], res[:coupon]), status: 500 + else + @cart.update_column(:coupon, code) + render partial: plugin_view('partials/checkout/products_detail'), layout: false + end + end + # params[cart]: product_id, qty def cart_add data = params[:cart] - product_id = data[:product_id] - @cart.add_product(product_id) - @cart.set_option("product_#{product_id}", e_add_data_product(data, product_id)) - flash[:notice] = t('plugin.ecommerce.msg.added_product_in_cart') + qty = data[:qty].to_f rescue 0 + product = current_site.products.find(data[:product_id]).decorate + unless product.can_added?(qty) + flash[:error] = t('plugins.ecommerce.messages.not_enough_product_qty', product: product.the_title, qty: product.the_qty_real, default: 'There is not enough products "%{product}" (%{qty})') + return redirect_to :back + end + @cart.add_product(product, qty) + flash[:notice] = t('plugins.ecommerce.messages.added_product_in_cart', default: 'Product added into cart') redirect_to action: :cart_index end def cart_update + errors = [] params[:products].each do |data| - product_id = data[:product_id] - @cart.set_option("product_#{product_id}", e_add_data_product(data, product_id)) + product = @cart.products.find(data[:product_id]).decorate + qty = data[:qty].to_f + if product.can_added?(qty) + @cart.add_product(product, qty) + else + errors << t('plugins.ecommerce.messages.not_enough_product_qty', product: product.the_title, qty: product.the_qty_real, default: 'There is not enough products "%{product}" (%{qty})') + end end - flash[:notice] = "Updated product in Cart." + flash[:error] = errors.join('<br>') if errors.present? + flash[:notice] = t('plugins.ecommerce.messages.cart_updated', default: 'Shopping cart updated') unless errors.present? redirect_to action: :cart_index end def cart_remove @cart.remove_product(params[:product_id]) - @cart.delete_option("product_#{params[:product_id]}") - flash[:notice] = "Deleted product from the Cart." + flash[:notice] = t('plugins.ecommerce.messages.cart_deleted', default: 'Product removed from your shopping cart') redirect_to action: :cart_index end - def orders - render json: current_site.orders.set_user(current_user) + def cancel_order + # @cart = current_site.orders.find_by_slug(params[:order]) + @cart.update({status: 'canceled', kind: 'order', closed_at: Time.now}) + flash[:notice] = t('plugins.ecommerce.messages.canceled_order', default: "Canceled Order") + redirect_to plugins_ecommerce_orders_url end - private - def set_cart - if signin? - @cart = current_site.carts.set_user(current_user).first_or_create(name: "Cart by #{current_user.id}") + # pay by stripe + def pay_by_stripe + require 'stripe' + Stripe.api_key = @payment.options[:stripe_id] + customer = Stripe::Customer.create(:email => params[:stripeEmail], :source => params[:stripeToken]) + begin + charge = Stripe::Charge.create( + :customer => customer.id, + :amount => commerce_to_cents(@cart.total_amount), + :description => "Payment Products: #{@cart.products_title}", + :currency => commerce_current_currency + ) + @cart.set_meta("payment_data", params) + mark_order_like_received(@cart) + redirect_to plugins_ecommerce_orders_url + rescue Stripe::CardError => e + flash[:error] = e.message + flash[:payment_error] = true + redirect_to :back + rescue => e + flash[:error] = e.message + redirect_to :back + end + end + + def pay_by_bank_transfer + @cart.set_meta("payment_data", params[:details]) + mark_order_like_received(@cart, 'bank_pending') + redirect_to plugins_ecommerce_orders_url + end + + def pay_by_authorize_net + res = payment_pay_by_credit_card_authorize_net(@cart, @payment) + if res[:error].present? + flash[:error] = res[:error] + flash[:payment_error] = true + redirect_to :back else - cookies[:return_to] = request.referer - redirect_to cama_admin_login_path + mark_order_like_received(@cart) + redirect_to plugins_ecommerce_orders_url end end + def success_paypal + # @cart = current_site.carts.find_by_slug(params[:order]) + @cart.set_meta('payment_data', {token: params[:token], PayerID: params[:PayerID]}) + mark_order_like_received(@cart) + redirect_to plugins_ecommerce_orders_url + end - def process_pay(data = {}) + def cancel_paypal + # @cart = current_site.orders.find_by_slug(params[:order]) + redirect_to plugins_ecommerce_orders_url + end + def pay_by_paypal + billing_address = @cart.get_meta("billing_address") + ActiveMerchant::Billing::Base.mode = @payment.options[:paypal_sandbox].to_s.to_bool ? :test : :production + paypal_options = { + :login => @payment.options[:paypal_login], + :password => @payment.options[:paypal_password], + :signature => @payment.options[:paypal_signature] + } + @gateway = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) + @options = { + brand_name: current_site.name, + items: [{number: @cart.slug, name: "Buy Products from #{current_site.the_title}: #{@cart.products_title}", amount: commerce_to_cents(@cart.total_amount)}], + :order_id => @cart.slug, + :currency => current_site.currency_code, + :email => @cart.user.email, + :billing_address => {:name => "#{billing_address[:first_name]} #{billing_address[:last_name]}", + :address1 => billing_address[:address1], + :address2 => billing_address[:address2], + :city => billing_address[:city], + :state => billing_address[:state], + :country => billing_address[:country], + :zip => billing_address[:zip] + }, + :description => "Buy Products from #{current_site.the_title}: #{@cart.total_amount}", + :ip => request.remote_ip, + :return_url => plugins_ecommerce_checkout_success_paypal_url(order: @cart.slug), + :cancel_return_url => plugins_ecommerce_checkout_cancel_paypal_url(order: @cart.slug) + } + response = @gateway.setup_purchase(commerce_to_cents(@cart.total_amount), @options) + redirect_to @gateway.redirect_url_for(response.token) + end + private + def set_cart + @cart = current_site.carts.set_user(current_user).first_or_create(name: "Cart by #{current_user.id}").decorate end + def commerce_to_cents(money) + (money*100).round + end + def set_bread + @ecommerce_bredcrumb << [t('plugins.ecommerce.messages.checkout', default: 'Checkout'), url_for(action: :cart_index)] + end + + def set_payment + @payment = current_site.payment_methods.actives.where(id: params[:payment][:payment_id]).first + @cart.update_column(:payment_method_id, @payment.id) + end end