Download the PHP package openbuildings/purchases without Composer
On this page you can find all versions of the php package openbuildings/purchases. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download openbuildings/purchases
More information about openbuildings/purchases
Files in openbuildings/purchases
Package purchases
Short Description Multi Store Purchases
License BSD-3-Clause
Homepage https://github.com/OpenBuildings/purchases
Informations about the package purchases
Purchases Module
This is a Kohana module that gives you out of the box functionality for multi-brand purchases (each purchase may have Items from different sellers, each handling their portion of products independently)
It has support for eMerchantPay and Paypal at the moment
Instalation
All the purchase models work out of the box. However to use it properly you need to configure the models you want to sell by implementing Sellable interface. E.g
You need to add the "Buyer" behavior for you user model. It adds current_purchase
and purchases
associations:
Purchase, Brand Purchase and Purchase Items
The basic structure of the purchase is one purchase, representing the user's view of what is happening, that has several Brand_Purchase objects, one for each brand, and each one of these has a "Purchase_Items" assigned to it.
Prices
This module heavily utilizes jam-monetary - all of its price related methods and fields are Jam_Price objects allowing you to safely conduct price calculations, so that currency conversions happen transparently. For more informations see: https://github.com/OpenBuildings/jam-monetary
__Purchase_Item flags__
Purchase item has important "flags"
- __is_payable__ - that means that this is an item that should be "payed for" by the buyer, and will be added to his total bill. This is needed as some items need to be visible (and calculated) only for the seller for example, but should not appear on the buyer's bill.
- __is_discount__ - this means that the purchase item's price should be negative value. This enforces a validation - discounted items can only have negative prices, whereas normal ones must always have positive prices.
Item Querying
You can query items of the Brand Purchase with the items()
method:
All of these types of queries can be used by items_count()
and total_price()
There is also "items_quantity" which sums the quantities of all the items, matched by the filters.
All of these methods can also be executed on Model_Purchase objects, giving you an aggregate of all the brand_purchases. For example:
There is a special method that is available only on the Model_Brand_Purchase object. total_price_ratio
- it will return what part of the whole purchase is the particular brand purchase (from 0 to 1). You can pass filters to it too so only certain purchase_items will be taken into account.
Price Freezing
Normally all prices for purchase items are derived dynamically, by calling ->price_for_purchase_item() method on the reference object (be that a product, a promotion etc.), calculated with the current monetary exchange rates. Once you call the freeze()
method on the purchase (and save it) both the exchange rates and the prices are set to the purchase disallowing any further modification of the purchase, even if the reference's price changes, the purchase item's prices will stay the same as in the moment of freezing.
If you want to modify the purchase after that, you'll have to unfreeze()
it. Also if you want to know the state of the purchase, there is isFrozen
flag.
Once the purchase has been frozen and saved, any change to the frozen fields / associations will be treated as validation errors.
Freezable traits
In order for that to work across all the models of the purchase, the clippings/freezable
package is used. It has useful traits for keeping some values or collections frozen.
That means that whenever the model is "frozen" then the field named "price" will be assigned the value of the method "price()".
And all the associations will be also "frozen". The associations themselves have to be Freezable (implement the FreezableInterface
) in order for this to work. And the price() method, as well as any other fields, have to take into account if the object is frozen. E.g.
Adding / Updating single items
You can add an item to the purchase with the add_item()
method. It would search all the purchase items in all the brand_items, If the same item is found elsewhere it would update its quantity, otherwise it would add it to the appropriate brand_item (or create that if none exist):
EMP Processor
To Use the emp processor you'll need a form on your page (you can use the included Model_Emp_Form). To supply the processor with the cc data.
in the controller:
The form is a simple Jam_Form inside your view:
EMP VBV Processor
This uses EMP credit card processor but with VBV/3DSecure utalizing authorize and execute methods
in the controller:
The form is a simple Jam_Form inside your view:
PayPal Processor
A PayPal transaction requires 3 steps - creating the transaction, authorizing it by the user through PayPal's interface, and executing the transaction onces its been authorized.
$processor->next_url()
is used to go to the PayPal authorization page.
Additional billing info
You could pass additional info to the payment processor as billing address / name, by using the billing association.
Refunds
Refunds are performed with special Model_Brand_Refund objects - each refund is specific to a brand purchase - if you do not set any custom items, then all of them will be refunded (the whole transaction) otherwise, you can add Model_Brand_Refund_Item objects for refunding specific items (partial refund).
Later you can retrieve the refunds from the brand purchase or issue multiple refunds
Extending payment
execute()
, authorize()
and refund()
methods on the payment model, trigger some events and save the model - respectively:
- model.before_execute
- model.after_execute
- model.before_authorize
- model.after_authorize
- model.before_refund
- model.after_refund
Before methods are executed before any payment operations. After - after the payment operation is complete (money is sent) and the models are saved. Here's how you can use it:
Refund events also send the Model_Brand_Refund object as the third argument.
Updating Items and Extending Updates
Both brand_purchase
and purchase
have an update_items method, which trigger the brand_purchase's event 'model.update_items'. This is used mainly by external modules that can hook into purchases and add / update purchase_items when that event is triggered. For example openbuildings/shipping module uses that to add / update shipping items.
For example we might have a behavior like this:
Extending filters
items()
, items_count()
and total_price()
use filters array as an argument. It has a special event model.filter_items wich you can use in your behaviors to add additional filters or extend existing ones.
Here's an example of how you can do that:
Running tests
Tests should be run with selenium running (on port 4444 local)
E.g.
xvfb-run java -jar vendor/claylo/selenium-server-standalone/selenium-server-standalone-2.*.jar
License
Copyright (c) 2012-2013, OpenBuildings Ltd. Developed by Ivan Kerin as part of clippings.com
Under BSD-3-Clause license, read LICENSE file.
All versions of purchases with dependencies
composer/installers Version *
openbuildings/jam Version ^0.6
openbuildings/jam-auth Version ^0.5.1
openbuildings/jam-monetary Version ^0.2
openbuildings/jam-locations Version ^0.2.1
clippings/freezable Version ^0.3
kohana/core Version ^3.3
kohana/database Version ^3.3.4
league/omnipay Version ^3.0.2
php-http/httplug Version ^2.0