Option to Add a variable Tip
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
Option to Add a variable Tip
In light of Covid 19 delivery risks, restaurant delivery personnel want to present customers with the OPTION of adding a variable tip to the order - similar to that now seen in many cafe's using tablets and touch screen point of sale devices.
After completing product selection and during final checkout the customer would be presented with the option:
-------------------------
Leave a tip?
o 20%
o 15%
o 10%
o No Tip
--------------------------
OR
--------------------------
Leave a tip?
[ 12 ] % (using a form field - any value customer enters)
--------------------------
Selection of a tip would add that percentage to the order total before tax and shipping.
Is there a way to configure this in the standard product through a service or other method?
After completing product selection and during final checkout the customer would be presented with the option:
-------------------------
Leave a tip?
o 20%
o 15%
o 10%
o No Tip
--------------------------
OR
--------------------------
Leave a tip?
[ 12 ] % (using a form field - any value customer enters)
--------------------------
Selection of a tip would add that percentage to the order total before tax and shipping.
Is there a way to configure this in the standard product through a service or other method?
Re: Option to Add a variable Tip
There are two options:
1.) You can add a product attribute with code "custom" and type "price" to each product so customers can chose the amount of the tip themselves in the product detail view
2.) You write a service decorator that adds the list of possible values to the delivery or payment option and add the calculated tip on top of the price of that option. Your implementation would be a combination of those two decorators:
- For the list of options: https://github.com/aimeos/aimeos-core/b ... pplier.php
- For adding the tip: https://github.com/aimeos/aimeos-core/b ... /Costs.php
1.) You can add a product attribute with code "custom" and type "price" to each product so customers can chose the amount of the tip themselves in the product detail view
2.) You write a service decorator that adds the list of possible values to the delivery or payment option and add the calculated tip on top of the price of that option. Your implementation would be a combination of those two decorators:
- For the list of options: https://github.com/aimeos/aimeos-core/b ... pplier.php
- For adding the tip: https://github.com/aimeos/aimeos-core/b ... /Costs.php
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star
Re: Option to Add a variable Tip
Thanks - I'm at a loss as to how to pass the array of tip values to the decorator and how to get the html to show up in the cart.
Attached is what I have so far but I'm especially struggling with how to modify a copy of the second decorator example (Supplier.php).
From copy of the costs.php decorator:
From copy of supplier.php
And here's an example of what we want to achieve (From woocommerce)
Attached is what I have so far but I'm especially struggling with how to modify a copy of the second decorator example (Supplier.php).
From copy of the costs.php decorator:
Code: Select all
<?php
/**
* @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
* @copyright Metaways Infosystems GmbH, 2013
* @copyright Aimeos (aimeos.org), 2015-2018
* @package MShop
* @subpackage Service
*/
namespace Aimeos\MShop\Service\Provider\Decorator;
/**
* Decorator for service providers adding additional costs.
*
* @package MShop
* @subpackage Service
*/
class Tip
extends \Aimeos\MShop\Service\Provider\Decorator\Base
implements \Aimeos\MShop\Service\Provider\Decorator\Iface
{
private $beConfig = array(
'costs.percent' => array(
'code' => 'tip.percent',
'internalcode' => 'tip.percent',
'label' => 'Costs: Decimal percent value',
'type' => 'number',
'internaltype' => 'float',
'default' => 0,
'required' => true,
),
);
/**
* Checks the backend configuration attributes for validity.
*
* @param array $attributes Attributes added by the shop owner in the administraton interface
* @return array An array with the attribute keys as key and an error message as values for all attributes that are
* known by the provider but aren't valid
*/
public function checkConfigBE( array $attributes )
{
$error = $this->getProvider()->checkConfigBE( $attributes );
$error += $this->checkConfig( $this->beConfig, $attributes );
return $error;
}
/**
* Returns the configuration attribute definitions of the provider to generate a list of available fields and
* rules for the value of each field in the administration interface.
*
* @return array List of attribute definitions implementing \Aimeos\MW\Common\Critera\Attribute\Iface
*/
public function getConfigBE()
{
return array_merge( $this->getProvider()->getConfigBE(), $this->getConfigItems( $this->beConfig ) );
}
/**
* Returns the tip amount when using the provider.
* This is calculated based on
* the basket content, e.g. 10% of the value as transaction cost.
*
* @param \Aimeos\MShop\Order\Item\Base\Iface $basket Basket object
* @return \Aimeos\MShop\Price\Item\Iface Price item containing the price, shipping, rebate
*/
public function calcPrice( \Aimeos\MShop\Order\Item\Base\Iface $basket )
{
$config = $this->getServiceItem()->getConfig();
if( !isset( $config['tip.percent'] ) ) {
throw new \Aimeos\MShop\Service\Exception( sprintf( 'Missing configuration "%1$s"', 'tip.percent' ) );
}
$value = $basket->getPrice()->getValue() * $config['tip.percent'] / 100;
$price = $this->getProvider()->calcPrice( $basket );
$price->setCosts( $price->getCosts() + $value );
return $price;
}
}
Code: Select all
<?php
/**
* @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
* @copyright Aimeos (aimeos.org), 2017-2018
* @package MShop
* @subpackage Service
*/
namespace Aimeos\MShop\Service\Provider\Decorator;
/**
* Supplier tip decorator for service providers
* @package MShop
* @subpackage Service
*/
class TipOptions
extends \Aimeos\MShop\Service\Provider\Decorator\Base
implements \Aimeos\MShop\Service\Provider\Decorator\Iface
{
private $feConfig = array(
'tip.code' => array(
'code' => 'tip.code',
'internalcode' => 'tip.percent',
'label' => 'Tip Amount',
'type' => 'list',
'internaltype' => 'array',
'default' => [0=>'No Tip'],
'required' => true
),
);
/* public $tips=array(
array('tip.code' => 0, 'label' =>'No Tip'),
array('tip.code' => 10, 'label' =>'5% Tip'),
array('tip.code' => 15, 'label' =>'10% Tip'),
array('tip.code' => 20, 'label' =>'15% Tip')
); */
private $beConfig = array(
'tip.display-code' => array(
'code' => 'tip.display-code',
'internalcode' => 'tip.percent',
'label' => 'Display tip code in summary and email',
'type' => 'integer',
'internaltype' => 'integer',
'default' => 0,
'required' => false,
),
);
/**
* Initializes a new service provider object using the given context object.
*
* @param \Aimeos\MShop\Service\Provider\Iface $provider Service provider or decorator
* @param \Aimeos\MShop\Context\Item\Iface $context Context object with required objects
* @param \Aimeos\MShop\Service\Item\Iface $serviceItem Service item with configuration for the provider
*/
public function __construct( \Aimeos\MShop\Service\Provider\Iface $provider,
\Aimeos\MShop\Context\Item\Iface $context, \Aimeos\MShop\Service\Item\Iface $serviceItem )
{
parent::__construct( $provider, $context, $serviceItem );
$manager = \Aimeos\MShop::create( $context, 'supplier' );
$tipManager = \Aimeos\MShop::create( $context, 'supplier/tip' );
$search = $manager->createSearch( true );
$search->setSortations( [$search->sort( '+', 'tip.percent' )] );
foreach( $manager->searchItems( $search, ['supplier/tip'] ) as $item )
{
$tips = array(0 =>'No Tip', 10 => '10% Tip', 15 =>'10% Tip', 20 =>'10% Tip');
if( empty( $tips ) ) {
$tips[] = $tipManager->createItem();
}
foreach( $tips as $id => $tip )
{
$tipId = ( count( $tips ) > 1) ? $item->getCode() . '-' . $id : $item->getCode();
$this->feConfig['tip.code']['default'][$tipId] = preg_replace( "/\n+/m", "\n", sprintf(
/// Tip Format with label (%1$s)
$context->getI18n()->dt( 'mshop', '%1$s'),
$tip->getTip()
) );
$this->feConfig['tip.code']['short'][$tipId] = preg_replace( "/\n+/m", "\n", sprintf(
$context->getI18n()->dt( 'mshop', '%1$s'),
$tip->getTip()
) );
}
}
}
/**
* Checks the frontend configuration attributes for validity.
*
* @param array $attributes Attributes entered by the customer during the checkout process
* @return array An array with the attribute keys as key and an error message as values for all attributes that are
* known by the provider but aren't valid resp. null for attributes whose values are OK
*/
public function checkConfigFE( array $attributes )
{
$result = $this->getProvider()->checkConfigFE( $attributes );
return array_merge( $result, $this->checkConfig( $this->feConfig, $attributes ) );
}
/**
* Returns the configuration attribute definitions of the provider to generate a list of available fields and
* rules for the value of each field in the frontend.
*
* @param \Aimeos\MShop\Order\Item\Base\Iface $basket Basket object
* @return array List of attribute definitions implementing \Aimeos\MW\Common\Critera\Attribute\Iface
*/
public function getConfigFE( \Aimeos\MShop\Order\Item\Base\Iface $basket )
{
$feconfig = $this->feConfig;
try
{
$type = \Aimeos\MShop\Order\Item\Base\Service\Base::TYPE_DELIVERY;
$service = $this->getBasketService( $basket, $type, $this->getServiceItem()->getCode() );
if( ( $value = $service->getAttribute( 'tip.code', 'delivery' ) ) != ''
&& isset( $feconfig['tip.code']['default'][$value] )
) {
// move to first position so it's selected
$tip = $feconfig['tip.code']['default'][$value];
unset( $feconfig['tip.code']['default'][$value] );
$feconfig['tip.code']['default'] = [$value => $address] + $feconfig['tip.code']['default'];
}
}
catch( \Aimeos\MShop\Service\Exception $e ) {} // If service isn't available
return array_merge( $this->getProvider()->getConfigFE( $basket ), $this->getConfigItems( $feconfig ) );
}
/**
* Sets the Payment attributes in the given service.
*
* @param \Aimeos\MShop\Order\Item\Base\Service\Iface $orderServiceItem Order service item that will be added to the basket
* @param array $attributes Attribute key/value pairs entered by the customer during the checkout process
* @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order service item with attributes added
*/
public function setConfigFE( \Aimeos\MShop\Order\Item\Base\Service\Iface $orderServiceItem, array $attributes )
{
if( ( $code = $attributes['tip.code'] ) != '' )
{
// add short address as attribute for summary page / customer email
$attributes['tip.percent'] = $this->feConfig['tip.code']['short'][$code];
// remove code attribute for summary page / customer email
if( $this->getConfigValue('tip.display-code') == 0 ) {
unset( $attributes['tip.code'] );
}
}
return $this->getProvider()->setConfigFE( $orderServiceItem, $attributes );
}
}
And here's an example of what we want to achieve (From woocommerce)
- Attachments
-
- example.-tips.jpg (35.94 KiB) Viewed 1441 times
Re: Option to Add a variable Tip
You need to do this in one decorator, not in two.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star