Skip to content

Commit 6be1d5c

Browse files
committed
Issue #2873394 by bojanz: Make taxes functional
1 parent b8a7444 commit 6be1d5c

File tree

6 files changed

+157
-12
lines changed

6 files changed

+157
-12
lines changed

modules/cart/tests/src/Kernel/CartManagerTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function testCartManager() {
117117

118118
$order_item1 = $this->cartManager->addEntity($cart, $this->variation1);
119119
$order_item1 = $this->reloadEntity($order_item1);
120-
$this->assertEquals([$order_item1], $cart->getItems());
120+
$this->assertNotEmpty($cart->hasItem($order_item1));
121121
$this->assertEquals(1, $order_item1->getQuantity());
122122
$this->assertEquals(new Price('1.00', 'USD'), $cart->getTotalPrice());
123123

@@ -145,7 +145,7 @@ public function testCartManager() {
145145
}
146146

147147
/**
148-
* Tests that order items without purchaseable entity do not cause crashes.
148+
* Tests that order items without purchasable entities do not cause crashes.
149149
*/
150150
public function testAddOrderItem() {
151151
$this->installCommerceCart();

modules/order/src/Entity/Order.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,13 @@ public function preSave(EntityStorageInterface $storage) {
485485
}
486486
}
487487

488+
// Ensure that $order_item->getOrder() works, for the order refresh
489+
// process. The actual reference will be saved in postSave().
490+
foreach ($this->getItems() as $order_item) {
491+
if ($order_item->order_id->isEmpty()) {
492+
$order_item->order_id = $this;
493+
}
494+
}
488495
// Maintain the completed timestamp.
489496
$state = $this->getState()->value;
490497
$original_state = isset($this->original) ? $this->original->getState()->value : '';
@@ -493,7 +500,6 @@ public function preSave(EntityStorageInterface $storage) {
493500
$this->setCompletedTime(\Drupal::time()->getRequestTime());
494501
}
495502
}
496-
497503
// Refresh draft orders on every save.
498504
if ($this->getState()->value == 'draft' && empty($this->getRefreshState())) {
499505
$this->setRefreshState(self::REFRESH_ON_SAVE);

modules/tax/config/schema/commerce_tax.schema.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ commerce_tax.commerce_tax_type.plugin.custom:
5454
type: label
5555
label: 'Label'
5656
amount:
57-
type: float
57+
type: string
5858
label: 'Amount'
5959
territories:
6060
type: sequence

modules/tax/src/Event/CustomerProfileEvent.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@ class CustomerProfileEvent extends Event {
3131
* Constructs a new CustomerProfileEvent.
3232
*
3333
* @param \Drupal\profile\Entity\ProfileInterface $customer_profile
34-
* The customer profile.
34+
* The initially selected customer profile.
3535
* @param \Drupal\commerce_order\Entity\OrderItemInterface $order_item
36-
* The removed order item.
36+
* The order item.
3737
*/
38-
public function __construct(ProfileInterface $customer_profile, OrderItemInterface $order_item) {
38+
public function __construct(ProfileInterface $customer_profile = NULL, OrderItemInterface $order_item) {
3939
$this->customerProfile = $customer_profile;
4040
$this->orderItem = $order_item;
4141
}
4242

4343
/**
4444
* Gets the customer profile.
4545
*
46-
* @return \Drupal\profile\Entity\ProfileInterface
47-
* The customer profile.
46+
* @return \Drupal\profile\Entity\ProfileInterface|null
47+
* The customer profile, or NULL if not yet known.
4848
*/
4949
public function getCustomerProfile() {
5050
return $this->customerProfile;

modules/tax/src/Plugin/Commerce/TaxType/TaxTypeBase.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,6 @@ protected function getTaxableType(OrderItemInterface $order_item) {
217217
*/
218218
protected function resolveCustomerProfile(OrderItemInterface $order_item) {
219219
$order = $order_item->getOrder();
220-
if (!$order) {
221-
return;
222-
}
223220
$store = $order->getStore();
224221
$prices_include_tax = $store->get('prices_include_tax')->value;
225222
$customer_profile = $order->getBillingProfile();
@@ -232,6 +229,7 @@ protected function resolveCustomerProfile(OrderItemInterface $order_item) {
232229
// better to show the store's default tax than nothing.
233230
$profile_storage = $this->entityTypeManager->getStorage('profile');
234231
$customer_profile = $profile_storage->create([
232+
'type' => 'customer',
235233
'uid' => $order->getCustomerId(),
236234
'address' => $store->getAddress(),
237235
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace Drupal\Tests\commerce_tax\Kernel;
4+
5+
use Drupal\commerce_order\Entity\Order;
6+
use Drupal\commerce_order\Entity\OrderItem;
7+
use Drupal\commerce_order\Entity\OrderItemType;
8+
use Drupal\commerce_price\Price;
9+
use Drupal\commerce_tax\Entity\TaxType;
10+
use Drupal\profile\Entity\Profile;
11+
use Drupal\Tests\commerce\Kernel\CommerceKernelTestBase;
12+
13+
/**
14+
* Tests integration with orders.
15+
*
16+
* @group commerce
17+
*/
18+
class OrderIntegrationTest extends CommerceKernelTestBase {
19+
20+
/**
21+
* A sample order.
22+
*
23+
* @var \Drupal\commerce_order\Entity\OrderInterface
24+
*/
25+
protected $order;
26+
27+
/**
28+
* Modules to enable.
29+
*
30+
* @var array
31+
*/
32+
public static $modules = [
33+
'entity_reference_revisions',
34+
'path',
35+
'profile',
36+
'state_machine',
37+
'commerce_order',
38+
'commerce_tax',
39+
];
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
protected function setUp() {
45+
parent::setUp();
46+
47+
$this->installEntitySchema('profile');
48+
$this->installEntitySchema('commerce_order');
49+
$this->installEntitySchema('commerce_order_item');
50+
$this->installConfig(['commerce_order']);
51+
$user = $this->createUser(['mail' => $this->randomString() . '@example.com']);
52+
53+
$this->store->set('prices_include_tax', TRUE);
54+
$this->store->save();
55+
56+
// The default store is US-WI, so imagine that the US has VAT.
57+
TaxType::create([
58+
'id' => 'us_vat',
59+
'label' => 'US VAT',
60+
'plugin' => 'custom',
61+
'configuration' => [
62+
'display_inclusive' => TRUE,
63+
'rates' => [
64+
[
65+
'id' => 'standard',
66+
'label' => 'Standard',
67+
'amount' => '0.2',
68+
],
69+
],
70+
'territories' => [
71+
['country_code' => 'US', 'administrative_area' => 'WI'],
72+
['country_code' => 'US', 'administrative_area' => 'SC'],
73+
],
74+
],
75+
])->save();
76+
OrderItemType::create([
77+
'id' => 'test',
78+
'label' => 'Test',
79+
'orderType' => 'default',
80+
])->save();
81+
$order = Order::create([
82+
'type' => 'default',
83+
'store_id' => $this->store->id(),
84+
'state' => 'draft',
85+
'mail' => $user->getEmail(),
86+
'uid' => $user->id(),
87+
'ip_address' => '127.0.0.1',
88+
'order_number' => '6',
89+
]);
90+
$order->save();
91+
$this->order = $this->reloadEntity($order);
92+
}
93+
94+
/**
95+
* Tests that the store address is used as a default for new orders.
96+
*/
97+
public function testDefaultProfile() {
98+
$order_item = OrderItem::create([
99+
'type' => 'test',
100+
'quantity' => '1',
101+
'unit_price' => new Price('12.00', 'USD'),
102+
]);
103+
$order_item->save();
104+
$this->order->addItem($order_item);
105+
$this->order->save();
106+
$adjustments = $this->order->collectAdjustments();
107+
$adjustment = reset($adjustments);
108+
$this->assertCount(1, $adjustments);
109+
$this->assertEquals(new Price('2.00', 'USD'), $adjustment->getAmount());
110+
$this->assertEquals('us_vat|default|standard', $adjustment->getSourceId());
111+
}
112+
113+
/**
114+
* Tests the usage of default billing profile.
115+
*/
116+
public function testBillingProfile() {
117+
$profile = Profile::create([
118+
'type' => 'customer',
119+
'address' => [
120+
'country_code' => 'US',
121+
'administrative_area' => 'SC',
122+
],
123+
]);
124+
$profile->save();
125+
$order_item = OrderItem::create([
126+
'type' => 'test',
127+
'quantity' => '1',
128+
'unit_price' => new Price('12.00', 'USD'),
129+
]);
130+
$order_item->save();
131+
$this->order->addItem($order_item);
132+
$this->order->setBillingProfile($profile);
133+
$this->order->save();
134+
$adjustments = $this->order->collectAdjustments();
135+
$adjustment = reset($adjustments);
136+
$this->assertCount(1, $adjustments);
137+
$this->assertEquals(new Price('2.00', 'USD'), $adjustment->getAmount());
138+
$this->assertEquals('us_vat|default|standard', $adjustment->getSourceId());
139+
}
140+
141+
}

0 commit comments

Comments
 (0)