Skip to content

WIP / test only -- 2804227 get order balance jack #821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2b82fad
Issue #2804227 Add total_paid field and Order::getBalance() and relat…
steveoliver Sep 23, 2016
f9b39a5
Fix OrderInterface docblocks (thanks, phpcs).
steveoliver Sep 23, 2016
21f71f5
Add Order tests for ::getBalance, ::getTotalPaid, ::setTotalPaid, ::a…
steveoliver Oct 17, 2016
dd89f06
Add and subtract payments to and from order when saving and deleting …
steveoliver Feb 7, 2017
d1f657a
Support multiple partial refunds.
steveoliver Feb 8, 2017
7c0c7bc
Clean up Order entity test.
steveoliver Feb 8, 2017
bc714fb
Use Price.
steveoliver Apr 12, 2017
1b626a9
add update to add the total_paid field
vasike Sep 4, 2017
6716a30
Update payment states to match new names
jackbravo Sep 7, 2017
4228332
Watch payment status before changing order balance
jackbravo Sep 11, 2017
d32cfb1
Fix two coding standard errors
jackbravo Sep 11, 2017
52dbc5d
remove the word 'remaining' -- it seems redundant
steveoliver Sep 15, 2017
e6e941d
Issue #2804227 Add total_paid field and Order::getBalance() and relat…
steveoliver Sep 23, 2016
efd1ed3
Fix OrderInterface docblocks (thanks, phpcs).
steveoliver Sep 23, 2016
bd7d456
Add Order tests for ::getBalance, ::getTotalPaid, ::setTotalPaid, ::a…
steveoliver Oct 17, 2016
1e7afa1
Add and subtract payments to and from order when saving and deleting …
steveoliver Feb 7, 2017
9604c02
Support multiple partial refunds.
steveoliver Feb 8, 2017
e4cb7b6
Clean up Order entity test.
steveoliver Feb 8, 2017
8e9bb02
add update to add the total_paid field
vasike Sep 4, 2017
cea937e
Watch payment status before changing order balance
jackbravo Sep 11, 2017
b20f2b7
Fix two coding standard errors
jackbravo Sep 11, 2017
47f337a
remove the word 'remaining' -- it seems redundant
steveoliver Sep 15, 2017
0d0802f
Get test to almost passing for core updates
Mar 28, 2018
c077bd1
Merge branch '2804227-get-order-balance-jack' of https://github.com/s…
Mar 28, 2018
c88310e
Remove hanging conflict markers
Mar 28, 2018
b184f5b
Merge branch '8.x-2.x' into 2804227-get-order-balance-jack
steveoliver Mar 29, 2018
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
16 changes: 16 additions & 0 deletions modules/order/commerce_order.post_update.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Field\BaseFieldDefinition;

/**
* Revert Order views to fix broken Price fields.
Expand Down Expand Up @@ -201,3 +202,18 @@ function commerce_order_post_update_7() {

return $message;
}

/**
* Add 'total_paid' field to 'commerce_order' entities.
*/
function commerce_order_post_update_8() {
$storage_definition = BaseFieldDefinition::create('commerce_price')
->setLabel(t('Total paid'))
->setDescription(t('The total amount paid on the order.'))
->setReadOnly(TRUE)
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', TRUE);
\Drupal::entityDefinitionUpdateManager()
->installFieldStorageDefinition('total_paid', 'commerce_order', 'commerce_order', $storage_definition);
return t('The order total paid field was created.');
}
51 changes: 51 additions & 0 deletions modules/order/src/Entity/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Drupal\commerce\Entity\CommerceContentEntityBase;
use Drupal\commerce_order\Adjustment;
use Drupal\commerce_price\Price;
use Drupal\commerce_store\Entity\StoreInterface;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
Expand Down Expand Up @@ -389,6 +390,49 @@ public function getTotalPrice() {
}
}

/**
* {@inheritdoc}
*/
public function addPayment(Price $amount) {
$this->setTotalPaid($this->getTotalPaid()->add($amount));
return $this;
}

/**
* {@inheritdoc}
*/
public function subtractPayment(Price $amount) {
$this->setTotalPaid($this->getTotalPaid()->subtract($amount));
return $this;
}

/**
* {@inheritdoc}
*/
public function getTotalPaid() {
if (!$this->get('total_paid')->isEmpty()) {
return $this->get('total_paid')->first()->toPrice();
}
return new Price('0', $this->getStore()->getDefaultCurrencyCode());
}

/**
* {@inheritdoc}
*/
public function setTotalPaid(Price $amount) {
$this->set('total_paid', $amount);
}

/**
* {@inheritdoc}
*/
public function getBalance() {
if ($this->getTotalPrice() && $this->getTotalPaid()) {
return $this->getTotalPrice()->subtract($this->getTotalPaid());
}
return $this->getTotalPrice();
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -670,6 +714,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', TRUE);

$fields['total_paid'] = BaseFieldDefinition::create('commerce_price')
->setLabel(t('Total paid'))
->setDescription(t('The total amount paid on the order.'))
->setReadOnly(TRUE)
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', TRUE);

$fields['state'] = BaseFieldDefinition::create('state')
->setLabel(t('State'))
->setDescription(t('The order state.'))
Expand Down
45 changes: 45 additions & 0 deletions modules/order/src/Entity/OrderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Drupal\commerce_order\Entity;

use Drupal\commerce_order\EntityAdjustableInterface;
use Drupal\commerce_price\Price;
use Drupal\commerce_store\Entity\StoreInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityChangedInterface;
Expand Down Expand Up @@ -274,6 +275,50 @@ public function recalculateTotalPrice();
*/
public function getTotalPrice();

/**
* Adds an amount to the order total paid.
*
* @param \Drupal\commerce_price\Price $amount
* The amount to add to the total paid.
*
* @return $this
*/
public function addPayment(Price $amount);

/**
* Subtracts an amount from the order total paid.
*
* @param \Drupal\commerce_price\Price $amount
* The amount to subtract from the total paid.
*
* @return $this
*/
public function subtractPayment(Price $amount);

/**
* Gets the total amount paid on the order.
*
* @return \Drupal\commerce_price\Price
* The order total paid amount.
*/
public function getTotalPaid();

/**
* Sets the total amount paid on the order.
*
* @param \Drupal\commerce_price\Price $amount
* The amount to set as the order total paid.
*/
public function setTotalPaid(Price $amount);

/**
* Gets the amount unpaid on the order.
*
* @return \Drupal\commerce_price\Price|null
* The total order amount minus the total paid, or NULL.
*/
public function getBalance();

/**
* Gets the order state.
*
Expand Down
136 changes: 131 additions & 5 deletions modules/order/tests/src/Kernel/Entity/OrderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Drupal\commerce_order\Entity\OrderItemType;
use Drupal\commerce_price\Exception\CurrencyMismatchException;
use Drupal\commerce_price\Price;
use Drupal\commerce_payment\Entity\Payment;
use Drupal\commerce_payment\Entity\PaymentGateway;
use Drupal\profile\Entity\Profile;
use Drupal\Tests\commerce\Kernel\CommerceKernelTestBase;

Expand All @@ -27,6 +29,13 @@ class OrderTest extends CommerceKernelTestBase {
*/
protected $user;

/**
* The payment gateway plugin.
*
* @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsRefundsInterface
*/
protected $payment_gateway_plugin;

/**
* Modules to enable.
*
Expand All @@ -36,6 +45,8 @@ class OrderTest extends CommerceKernelTestBase {
'entity_reference_revisions',
'profile',
'state_machine',
'commerce_payment',
'commerce_payment_example',
'commerce_product',
'commerce_order',
];
Expand All @@ -49,6 +60,7 @@ protected function setUp() {
$this->installEntitySchema('profile');
$this->installEntitySchema('commerce_order');
$this->installEntitySchema('commerce_order_item');
$this->installEntitySchema('commerce_payment');
$this->installConfig('commerce_order');

// An order item type that doesn't need a purchasable entity, for simplicity.
Expand All @@ -58,6 +70,14 @@ protected function setUp() {
'orderType' => 'default',
])->save();

$payment_gateway = PaymentGateway::create([
'id' => 'example',
'label' => 'Example',
'plugin' => 'example_onsite',
]);
$payment_gateway->save();
$this->payment_gateway_plugin = $payment_gateway->getPlugin();

$user = $this->createUser();
$this->user = $this->reloadEntity($user);
}
Expand Down Expand Up @@ -96,6 +116,11 @@ protected function setUp() {
* @covers ::getSubtotalPrice
* @covers ::recalculateTotalPrice
* @covers ::getTotalPrice
* @covers ::getBalance
* @covers ::addPayment
* @covers ::subtractPayment
* @covers ::setTotalPaid
* @covers ::getTotalPaid
* @covers ::getState
* @covers ::getRefreshState
* @covers ::setRefreshState
Expand Down Expand Up @@ -138,6 +163,7 @@ public function testOrder() {
$order = Order::create([
'type' => 'default',
'state' => 'completed',
'store_id' => $this->store->id(),
]);
$order->save();

Expand Down Expand Up @@ -182,7 +208,9 @@ public function testOrder() {
$this->assertEquals([$order_item, $another_order_item], $order->getItems());
$this->assertNotEmpty($order->hasItem($another_order_item));
$this->assertEquals(new Price('8.00', 'USD'), $order->getTotalPrice());
$this->assertEquals(new Price('8.00', 'USD'), $order->getBalance());

// Create Adjustments
$adjustments = [];
$adjustments[] = new Adjustment([
'type' => 'custom',
Expand All @@ -198,36 +226,135 @@ public function testOrder() {
$order->addAdjustment($adjustments[0]);
$order->addAdjustment($adjustments[1]);
$this->assertEquals($adjustments, $order->getAdjustments());

// Confirm Collect Adjustments
$collected_adjustments = $order->collectAdjustments();
$this->assertEquals($adjustments[0]->getAmount(), $collected_adjustments[0]->getAmount());
$this->assertEquals($adjustments[1]->getAmount(), $collected_adjustments[1]->getAmount());

// Confirm Remove Adjustment
$order->removeAdjustment($adjustments[0]);
$this->assertEquals(new Price('8.00', 'USD'), $order->getSubtotalPrice());
$this->assertEquals(new Price('18.00', 'USD'), $order->getTotalPrice());
$this->assertEquals([$adjustments[1]], $order->getAdjustments());
$this->assertEquals(new Price('18.00', 'USD'), $order->getBalance());

// Confirm Set Adjustment to order
$order->setAdjustments($adjustments);
$this->assertEquals($adjustments, $order->getAdjustments());
$this->assertEquals(new Price('17.00', 'USD'), $order->getTotalPrice());

// Confirm that locked adjustments persist after clear.
// Custom adjustments are locked by default.
// Custom adjustments are locked by default. This adjustment clears immediately on next line
$order->addAdjustment(new Adjustment([
'type' => 'fee',
'label' => 'Random fee',
'amount' => new Price('10.00', 'USD'),
]));
$order->clearAdjustments();
$this->assertEquals($adjustments, $order->getAdjustments());
$this->assertEquals(new Price('10.00', 'USD'), $collected_adjustments[1]->getAmount());

// Confirm add payment to order
$order->addPayment(new Price('15.00', 'USD'));
$this->assertEquals(new Price('15.00', 'USD'), $order->getTotalPaid());
$this->assertEquals(new Price('2.00', 'USD'), $order->getBalance());

// Confirm subtract payment from order
$order->subtractPayment(new Price('5.00', 'USD'));
$this->assertEquals(new Price('10.00', 'USD'), $order->getTotalPaid());
$this->assertEquals(new Price('7.00', 'USD'), $order->getBalance());

// Test that payments update the order total paid and balance.
$order->save();
$payment = Payment::create([
'order_id' => $order->id(),
'amount' => new Price('7.00', 'USD'),
'payment_gateway' => 'example',
'state' => 'completed',
]);
$payment->save();
$order = Order::load($order->id());
$this->assertEquals(new Price('0.00', 'USD'), $order->getBalance());

// Confirm that payments update the order total paid and balance.
$order = Order::load($order->id());
$this->assertEquals(new Price('17.00', 'USD'), $order->getTotalPaid());
$this->assertEquals(new Price('0.00', 'USD'), $order->getBalance());

// Confirm that when we delete the payment, the payment and the refund are removed from the order
$payment->delete();
$order = Order::load($order->id());
$this->assertEquals(new Price('10.00', 'USD'), $order->getTotalPaid());

// Confirm that adding a payment updates the order balance
$payment2 = Payment::create([
'order_id' => $order->id(),
'amount' => new Price('7.00', 'USD'),
'payment_gateway' => 'example',
]);
$payment2->save();
$order = Order::load($order->id());
$this->assertEquals(new Price('0.00', 'USD'), $order->getBalance());

$payment2->setState('completed');
$payment2->save();

// Test that payments can be partially refunded multiple times.
$this->payment_gateway_plugin->refundPayment($payment2, new Price('7.00', 'USD'));
$order = Order::load($order->id());
$this->assertEquals(new Price('5.00', 'USD'), $order->getBalance());

// Refund the remaining
$this->payment_gateway_plugin->refundPayment($payment2, new Price('2.00', 'USD'));
$order = Order::load($order->id());
$this->assertEquals(new Price('7.00', 'USD'), $order->getBalance());

// Test that payments only substract total when setting to completed.
$order->save();
$payment3 = Payment::create([
'order_id' => $order->id(),
'amount' => new Price('7.00', 'USD'),
'payment_gateway' => 'example',
]);
$payment3->save();
$order = Order::load($order->id());
$this->assertEquals(new Price('17.00', 'USD'), $order->getTotalPaid());
$this->assertEquals(new Price('0.00', 'USD'), $order->getBalance());

// Confirm payment refunding updates order
$payment3->setRefundedAmount(new Price('5.00', 'USD'))->save();
$order = Order::load($order->id());
$this->assertEquals(new Price('12.00', 'USD'), $order->getTotalPaid());
$this->assertEquals(new Price('5.00', 'USD'), $order->getBalance());

$payment4 = Payment::create([
'order_id' => $order->id(),
'amount' => new Price('2.00', 'USD'),
'payment_gateway' => 'example',
]);
$payment4->save();
$order = Order::load($order->id());
$this->assertEquals(new Price('3.00', 'USD'), $order->getBalance());

// Test that the total paid amount can be set explicitly on the order.
$order->setTotalPaid(new Price('0.00', 'USD'));
$order->save();
$this->assertEquals(new Price('17.00', 'USD'), $order->getBalance());

// Confirm that we can set total paid on order
$order->setTotalPaid(new Price('7.00', 'USD'));
$this->assertEquals(new Price('10.00', 'USD'), $order->getBalance());
$this->assertEquals('completed', $order->getState()->value);

$order->setRefreshState(Order::REFRESH_ON_SAVE);
$this->assertEquals(Order::REFRESH_ON_SAVE, $order->getRefreshState());

$this->assertEquals('default', $order->getData('test', 'default'));

$order->setData('test', 'value');
$this->assertEquals('value', $order->getData('test', 'default'));

$this->assertFalse($order->isLocked());

$order->lock();
$this->assertTrue($order->isLocked());
$order->unlock();
Expand Down Expand Up @@ -350,8 +477,7 @@ public function testMultipleCurrencies() {
$this->assertEquals($eur_order_item->getTotalPrice(), $order->getTotalPrice());

// Adding a second order item with a different currency should fail.
$currency_mismatch = FALSE;
try {
$currency_mismatch = FALSE; try {
$order->addItem($usd_order_item);
}
catch (CurrencyMismatchException $e) {
Expand Down
Loading