Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions Model/Config/Source/CaptureTrigger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Taxcloud_Magento2
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @package Taxcloud_Magento2
* @author TaxCloud <service@taxcloud.net>
* @copyright 2021 The Federal Tax Authority, LLC d/b/a TaxCloud
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/

namespace Taxcloud\Magento2\Model\Config\Source;

use \Magento\Framework\Data\OptionSourceInterface;

class CaptureTrigger implements OptionSourceInterface
{
const ORDER_CREATION = 'order_creation';
const PAYMENT = 'payment';
const SHIPMENT = 'shipment';

/**
* @return array
*/
public function toOptionArray()
{
return [
['value' => self::ORDER_CREATION, 'label' => __('On order creation')],
['value' => self::PAYMENT, 'label' => __('On payment')],
['value' => self::SHIPMENT, 'label' => __('On shipment')],
];
}
}
78 changes: 76 additions & 2 deletions Observer/Sales/Complete.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,18 @@

use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer;
use Taxcloud\Magento2\Model\Config\Source\CaptureTrigger;

class Complete implements ObserverInterface
{
/** @var string Magento event: order placed */
const EVENT_ORDER_PLACE_AFTER = 'sales_order_place_after';

/** @var string Magento event: invoice paid */
const EVENT_INVOICE_PAY = 'sales_order_invoice_pay';

/** @var string Magento event: shipment saved */
const EVENT_SHIPMENT_SAVE_AFTER = 'sales_order_shipment_save_after';

/**
* Core store config
Expand Down Expand Up @@ -69,6 +78,17 @@ public function info()
}

/**
* Event names that correspond to each capture trigger option.
*/
private static $triggerToEvent = [
CaptureTrigger::ORDER_CREATION => self::EVENT_ORDER_PLACE_AFTER,
CaptureTrigger::PAYMENT => self::EVENT_INVOICE_PAY,
CaptureTrigger::SHIPMENT => self::EVENT_SHIPMENT_SAVE_AFTER,
];

/**
* Run only when the current event matches the configured "Capture in TaxCloud" setting.
*
* @param Observer $observer
*/
public function execute(
Expand All @@ -81,10 +101,64 @@ public function execute(
return;
}

$this->tclogger->info('Running Observer sales_order_place_after');
$eventName = $observer->getEvent()->getName();
$configuredTrigger = $this->scopeConfig->getValue(
'tax/taxcloud_settings/capture_trigger',
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
if ($configuredTrigger === null || $configuredTrigger === '') {
$configuredTrigger = CaptureTrigger::ORDER_CREATION;
}

$expectedEvent = isset(self::$triggerToEvent[$configuredTrigger])
? self::$triggerToEvent[$configuredTrigger]
: self::$triggerToEvent[CaptureTrigger::ORDER_CREATION];

if ($eventName !== $expectedEvent) {
return;
}

$this->tclogger->info('Running Observer ' . $eventName . ' (capture trigger: ' . $configuredTrigger . ')');

$order = $observer->getEvent()->getOrder();
$order = $this->getOrderFromObserver($observer, $eventName);
if (!$order) {
return;
}

$this->tcapi->authorizeCapture($order);
}

/**
* Get order from observer based on event. Returns null if we should skip (e.g. not first invoice/shipment).
*
* @param Observer $observer
* @param string $eventName
* @return \Magento\Sales\Model\Order|null
*/
private function getOrderFromObserver(Observer $observer, $eventName)
{
$event = $observer->getEvent();

if ($eventName === self::EVENT_ORDER_PLACE_AFTER) {
return $event->getOrder();
}

if ($eventName === self::EVENT_INVOICE_PAY) {
$order = $event->getInvoice()->getOrder();
if ($order->getInvoiceCollection()->getSize() > 1) {
return null;
}
return $order;
}

if ($eventName === self::EVENT_SHIPMENT_SAVE_AFTER) {
$order = $event->getShipment()->getOrder();
if ($order->getShipmentCollection()->getSize() > 1) {
return null;
}
return $order;
}

return null;
}
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Navigate to *Stores → Configuration* and then *Sales → Tax*.
* **Default TIC** - Enter the Taxability Information Code you would like to use for products where an explicit TIC has not been specified.
* **Shipping TIC** - Enter the Taxability Information Code you would like to use for shipping costs. Use `11010` if you charge only postage, and `11000` for shipping & handling.
* **Cache Lifetime** - Enter the amount of time in seconds you would like to cache the sales tax lookup and verify address API calls. The default value is `86400` (24 hours), or enter `0` to disable caching for development purposes.
* **Capture in TaxCloud** - Choose when the order is sent to TaxCloud: *On order creation* (at checkout; default), *On payment* (when an invoice is paid; recommended to avoid canceled orders reaching TaxCloud), or *On shipment* (when a shipment is created). For online payment methods, "on creation" and "on payment" often fire together; the choice matters for offline payment or when you only want to report tax on fulfilled orders.

#### Product Settings

Expand Down Expand Up @@ -243,8 +244,8 @@ Each of these situations can be accomplished using an event observer. For every
| `taxcloud_lookup_after` | Emitted after the `Lookup` call to get tax rates | `$result`, `$customer`, `$address`, `$quote`, `$itemsByType`, `$shippingAssignment` |
| `taxcloud_verify_address_before` | Emitted before the `VerifyAddress` call during checkout | `$params` |
| `taxcloud_verify_address_after` | Emitted after the `VerifyAddress` call during checkout | `$result` |
| `taxcloud_authorized_with_capture_before` | Emitted before the `AuthorizedWithCapture` call when an order is placed | `$params`, `$order` |
| `taxcloud_authorized_with_capture_after` | Emitted after the `AuthorizedWithCapture` call when an order is placed | `$result`, `$order` |
| `taxcloud_authorized_with_capture_before` | Emitted before the `AuthorizedWithCapture` call (when the order is sent per "Capture in TaxCloud" setting) | `$params`, `$order` |
| `taxcloud_authorized_with_capture_after` | Emitted after the `AuthorizedWithCapture` call (when the order is sent per "Capture in TaxCloud" setting) | `$result`, `$order` |
| `taxcloud_returned_before` | Emitted before the `Returned` call when a credit memo is created or when a canceled unpaid order is reversed | `$params`, `$order`, `$items`, `$creditmemo` |
| `taxcloud_returned_after` | Emitted after the `Returned` call when a credit memo is created or when a canceled unpaid order is reversed | `$result`, `$order`, `$items`, `$creditmemo` |

Expand Down
10 changes: 10 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@
</depends>
</field>

<field id="capture_trigger" translate="label" type="select" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Capture in TaxCloud</label>
<source_model>Taxcloud\Magento2\Model\Config\Source\CaptureTrigger</source_model>
<config_path>tax/taxcloud_settings/capture_trigger</config_path>
<tooltip>On order creation: at checkout (default; canceled orders may reach TaxCloud). On payment: when invoice is paid (recommended to avoid canceled orders). On shipment: when shipment is created.</tooltip>
<depends>
<field id="enabled">1</field>
</depends>
</field>

</group>
</section>
</system>
Expand Down
1 change: 1 addition & 0 deletions etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<shipping_tic>11010</shipping_tic>
<cache_lifetime>86400</cache_lifetime>
<fallback_to_magento>0</fallback_to_magento>
<capture_trigger>order_creation</capture_trigger>
</taxcloud_settings>
</tax>
</default>
Expand Down
6 changes: 6 additions & 0 deletions etc/events.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
<event name="sales_order_place_after">
<observer name="afterOrder" instance="Taxcloud\Magento2\Observer\Sales\Complete"/>
</event>
<event name="sales_order_invoice_pay">
<observer name="afterInvoicePay" instance="Taxcloud\Magento2\Observer\Sales\Complete"/>
</event>
<event name="sales_order_shipment_save_after">
<observer name="afterShipment" instance="Taxcloud\Magento2\Observer\Sales\Complete"/>
</event>

<event name="sales_order_creditmemo_refund">
<observer name="afterRefund" instance="Taxcloud\Magento2\Observer\Sales\Refund"/>
Expand Down
Loading