mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
Add PurchaseUnitSanitizer tests
Add subtotal mismatch admin options
This commit is contained in:
parent
c15b8ee463
commit
837bdb0392
6 changed files with 314 additions and 50 deletions
|
@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentPreferencesFactory;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PlanFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ProductFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingOptionFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
|
@ -299,6 +300,7 @@ return array(
|
|||
$payments_factory = $container->get( 'api.factory.payments' );
|
||||
$prefix = $container->get( 'api.prefix' );
|
||||
$soft_descriptor = $container->get( 'wcgateway.soft-descriptor' );
|
||||
$sanitizer = $container->get( 'api.helper.purchase-unit-sanitizer' );
|
||||
|
||||
return new PurchaseUnitFactory(
|
||||
$amount_factory,
|
||||
|
@ -308,7 +310,8 @@ return array(
|
|||
$shipping_factory,
|
||||
$payments_factory,
|
||||
$prefix,
|
||||
$soft_descriptor
|
||||
$soft_descriptor,
|
||||
$sanitizer
|
||||
);
|
||||
},
|
||||
'api.factory.patch-collection-factory' => static function ( ContainerInterface $container ): PatchCollectionFactory {
|
||||
|
@ -814,4 +817,12 @@ return array(
|
|||
'api.order-helper' => static function( ContainerInterface $container ): OrderHelper {
|
||||
return new OrderHelper();
|
||||
},
|
||||
'api.helper.purchase-unit-sanitizer' => static function( ContainerInterface $container ): PurchaseUnitSanitizer {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
$behavior = $settings->has( 'subtotal_mismatch_behavior' ) ? $settings->get( 'subtotal_mismatch_behavior' ) : null;
|
||||
$line_name = $settings->has( 'subtotal_mismatch_line_name' ) ? $settings->get( 'subtotal_mismatch_line_name' ) : null;
|
||||
return new PurchaseUnitSanitizer( $behavior, $line_name );
|
||||
},
|
||||
);
|
||||
|
|
|
@ -93,6 +93,13 @@ class PurchaseUnit {
|
|||
*/
|
||||
private $contains_physical_goods = false;
|
||||
|
||||
/**
|
||||
* The sanitizer for this purchase unit output.
|
||||
*
|
||||
* @var PurchaseUnitSanitizer|null
|
||||
*/
|
||||
private $sanitizer;
|
||||
|
||||
/**
|
||||
* PurchaseUnit constructor.
|
||||
*
|
||||
|
@ -222,6 +229,16 @@ class PurchaseUnit {
|
|||
$this->custom_id = $custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sanitizer for this purchase unit output.
|
||||
*
|
||||
* @param PurchaseUnitSanitizer|null $sanitizer The sanitizer.
|
||||
* @return void
|
||||
*/
|
||||
public function set_sanitizer( ?PurchaseUnitSanitizer $sanitizer ) {
|
||||
$this->sanitizer = $sanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invoice id.
|
||||
*
|
||||
|
@ -317,8 +334,8 @@ class PurchaseUnit {
|
|||
$purchase_unit['soft_descriptor'] = $this->soft_descriptor();
|
||||
}
|
||||
|
||||
if ( $sanitize_output ) {
|
||||
$purchase_unit = ( new PurchaseUnitSanitizer( $purchase_unit, $this->items() ) )->sanitize();
|
||||
if ( $sanitize_output && isset( $this->sanitizer ) ) {
|
||||
$purchase_unit = ( $this->sanitizer->sanitize( $purchase_unit, $this->items() ) );
|
||||
}
|
||||
|
||||
return $purchase_unit;
|
||||
|
|
|
@ -13,6 +13,7 @@ use WC_Session_Handler;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\CustomIds;
|
||||
|
||||
|
@ -77,17 +78,25 @@ class PurchaseUnitFactory {
|
|||
*/
|
||||
private $soft_descriptor;
|
||||
|
||||
/**
|
||||
* The sanitizer for purchase unit output data.
|
||||
*
|
||||
* @var PurchaseUnitSanitizer|null
|
||||
*/
|
||||
private $sanitizer;
|
||||
|
||||
/**
|
||||
* PurchaseUnitFactory constructor.
|
||||
*
|
||||
* @param AmountFactory $amount_factory The amount factory.
|
||||
* @param PayeeRepository $payee_repository The Payee repository.
|
||||
* @param PayeeFactory $payee_factory The Payee factory.
|
||||
* @param ItemFactory $item_factory The item factory.
|
||||
* @param ShippingFactory $shipping_factory The shipping factory.
|
||||
* @param PaymentsFactory $payments_factory The payments factory.
|
||||
* @param string $prefix The prefix.
|
||||
* @param string $soft_descriptor The soft descriptor.
|
||||
* @param AmountFactory $amount_factory The amount factory.
|
||||
* @param PayeeRepository $payee_repository The Payee repository.
|
||||
* @param PayeeFactory $payee_factory The Payee factory.
|
||||
* @param ItemFactory $item_factory The item factory.
|
||||
* @param ShippingFactory $shipping_factory The shipping factory.
|
||||
* @param PaymentsFactory $payments_factory The payments factory.
|
||||
* @param string $prefix The prefix.
|
||||
* @param string $soft_descriptor The soft descriptor.
|
||||
* @param ?PurchaseUnitSanitizer $sanitizer The purchase unit to_array sanitizer.
|
||||
*/
|
||||
public function __construct(
|
||||
AmountFactory $amount_factory,
|
||||
|
@ -97,7 +106,8 @@ class PurchaseUnitFactory {
|
|||
ShippingFactory $shipping_factory,
|
||||
PaymentsFactory $payments_factory,
|
||||
string $prefix = 'WC-',
|
||||
string $soft_descriptor = ''
|
||||
string $soft_descriptor = '',
|
||||
PurchaseUnitSanitizer $sanitizer = null
|
||||
) {
|
||||
|
||||
$this->amount_factory = $amount_factory;
|
||||
|
@ -108,6 +118,7 @@ class PurchaseUnitFactory {
|
|||
$this->payments_factory = $payments_factory;
|
||||
$this->prefix = $prefix;
|
||||
$this->soft_descriptor = $soft_descriptor;
|
||||
$this->sanitizer = $sanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,6 +162,9 @@ class PurchaseUnitFactory {
|
|||
$invoice_id,
|
||||
$soft_descriptor
|
||||
);
|
||||
|
||||
$this->init_purchase_unit( $purchase_unit );
|
||||
|
||||
/**
|
||||
* Returns PurchaseUnit for the WC order.
|
||||
*/
|
||||
|
@ -221,6 +235,8 @@ class PurchaseUnitFactory {
|
|||
$soft_descriptor
|
||||
);
|
||||
|
||||
$this->init_purchase_unit( $purchase_unit );
|
||||
|
||||
return $purchase_unit;
|
||||
}
|
||||
|
||||
|
@ -283,6 +299,9 @@ class PurchaseUnitFactory {
|
|||
$soft_descriptor,
|
||||
$payments
|
||||
);
|
||||
|
||||
$this->init_purchase_unit( $purchase_unit );
|
||||
|
||||
return $purchase_unit;
|
||||
}
|
||||
|
||||
|
@ -313,4 +332,16 @@ class PurchaseUnitFactory {
|
|||
$countries = array( 'AE', 'AF', 'AG', 'AI', 'AL', 'AN', 'AO', 'AW', 'BB', 'BF', 'BH', 'BI', 'BJ', 'BM', 'BO', 'BS', 'BT', 'BW', 'BZ', 'CD', 'CF', 'CG', 'CI', 'CK', 'CL', 'CM', 'CO', 'CR', 'CV', 'DJ', 'DM', 'DO', 'EC', 'EG', 'ER', 'ET', 'FJ', 'FK', 'GA', 'GD', 'GH', 'GI', 'GM', 'GN', 'GQ', 'GT', 'GW', 'GY', 'HK', 'HN', 'HT', 'IE', 'IQ', 'IR', 'JM', 'JO', 'KE', 'KH', 'KI', 'KM', 'KN', 'KP', 'KW', 'KY', 'LA', 'LB', 'LC', 'LK', 'LR', 'LS', 'LY', 'ML', 'MM', 'MO', 'MR', 'MS', 'MT', 'MU', 'MW', 'MZ', 'NA', 'NE', 'NG', 'NI', 'NP', 'NR', 'NU', 'OM', 'PA', 'PE', 'PF', 'PY', 'QA', 'RW', 'SA', 'SB', 'SC', 'SD', 'SL', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SY', 'TC', 'TD', 'TG', 'TL', 'TO', 'TT', 'TV', 'TZ', 'UG', 'UY', 'VC', 'VE', 'VG', 'VN', 'VU', 'WS', 'XA', 'XB', 'XC', 'XE', 'XL', 'XM', 'XN', 'XS', 'YE', 'ZM', 'ZW' );
|
||||
return in_array( $country_code, $countries, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a purchase unit object.
|
||||
*
|
||||
* @param PurchaseUnit $purchase_unit The purchase unit.
|
||||
* @return void
|
||||
*/
|
||||
private function init_purchase_unit( PurchaseUnit $purchase_unit ): void {
|
||||
if ( $this->sanitizer instanceof PurchaseUnitSanitizer ) {
|
||||
$purchase_unit->set_sanitizer( $this->sanitizer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,31 +24,80 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
|||
* Class PurchaseUnitSanitizer
|
||||
*/
|
||||
class PurchaseUnitSanitizer {
|
||||
const MODE_DITCH = 'ditch';
|
||||
const MODE_EXTRA_LINE = 'extra_line';
|
||||
const VALID_MODES = array(
|
||||
self::MODE_DITCH,
|
||||
self::MODE_EXTRA_LINE,
|
||||
);
|
||||
|
||||
const EXTRA_LINE_NAME = 'Subtotal mismatch';
|
||||
|
||||
/**
|
||||
* The purchase unit data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $purchase_unit;
|
||||
private $purchase_unit = array();
|
||||
|
||||
/**
|
||||
* The purchase unit Item objects
|
||||
*
|
||||
* @var array|Item[]
|
||||
*/
|
||||
private $item_objects;
|
||||
private $item_objects = array();
|
||||
|
||||
/**
|
||||
* The working mode
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $mode;
|
||||
|
||||
/**
|
||||
* The name for the extra line
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $extra_line_name;
|
||||
|
||||
|
||||
/**
|
||||
* PurchaseUnitSanitizer constructor.
|
||||
*
|
||||
* @param array $purchase_unit The purchase_unit array that should be sanitized.
|
||||
* @param array|Item[] $item_objects The purchase unit Item objects used for recalculations.
|
||||
* @param string|null $mode The mismatch handling mode, ditch or extra_line.
|
||||
* @param string|null $extra_line_name The name of the extra line.
|
||||
*/
|
||||
public function __construct( array $purchase_unit, array $item_objects ) {
|
||||
$this->purchase_unit = $purchase_unit;
|
||||
$this->item_objects = $item_objects;
|
||||
public function __construct( string $mode = null, string $extra_line_name = null ) {
|
||||
|
||||
if ( ! in_array( $mode, self::VALID_MODES, true ) ) {
|
||||
$mode = self::MODE_DITCH;
|
||||
}
|
||||
|
||||
if ( ! $extra_line_name ) {
|
||||
$extra_line_name = self::EXTRA_LINE_NAME;
|
||||
}
|
||||
|
||||
$this->mode = $mode;
|
||||
$this->extra_line_name = $extra_line_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if mode is ditch.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_mode_ditch(): bool {
|
||||
return $this->mode === self::MODE_DITCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if mode is adding extra line.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_mode_extra_line(): bool {
|
||||
return $this->mode === self::MODE_EXTRA_LINE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,9 +152,14 @@ class PurchaseUnitSanitizer {
|
|||
/**
|
||||
* The sanitizes the purchase_unit array.
|
||||
*
|
||||
* @param array $purchase_unit The purchase_unit array that should be sanitized.
|
||||
* @param array|Item[] $item_objects The purchase unit Item objects used for recalculations.
|
||||
* @return array
|
||||
*/
|
||||
public function sanitize(): array {
|
||||
public function sanitize( array $purchase_unit, array $item_objects ): array {
|
||||
$this->purchase_unit = $purchase_unit;
|
||||
$this->item_objects = $item_objects;
|
||||
|
||||
$this->sanitize_item_amount_mismatch();
|
||||
$this->sanitize_item_tax_mismatch();
|
||||
$this->sanitize_breakdown_mismatch();
|
||||
|
@ -120,25 +174,28 @@ class PurchaseUnitSanitizer {
|
|||
private function sanitize_item_amount_mismatch(): void {
|
||||
$item_mismatch = $this->calculate_item_mismatch();
|
||||
|
||||
if ( $item_mismatch < 0 ) {
|
||||
// Do floors on item amounts so item_mismatch is a positive value.
|
||||
foreach ( $this->item_objects as $index => $item ) {
|
||||
$this->purchase_unit['items'][ $index ] = $item->to_array(
|
||||
$item->unit_amount()->is_rounding_up()
|
||||
);
|
||||
if ( $this->is_mode_extra_line() ) {
|
||||
if ( $item_mismatch < 0 ) {
|
||||
// Do floors on item amounts so item_mismatch is a positive value.
|
||||
foreach ( $this->item_objects as $index => $item ) {
|
||||
$this->purchase_unit['items'][ $index ] = $item->to_array(
|
||||
$item->unit_amount()->is_rounding_up()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$item_mismatch = $this->calculate_item_mismatch();
|
||||
|
||||
if ( $item_mismatch > 0 ) {
|
||||
// Add extra line item with roundings.
|
||||
$line_name = $this->extra_line_name;
|
||||
$roundings_money = new Money( $item_mismatch, $this->currency_code() );
|
||||
$this->purchase_unit['items'][] = ( new Item( $line_name, $roundings_money, 1 ) )->to_array();
|
||||
}
|
||||
|
||||
$item_mismatch = $this->calculate_item_mismatch();
|
||||
}
|
||||
|
||||
$item_mismatch = $this->calculate_item_mismatch();
|
||||
|
||||
if ( $item_mismatch > 0 ) {
|
||||
// Add extra line item with roundings.
|
||||
$roundings_money = new Money( $item_mismatch, $this->currency_code() );
|
||||
$this->purchase_unit['items'][] = ( new Item( 'Roundings', $roundings_money, 1 ) )->to_array();
|
||||
}
|
||||
|
||||
$item_mismatch = $this->calculate_item_mismatch();
|
||||
|
||||
if ( $item_mismatch !== 0.0 ) {
|
||||
// Ditch items.
|
||||
if ( isset( $this->purchase_unit['items'] ) ) {
|
||||
|
@ -257,8 +314,8 @@ class PurchaseUnitSanitizer {
|
|||
$amount_total += $this->breakdown_value( 'item_total' );
|
||||
$amount_total += $this->breakdown_value( 'tax_total' );
|
||||
$amount_total += $this->breakdown_value( 'shipping' );
|
||||
$amount_total += $this->breakdown_value( 'discount' );
|
||||
$amount_total += $this->breakdown_value( 'shipping_discount' );
|
||||
$amount_total -= $this->breakdown_value( 'discount' );
|
||||
$amount_total -= $this->breakdown_value( 'shipping_discount' );
|
||||
$amount_total += $this->breakdown_value( 'handling' );
|
||||
$amount_total += $this->breakdown_value( 'insurance' );
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
|
@ -496,6 +497,42 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'subtotal_mismatch_behavior' => array(
|
||||
'title' => __( 'Subtotal mismatch behavior', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'vertical',
|
||||
'desc_tip' => true,
|
||||
'description' => __(
|
||||
'Differences between WooCommerce and PayPal roundings may give origin to a mismatch in order items subtotal calculations. If not handled these mismatches will cause the PayPal transaction to fail.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'options' => array(
|
||||
PurchaseUnitSanitizer::MODE_DITCH => __( 'Do not send line items to PayPal', 'woocommerce-paypal-payments' ),
|
||||
PurchaseUnitSanitizer::MODE_EXTRA_LINE => __( 'Add another line item', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'subtotal_mismatch_line_name' => array(
|
||||
'title' => __( 'Subtotal mismatch line name', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The name of the extra line that will be sent to PayPal to correct the subtotal mismatch.', 'woocommerce-paypal-payments' ),
|
||||
'maxlength' => 22,
|
||||
'default' => '',
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'placeholder' => PurchaseUnitSanitizer::EXTRA_LINE_NAME,
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( $fields, $connection_fields );
|
||||
|
|
|
@ -3,6 +3,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use Mockery;
|
||||
|
||||
|
@ -75,24 +76,57 @@ class PurchaseUnitTest extends TestCase
|
|||
$this->assertEquals($expected, $testee->to_array());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForDitchTests
|
||||
* @param array $items
|
||||
* @param Amount $amount
|
||||
* @param bool $doDitch
|
||||
*/
|
||||
public function testDitchMethod(array $items, Amount $amount, bool $doDitch, string $message)
|
||||
/**
|
||||
* @dataProvider dataForDitchTests
|
||||
* @param array $items
|
||||
* @param Amount $amount
|
||||
* @param bool|array $doDitch
|
||||
* @param string $message
|
||||
*/
|
||||
public function testDitchMethod(array $items, Amount $amount, $doDitch, string $message)
|
||||
{
|
||||
if (is_array($doDitch)) {
|
||||
$doDitchItems = $doDitch['items'];
|
||||
$doDitchBreakdown = $doDitch['breakdown'];
|
||||
$doDitchTax = $doDitch['tax'];
|
||||
} else {
|
||||
$doDitchItems = $doDitch;
|
||||
$doDitchBreakdown = $doDitch;
|
||||
$doDitchTax = $doDitch;
|
||||
}
|
||||
|
||||
// $dataSetName = $this->dataName();
|
||||
// if ($dataSetName !== 'dont_ditch_with_discount') {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// print_r($amount->to_array());
|
||||
// foreach ($items as $item) {
|
||||
// print_r($item->to_array());
|
||||
// }
|
||||
|
||||
$testee = new PurchaseUnit(
|
||||
$amount,
|
||||
$items
|
||||
);
|
||||
|
||||
$testee->set_sanitizer(new PurchaseUnitSanitizer(PurchaseUnitSanitizer::MODE_DITCH));
|
||||
|
||||
$array = $testee->to_array();
|
||||
$resultItems = $doDitch === ! array_key_exists('items', $array);
|
||||
$resultBreakdown = $doDitch === ! array_key_exists('breakdown', $array['amount']);
|
||||
$resultItems = $doDitchItems === ! array_key_exists('items', $array);
|
||||
//
|
||||
// echo "------ RESULT ------\n";
|
||||
// print_r($array);
|
||||
// die('.');
|
||||
|
||||
$resultBreakdown = $doDitchBreakdown === ! array_key_exists('breakdown', $array['amount']);
|
||||
$this->assertTrue($resultItems, $message);
|
||||
$this->assertTrue($resultBreakdown, $message);
|
||||
|
||||
foreach ($array['items'] ?? [] as $item) {
|
||||
$resultTax = $doDitchTax === ! array_key_exists('tax', $item);
|
||||
$this->assertTrue($resultTax, $message);
|
||||
}
|
||||
}
|
||||
|
||||
public function dataForDitchTests() : array
|
||||
|
@ -406,6 +440,58 @@ class PurchaseUnitTest extends TestCase
|
|||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_items_total_but_not_breakdown' => [
|
||||
'message' => 'Items should be ditched because the item total does not add up. But not breakdown because it adds up.',
|
||||
'ditch' => [
|
||||
'items' => true,
|
||||
'breakdown' => false,
|
||||
'tax' => true,
|
||||
],
|
||||
'items' => [
|
||||
[
|
||||
'value' => 11,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'item_total' => 20,
|
||||
'tax_total' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shipping_discount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_items_tax_with_incorrect_tax_total' => [
|
||||
'message' => 'Ditch tax from items. Items should not be ditched because the mismatch is on the tax.',
|
||||
'ditch' => [
|
||||
'items' => false,
|
||||
'breakdown' => false,
|
||||
'tax' => true,
|
||||
],
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 4,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'item_total' => 20,
|
||||
'tax_total' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shipping_discount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$values = [];
|
||||
|
@ -421,10 +507,16 @@ class PurchaseUnitTest extends TestCase
|
|||
'tax' => $tax,
|
||||
'quantity'=> $item['quantity'],
|
||||
'category' => $item['category'],
|
||||
'to_array' => [],
|
||||
'to_array' => [
|
||||
'unit_amount' => $unitAmount->to_array(),
|
||||
'tax' => $tax->to_array(),
|
||||
'quantity'=> $item['quantity'],
|
||||
'category' => $item['category'],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown = null;
|
||||
if ($test['breakdown']) {
|
||||
$breakdown = Mockery::mock(AmountBreakdown::class);
|
||||
|
@ -438,10 +530,29 @@ class PurchaseUnitTest extends TestCase
|
|||
return $money;
|
||||
});
|
||||
}
|
||||
|
||||
$breakdown
|
||||
->shouldReceive('to_array')
|
||||
->andReturn(
|
||||
array_map(
|
||||
function ($value) {
|
||||
return $value ? (new Money($value, 'EUR'))->to_array() : null;
|
||||
},
|
||||
$test['breakdown']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$amountMoney = new Money($test['amount'], 'EUR');
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amount->shouldReceive('to_array')->andReturn(['value' => number_format( $test['amount'], 2, '.', '' ), 'breakdown' => []]);
|
||||
$amount->shouldReceive('value_str')->andReturn(number_format( $test['amount'], 2, '.', '' ));
|
||||
$amount
|
||||
->shouldReceive('to_array')
|
||||
->andReturn([
|
||||
'value' => $amountMoney->value_str(),
|
||||
'currency_code' => $amountMoney->currency_code(),
|
||||
'breakdown' => $breakdown ? $breakdown->to_array() : [],
|
||||
]);
|
||||
$amount->shouldReceive('value_str')->andReturn($amountMoney->value_str());
|
||||
$amount->shouldReceive('currency_code')->andReturn('EUR');
|
||||
$amount->shouldReceive('breakdown')->andReturn($breakdown);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue