Approval Process feature integration
Edit on GitHubInstall Feature Core
Prerequisites
To start feature integration, review and install the necessary features:
Name | Version |
---|---|
Company Account | 201907.0 |
Shared Carts | 201907.0 |
Checkout | 201907.0 |
Spryker Core | 201907.0 |
1) Install the required modules using Composer
Run the following command to install the required modules:
composer require spryker-feature/approval-process:"^201907.0" --update-with-dependencies
Module | Expected Directory |
---|---|
`QuoteApproval` | `vendor/spryker/quote-approval` |
2) Set up Database Schema and Transfer Objects
Run the following commands to apply database changes and generate entity and transfer changes:
console transfer:generate
console propel:install
console transfer:generate
Database Entity | Type | Event |
---|---|---|
`spy_quote_approval` | table | created |
Transfer | Type | Event | Path |
---|---|---|---|
`QuoteTransfer.quoteApprovals` | column | created | `src/Generated/Shared/Transfer/QuoteTransfer` |
`QuoteActivationRequestTransfer` | class | created | `src/Generated/Shared/Transfer/QuoteApprovalTransfer` |
`QuoteApprovalRequestTransfer` | class | created | `src/Generated/Shared/Transfer/QuoteApprovalRequestTransfer` |
`QuoteApprovalResponseTransfer` | class | created | `src/Generated/Shared/Transfer/QuoteApprovalResponseTransfer` |
`QuoteApprovalCollectionTransfer` | class | created | `src/Generated/Shared/Transfer/QuoteApprovalResponseTransfer` |
3) Add Translations
Append glossary for the approval process feature:
src/data/import/glossary.csv
quote_approval.request.send,Send Request,en_US
quote_approval.request.send,Anfrage Senden,de_DE
quote_approval.remove,Cancel Request,en_US
quote_approval.remove,Anfrage Abbrechen,de_DE
quote_approval.cart.require_approval,"You can't place this order because of your purchasing limit, please send your cart for approval or contact your manager.",en_US
quote_approval.cart.require_approval,"Sie können diese Bestellung aufgrund Ihres Einkaufslimits nicht aufgeben. Senden Sie Ihren Einkaufswagen zur Genehmigung oder wenden Sie sich an Ihren Kontakmanager.",de_DE
quote_approval.create.approver_cant_approve_quote,"Selected approver cannot approve your request due to approver limit.",en_US
quote_approval.create.approver_cant_approve_quote,"Der ausgewählte Manager kann Ihre Anfrage aufgrund des Genehmigungslimits nicht genehmigen.",de_DE
quote_approval.create.you_cant_approve_quote,"You can't approve or decline this cart because it's amount higher that your Approver limit.",en_US
quote_approval.create.you_cant_approve_quote,"Sie können diesen Einkaufswagen nicht genehmigen oder ablehnen, weil dessen Betrag höher als ihr Genehmigungslimit ist.",de_DE
quote_approval.create.quote_already_approved,"This Cart was already approved.",en_US
quote_approval.create.quote_already_approved,"Dieser Einkaufswagen wurde schon zur Genehmigung gesendet.",de_DE
quote_approval.create.quote_already_declined,"This Cart was already declined.",en_US
quote_approval.create.quote_already_declined,"Dieser Einkaufswagen wurde schon abgelehnt.",de_DE
quote_approval.create.quote_already_cancelled,"You can't work with this Cart it was already sent to another approver.",en_US
quote_approval.create.quote_already_cancelled,"Sie können nicht mit diesem Einkaufswagen arbeiten, er wurde schon dem anderen Manager gesendet.",de_DE
quote_approval.create.quote_already_waiting_for_approval,"This Cart was already sent for approval.",en_US
quote_approval.create.quote_already_waiting_for_approval,"",de_DE
quote_approval.create.only_quote_owner_can_send_request,"You can't sent Cart for Approval, only Cart owner can do it.",en_US
quote_approval.create.only_quote_owner_can_send_request,"Sie können den Einkaufswagen zur Genehmigung nicht senden, das kann nur Inhaber des Einkaufswagens machen.",de_DE
quote_approval.cancel.do_not_have_permission,"You don't have permissions to cancel Approval request.",en_US
quote_approval.cancel.do_not_have_permission,"Sie haben nicht die notwendigen Rechte um die Genehmigungsanfrage zu abbrechen.",de_DE
quote_approval.request.approval_by,by,en_US
quote_approval.request.approval_by,von,de_DE
quote_approval.created,"Your request for Approval was send to %first_name% %last_name%".,en_US
quote_approval.created,"Ihre Anfrage zur Genehmigung wurde an %first_name% %last_name% gesendet.",de_DE
quote_approval.removed,"Your request for Approval was canceled.",en_US
quote_approval.removed,"Ihre Genehmigungsanfrage wurde abgebrochen.",de_DE
quote_approval.request.waiting_for_approval_from,Waiting for Approval from,en_US
quote_approval.request.waiting_for_approval_from,Wartet auf die Genehmigung von,de_DE
quote_approval.request.approved_by,Approved by,en_US
quote_approval.request.approved_by,Genehmigt von,de_DE
quote_approval.request.declined_by,Declined by,en_US
quote_approval.request.declined_by,Abgelehnt um,de_DE
To import the glossary data, run the following console command:
console data:import glossary
Make sure that the configured data has been added to the spy_glossary
table in the database.
4) Set up Behavior
Set up Permission Integration
To set up the permission integration, register the following plugins:
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
ApproveQuotePermissionPlugin |
Permission check that verifies if the customer can approve quote approval in the client layer. | None | Spryker\Client\QuoteApproval\Plugin\Permission |
PlaceOrderPermissionPlugin |
Permission check that verifies if the customer can place an order in the client layer. | None | Spryker\Client\QuoteApproval\Plugin\Permission |
RequestQuoteApprovalPermissionPlugin |
Permission check that verifies if the customer can request for approval in the client layer. | None | Spryker\Client\QuoteApproval\Plugin\Permission |
ApproveQuotePermissionPlugin |
Permission check that verifies if the customer can approve the quote approval in the Zed layer. | None | Spryker\Zed\QuoteApproval\Communication\Plugin\Permission |
PlaceOrderPermissionPlugin |
Permission check that verifies if the customer can place an order in the Zed layer. | None | Spryker\Zed\QuoteApproval\Communication\Plugin\Permission |
SanitizeQuoteApprovalQuoteLockPreResetPlugin |
Allows removing completely all the approval process-related data from the quote on the cart lock reset. | None | Spryker\Zed\QuoteApproval\Communication\Plugin\Cart |
src/Pyz/Client/Permission/PermissionDependencyProvider.php
<?php
namespace Pyz\Client\Permission;
use Spryker\Client\Permission\PermissionDependencyProvider as SprykerPermissionDependencyProvider;
use Spryker\Client\QuoteApproval\Plugin\Permission\ApproveQuotePermissionPlugin;
use Spryker\Client\QuoteApproval\Plugin\Permission\PlaceOrderPermissionPlugin;
use Spryker\Client\QuoteApproval\Plugin\Permission\RequestQuoteApprovalPermissionPlugin;
class PermissionDependencyProvider extends SprykerPermissionDependencyProvider
{
/**
* @return \Spryker\Shared\PermissionExtension\Dependency\Plugin\PermissionPluginInterface[]
*/
protected function getPermissionPlugins(): array
{
return [
new RequestQuoteApprovalPermissionPlugin(),
new PlaceOrderPermissionPlugin(),
new ApproveQuotePermissionPlugin(),
];
}
}
src/Pyz/Zed/Permission/PermissionDependencyProvider.php
<?php
namespace Pyz\Zed\Permission;
use Spryker\Zed\Permission\PermissionDependencyProvider as SprykerPermissionDependencyProvider;
use Spryker\Zed\QuoteApproval\Communication\Plugin\Permission\ApproveQuotePermissionPlugin;
use Spryker\Zed\QuoteApproval\Communication\Plugin\Permission\PlaceOrderPermissionPlugin;
class PermissionDependencyProvider extends SprykerPermissionDependencyProvider
{
/**
* @return \Spryker\Shared\PermissionExtension\Dependency\Plugin\PermissionPluginInterface[]
*/
protected function getPermissionPlugins()
{
return [
new PlaceOrderPermissionPlugin(),
new ApproveQuotePermissionPlugin(),
];
}
}
Pyz\Zed\Cart\CartDependencyProvider.php
<?php
namespace Pyz\Zed\Cart;
use Spryker\Zed\Cart\CartDependencyProvider as SprykerCartDependencyProvider;
use Spryker\Zed\QuoteApproval\Communication\Plugin\Cart\SanitizeQuoteApprovalPreQuoteUnlockPlugin;
class CartDependencyProvider extends SprykerCartDependencyProvider
{
/**
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\QuotePreUnlockPluginInterface[]
*/
protected function getQuotePreUnlockPlugins(): array
{
return [
new SanitizeQuoteApprovalPreQuoteUnlockPlugin(),
];
}
}
- When the customer permission is `RequestQuoteApprovalPermission`, then this customer can *request for approval*.
- When the customer permission is `ApproveQuotePermission`, then this customer can approve the *request for approval*.
- When the customer permission is `PlaceOrderPermissionPlugin`, then this customer can place order from quote with the approved *request for approval*.
- When you reset the cart lock, all the approval process-related data is removed from the quote.
Set up Quote Integration
To set up the quote integration, register the following plugins:
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
QuoteApprovalExpanderPlugin |
Expands quote with the QuoteApproval data. |
None | Spryker\Zed\QuoteApproval\Communication\Plugin\Quote |
RemoveQuoteApprovalsBeforeQuoteDeletePlugin |
Removes quote approvals from database before quote deletion. | None | Spryker\Zed\QuoteApproval\Communication\Plugin\Quote |
src/Pyz/Zed/Quote/QuoteDependencyProvider.php
<?php
namespace Pyz\Zed\Quote;
use Spryker\Zed\Quote\QuoteDependencyProvider as SprykerQuoteDependencyProvider;
use Spryker\Zed\QuoteApproval\Communication\Plugin\Quote\QuoteApprovalExpanderPlugin;
use Spryker\Zed\QuoteApproval\Communication\Plugin\Quote\RemoveQuoteApprovalsBeforeQuoteDeletePlugin;
class QuoteDependencyProvider extends SprykerQuoteDependencyProvider
{
/**
* @return \Spryker\Zed\QuoteExtension\Dependency\Plugin\QuoteWritePluginInterface[]
*/
protected function getQuoteDeleteBeforePlugins(): array
{
return [
new RemoveQuoteApprovalsBeforeQuoteDeletePlugin(),
];
}
/**
* @return \Spryker\Zed\QuoteExtension\Dependency\Plugin\QuoteExpanderPluginInterface[]
*/
protected function getQuoteExpanderPlugins(): array
{
return [
new QuoteApprovalExpanderPlugin(),
];
}
}
- On quote loading, the quote is expanded with data from `table spy_quote_approval` database table.
- Before quote deletion, the records from `spy_quote_approval` database table related to quote will be removed.
Set up Checkout Integration
To set up the checkout integration, register the following plugin:
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
QuoteApprovalCheckoutPreCheckPlugin |
Verifies that quote applicable for checkout if any of these conditions are met:
|
None | Spryker\Client\QuoteApproval\Plugin\Checkout |
src/Pyz/Client/Checkout/CheckoutDependencyProvider.php
<?php
namespace Pyz\Client\Checkout;
use Spryker\Client\Checkout\CheckoutDependencyProvider as SprykerCheckoutDependencyProvider;
use Spryker\Client\QuoteApproval\Plugin\Checkout\QuoteApprovalCheckoutPreCheckPlugin;
class CheckoutDependencyProvider extends SprykerCheckoutDependencyProvider
{
/**
* @return \Spryker\Client\CheckoutExtension\Dependency\Plugin\CheckoutPreCheckPluginInterface[]
*/
protected function getCheckoutPreCheckPlugins(): array
{
return [
new QuoteApprovalCheckoutPreCheckPlugin(),
];
}
}
Install feature frontend
Prerequisites
To start feature integration, review and install the necessary features:
Name | Version |
---|---|
Cart | 201907.0 |
Checkout | 201907.0 |
Spryker Core | 201907.0 |
1) Install the required modules using Composer
Run the following command to install the required modules:
composer require spryker-feature/approval-process: "^201907.0" --update-with-dependencies
Module | Expected Directory |
---|---|
`QuoteApprovalWidget` | `vendor/spryker-shop/quote-approval-widget` |
2) Add Translations
Append glossary according to your configuration:
src/data/import/glossary.csv
quote_approval_widget.title,Approval Request,en_US
quote_approval_widget.title,Genehmigungsanfrage,de_DE
quote_approval_widget.limit.unlimited,Unlimited,en_US
quote_approval_widget.limit.unlimited,Unbegrenzt,de_DE
quote_approval_widget.no_approvers_found,Keine Genehmiger gefunden.,de_DE
quote_approval_widget.no_approvers_found,No approvers found.,en_US
quote_approval_widget.cart.status.approved,"Approved",en_US
quote_approval_widget.cart.status.approved,"Genehmigt",de_DE
quote_approval_widget.cart.status.declined,"Declined",en_US
quote_approval_widget.cart.status.declined,"Abgelehnt",de_DE
quote_approval_widget.cart.status.waiting,"Waiting",en_US
quote_approval_widget.cart.status.waiting,"Wartet",de_DE
quote_approval_widget.shared_cart_warning,"After a cart has been sent to approval, all of its shares will be dismissed.",en_US
quote_approval_widget.shared_cart_warning,"Nachdem der Warenkorb zur Genehmigung gesendet wurde, wird sein Sharing aufgehoben.",de_DE
quote_approval_widget.limit_text,"Your purchase limit is %amount%. To spend more, request approval from your manager.",en_US
quote_approval_widget.limit_text,"Ihr Einkaufsrahmen liegt bei %amount%. Um mehr auszugeben, fordern Sie bitte die Genehmigung bei Ihrem Manager an",de_DE
quote_approval_widget.no_limit_text,"You do not have a purchase limit",en_US
quote_approval_widget.no_limit_text,"Sie haben kein Einkaufslimit",de_DE
quote_approval_widget.cart.status,"Status",en_US
quote_approval_widget.cart.status,"Status",de_DE
quote_approval_widget.cart.approve,"Approve",en_US
quote_approval_widget.cart.approve,"Genehmigen",de_DE
quote_approval_widget.cart.decline,"Decline",en_US
quote_approval_widget.cart.decline,"Ablehnen",de_DE
quote_approval_widget.cart.cancel,"Cancel",en_US
quote_approval_widget.cart.cancel,"Abbrechen",de_DE
quote_approval_widget.cart.success_message.approved,"Request from %first_name% %last_name% was successfully approved",en_US
quote_approval_widget.cart.success_message.approved,"Anfrage von %first_name% %last_name% wurde erfolgreich genehmigt",de_DE
quote_approval_widget.cart.success_message.declined,"Request from %first_name% %last_name% was successfully declined",en_US
quote_approval_widget.cart.success_message.declined,"Anfrage von %first_name% %last_name% wurde erfolgreich abgelehnt",de_DE
quote_approval_widget.cart.success_message.canceled,"Request from %first_name% %last_name% was successfully canceled",en_US
quote_approval_widget.cart.success_message.canceled,"Anfrage von %first_name% %last_name% wurde erfolgreich abgebrochen",de_DE
Run the following console command to import the glossary data:
console data:import glossary
Make sure that the configured data has been added to the spy_glossary
table in the database.
3) Set up Widgets
Register the following global widgets:
Widget | Description | Prerequisites | Namespace |
---|---|---|---|
QuoteApprovalStatusWidget |
Adds the quote approval status for a multi-cart list in the header and on the multi-cart list page. | None | SprykerShop\Yves\QuoteApprovalWidget\Widget |
QuoteApprovalWidget |
Adds an approve functionality to the Cart page. | None | SprykerShop\Yves\QuoteApprovalWidget\Widget |
QuoteApproveRequestWidget |
Adds the request for quote approve functionality to the Cart page. | None | SprykerShop\Yves\QuoteApprovalWidget\Widget |
src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php
<?php
namespace Pyz\Yves\ShopApplication;
use SprykerShop\Yves\QuoteApprovalWidget\Widget\QuoteApprovalStatusWidget;
use SprykerShop\Yves\QuoteApprovalWidget\Widget\QuoteApprovalWidget;
use SprykerShop\Yves\QuoteApprovalWidget\Widget\QuoteApproveRequestWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;
class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
/**
* @return string[]
*/
protected function getGlobalWidgets(): array
{
return [
QuoteApprovalStatusWidget::class,
QuoteApproveRequestWidget::class,
QuoteApprovalWidget::class,
];
}
}
Run the following command to enable the Javascript and CSS changes:
console frontend:yves:build
1. Open Yves and log in with the customer credentials.
2. Open `http://mysprykershop.com/company/company-role` and assign the following permission to any role related to the current customer:
- `RequestQuoteApprovalPermission`
- `PlaceOrderPermission`
- `ApproveQuotePermission`
3. Add the record to `spy_quote_approval` table with a current customer quote id and current customer company user as an approver.
Module | Test |
---|---|
`QuoteApprovalStatusWidget` | Hover over the multicart list in the header. It should contain a Quote Approval Status column.Open `http://mysprykershop.com/multi-cart/`: table should contain the Quote Approval Status column. |
`QuoteApproveRequestWidget` | Open `https://mysprykershop.com/cart/`. It should contain widget request for approval with a list approvers. |
`QuoteApprovalWidget` | Open `http://mysprykershop.com/cart/`. It should contain the widget approver functionality with buttons to Approve or Decline. |
4) Enable Controllers
To enable the controllers, register the following plugin:
Widget | Description | Prerequisites | Namespace |
---|---|---|---|
QuoteApprovalControllerProvider |
Provides routes used in QuoteApprovalWidget . |
None | SprykerShop\Yves\QuoteApprovalWidget\Plugin\Provider |
src/Pyz/Yves/ShopApplication/YvesBootstrap.php
<?php
namespace Pyz\Yves\ShopApplication;
use SprykerShop\Yves\QuoteApprovalWidget\Plugin\Provider\QuoteApprovalControllerProvider;
use SprykerShop\Yves\ShopApplication\YvesBootstrap as SprykerYvesBootstrap;
class YvesBootstrap extends SprykerYvesBootstrap
{
/**
* @param bool|null $isSsl
*
* @return \SprykerShop\Yves\ShopApplication\Plugin\Provider\AbstractYvesControllerProvider[]
*/
protected function getControllerProviderStack($isSsl)
{
return [
new QuoteApprovalControllerProvider($isSsl), #SharedCartFeature
];
}
}
1. Open Yves and log in with the customer credentials.
2. Open `http://mysprykershop.com/company/company-role/` and assign the following permission to any role related to the current customer:
- `RequestQuoteApprovalPermission`
- `PlaceOrderPermission`
- `ApproveQuotePermission`
3. Add the record to `spy_quote_approval` database table with a current customer quote id and current customer company user as an approver.
4. Open `http://mysprykershop.com/cart/` and click **Approve**. A Quote approval status should become approved and the **Proceed to Checkout** icon must be shown.
5. Create a new quote with items.
6. Open `http://mysprykershop.com/cart/` and click **Request for Approval**. A Quote approval status should become *Waiting*, and the *Approver* functionality must be shown.
Thank you!
For submitting the form