2016/10/29

How to pay with Paypal in Magento from the Admin Panel?

If you or your sales team creates orders for your customers over the Magento adminpanel sometimes, you might came to this issue: You cannot select Paypal in the Backend order.

This seems logical if you think about the Paypal payment process: after the checkout you are redirected to the Paypal website for the purchase. This is not possible in a situation, where you are creating an order for a customer, because you do not have his password (e.g. if you talk with the customer on the phone or in person in your local store). This is a general issue for all payment options like Paypal like Sofort.com, Klarna, Billsafe and so on.

But with a little workaround, you can easily let your customers pay with Paypal while you are ordering for him in the Magento Backend.

The solution

We are adding a Backend Payment method which is called "Paypal" with no further program logic. This ensures, the order and invoice information shows the correct payment method.

BackendPayment provides payment methods like cash, debit and Paypal
After we created the order, we go to our the official Paypal website and use the "Request money" function. This allows you to enter the Paypal Email address of your customer and the amount of the order to request the money over Paypal.

For the developers 

It is easy to provide a new payment method which is only available in the admin panel and not on the customers checkout. Just create a new module with the default folders and configuration for at least models, blocks and helpers.

The first thing you need is a model which looks like the following (you have to change class names to your correct namespace):

/**
 * Grafzahl_BackendPayments
 *
 * @category    Grafzahl
 * @package     Grafzahl_BackendPayments
 * @copyright   Copyright (c) 2016 Grafzahl (https://grafzahl.io)
 * @license     https://grafzahl.io/license
 */

class Grafzahl_BackendPayments_Model_PaypalPayment
    extends Mage_Payment_Model_Method_Abstract
{
    protected $_code = 'backendpayments_paypal';
    protected $_infoBlockType = 'backendpayments/info';
    protected $_canUseInternal = true;
    protected $_canUseCheckout = false;
    protected $_canUseForMultishipping  = false;

    public function __construct()
    {
        parent::__construct();
    }
}

The second thing is to create the related block from the model in the attribute $_infoBlockType. The block just needs to extend the block Mage_Payment_Block_Info. Now check the extending block and update the methods to your needs.

Complete ready to use solution

Such a payment method, mentioned above is already available. You can download BackendPayments from our grafzahl.io store and install it in your Magento store from version 1.7.x - 1.9.x with no pain.

This will provide you three new payment methods in your admin panel order form: Paypal, Debit and Cash. You can even use any other payment provider instead of Paypal. The title can be edited in the system configuration.

With this module you can also create order with the method Cash payment and Debit Payment. If you have a little local store which you manage with a Magento Shop-System, you will be able to create orders with cash payment from your admin panel.

You can also configure if these methods should automatically create the invoice for you. For further information, check our documentation source.


2016/10/27

Why should you make your Magento Product Filter URL look sexy

Fist off - it is every URL´s right to look sexy and Magento supports readable URLs well.

But some areas are still a little bit abstract and not optimized for humans or the search engines.

Search engines like Google have very complex algorithms to rate a website. They already guess very good which content a user is searching for. Because they are rating the websites on how good they are optimized for human!

This is the reason why Magento´s default layered filter URLs are bad for humans and for SEO:
http://magento.local/men/shirts.html?color=27
Nobody knows that color=27 is blue - neither does Google (although we think Google knows everything)!
So if someone is searching for a Shirt in blue, your products won´t be in the index, because your Shirt is 27, and therefor not indexed as blue shirts ;). This may be the case for the product detail pages, where the product has it´s attributes, but here we talk about the category pages where the product collections are filtered.

To solve this problem we have created the SEO Filter URL module. It is easy to install and it works with almost no configuration.
At the end you will get URLs for your Magento  1.7, 1.8, 1.8.1, 1.9, 1.9.1, 1.9.2, 1.9.3 like:
 http://magento.local/men/shirts/filter/color/blue.html
 Also the price filter is translated. If you click filter "$140.00 and above", you will get:
http://magento1-9-3.local/men/shirts/filter/color/blue/price/from-140-and-above.html
in your browser´s address line.

For the developers among us:
It seamlessly integrates in the routing with an observer on the event controller_front_init_before. The links of the layered are change by overwriting the navigation model Mage_Catalog_Model_Layer_Filter_Item.
Also the page links of the catalog toolbar are change to get a readable "page" instead of "p=" for links in the pager.


2012/01/28

Authentifizierung mit Rails und Authlogic

Man braucht sie heutzutage in jeder Applikation: die Benutzeranmeldung. Darin liegt auch die erste Hürde. Ein Controller muss die Anmeldung übernehmen, und der ApplicationController muss dafür sorgen, dass angemeldete Nutzer bei jedem Request aus der Session geladen werden. In jedem Controller muss festgelegt werden, für welche Actions man angemeldet sein muss.

Ein Tool, welches die meisten benötigten Funktionen abdeckt und relativ leicht zu installieren ist, ist authlogic. (Schnellanleitung: https://github.com/binarylogic/authlogic_example/blob/master/README.rdoc)


Mögliche Fehler nach der Installation:

undefined method `valid_password?' for #...

Nachdem ich die Spalte crypted_password der Tabelle hinzugefügt hatte, war das Problem gelöst.
Authlogic benötigt mindestens drei Felder, die meist automatisch erkannt werden. Benutzername/Email, Passwort und Passwortbestätigung. In meinem Fall musste ich in meinem _form.html.erb das Feld für die Passwortbestätigung :passwort_confirmation nennen, damit es funktioniert hat.
Wenn man nun authlogic soweit installiert hat, lässt sich ein nicht authentifizierter Besucher ganz einfach mit dem Aufruf eines before_filters in dem Ziel-Controller aussperren:


class UsersController < ApplicationController
  before_filter :require_no_user, :only => [:new, :create]
  before_filter :require_user, :only => [:show, :edit, :update]
[...]

2012/01/17

Einbinden von Styles und Scripts


Nach der vierten Auflage von "Agile Web Development with Rails" - und damit vermutlich nach den Konventionen von Rails < 3.1 - gehören Stylesheets und Javascripts in den /public/stylesheets Ordner und wird mit folgendem Methodenaufruf in das Layout geladen:
<%= stylesheet_link_tag "application" %>

Der String-Parameter "application" gibt an, welche CSS geladen wird.
Leider verlinkt der ausgegebene Link-Tag nicht auf den Ordner /public sondern /assets
Nach einer schnellen Suche im Ruby on Rails Guide ist eine Funktion namens Asset Pipeline per default eingeschaltet: http://guides.rubyonrails.org/asset_pipeline.html
Diese Funktion erlaubt es, Javascript und CSS zu bündeln und zu komprimieren um die Applikation zu optimieren.
Ebenso interessant dieser Funktion ist in Kapitel 2 des obigen Links nachzulesen: Es ermöglicht dem Entwickler, beispielsweise CSS nur dann zu laden, wenn es auch wirklich gebraucht wird. Dies wird über Controller definiert.
Der Scaffold-Befehl wird automatisch für jeden Controller in /assets/stylesheets/ eine CSS Datei erstellen.
Wenn man aber nun statt application.css eine andere CSS-Datei einbinden möchte, trifft man auf folgenden Fehler: 
Sprockets::CircularDependencyError in Controllername::Actionname

Um diesen Fehler zu umgehen, muss man die application.css löschen.
Damit immer nur das nötigste geladen wird lässt sich nun mit
<%= stylesheet_link_tag params[:controller] %>

die jeweilige CSS zum aufgerufenen Controller laden. Diese werden, wie schon erwähnt, mit jedem Scaffold automatisch erstellt und mit dem Suffix .css.scss in /assets/stylesheets/ abgelegt. 
Auf anhieb hat dies bei mir nicht funktioniert, aber nach einem Neustart des Servers wurden dann nur die nötigen CSS-Dateien geladen.

2012/01/15

Selbstverweisende Objekte - Tree Models

Mit Rails ist es relativ einfach Objekte zu erstellen, die rekursiv auf sich selbst verweisen können. Die repräsentieren meistens einen Kategoriebaum oder auch Beziehungen zwischen User (z.B. die Follower bei Twitter).

Man braucht dazu ein Model mit einem Datenbankfeld, welches sein eigenes Parent-Objekt speichert.
Mit den Methoden belongs_to und has_many lassen sich solche Beziehungen dann folgendermaßen darstellen:

  belongs_to  :parent_object,
                     :foreign_key  => "parent",
                     :class_name => "Category"
  has_many   :children,
                     :foreign_key  => "parent",
                     :class_name => "Category",
                     :order  => "name ASC",
                     :dependent => :delete_all

Nun lässt sich ganz einfach mit einer Instanz der Klasse, dessen Kinder aufrufen:

@category.children

Ebenso ist es möglich das Parent-Objekt aufzurufen:

@category.parent_object


Definiert werden diese Methoden mit dem ersten Parameter der belongs_to und has_many Definitionen. Man kann diese also nach belieben benennen.

2012/01/07

Rails Internationalisierung, Übersetzungsfehler für Datumformate

Wenn man sich eine Übersetzung einrichtet und dabei auf einen Fehler wie unten trifft, liegt dies vermutlich daran, dass Rails ein Datum nicht übersetzen kann.

Sehr aussagekräftig ist die Fehlermeldung nicht, deshalb habe ich die Lösung erst mit Google gefunden.

Die Lösung ist einfach:
Ruby on Rails fehlen für die Übersetzung von Datumformaten die korrekten Einträge in der Übersetzungsdatei (in meinem Fall config/locales/de.yml). Damit diese Datei für deutsche Datumformate vollständg ist, sollte man auf fertige Vorlagen zurückgreifen: https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale

Die besagte Fehlermeldung:


undefined method `-' for "translation missing: de.date.order":String

2012/01/04

Fehler beim updaten der rails gems: coffee-rails

Wenn man versucht ein update der gems durchzuführen und dabei folgender Fehler auftritt:
Updating coffee-rails
ERROR:  While executing gem ... (NoMethodError)
    undefined method `call' for nil:NilClass
kann man ihn mit einem Update von den RubyGems wieder beheben. Auf der Umgebung lief Rails 3.1 und RubyGems 1.3.7. Nach dem Update auf RubyGems 1.8.13 lief das Update sauber durch.
# gem install rubygems-update
Falls danach beim Update Fehler - ähnlich wie diese - auftauchen sollten:
Invalid gemspec in [/usr/local/ruby/lib/ruby/gems/1.9.1/specifications/therubyracer-0.9.8.gemspec]: invalid date format in specification: "2011-10-07 00:00:00.000000000Z" Invalid gemspec in [/usr/local/ruby/lib/ruby/gems/1.9.1/specifications/json-1.6.1.gemspec]: invalid date format in specification: "2011-09-18 00:00:00.000000000Z" Invalid gemspec in [/usr/local/ruby/lib/ruby/gems/1.9.1/specifications/rack-cache-1.0.3.gemspec]: invalid date format in specification: "2011-08-27 00:00:00.000000000Z"
kann man diese folgendermaßen beheben.
  1. Die entsprechende Datei in der Fehlerausgabe in einem Editor öffnen.
  2. Die Zeile mit s.date = suchen
  3. Den Zeitwert 00:00:00.000000000Z löschen, sodass die Zeile so wie diese aussieht:  s.date = %q{2011-10-07}