diff --git a/src/Contracts/InvoiceContract.php b/src/Contracts/InvoiceContract.php index c6ef361..0979c4b 100644 --- a/src/Contracts/InvoiceContract.php +++ b/src/Contracts/InvoiceContract.php @@ -2,6 +2,7 @@ namespace Potelo\MultiPayment\Contracts; +use Carbon\Carbon; use Potelo\MultiPayment\Models\Invoice; use Potelo\MultiPayment\Models\Customer; use Potelo\MultiPayment\Models\CreditCard; @@ -57,4 +58,15 @@ public function refundInvoice(Invoice $invoice): Invoice; * @throws \Potelo\MultiPayment\Exceptions\ModelAttributeValidationException */ public function chargeInvoiceWithCreditCard(Invoice $invoice): Invoice; + + /** + * Duplicate an invoice + * + * @param Invoice $invoice + * @param \Carbon\Carbon $expiresAt + * @param array $gatewayOptions + * @return Invoice + * @throws \Potelo\MultiPayment\Exceptions\GatewayException + */ + public function duplicateInvoice(Invoice $invoice, Carbon $expiresAt, array $gatewayOptions = []): Invoice; } diff --git a/src/Gateways/IuguGateway.php b/src/Gateways/IuguGateway.php index 2c13cad..1c76b2c 100644 --- a/src/Gateways/IuguGateway.php +++ b/src/Gateways/IuguGateway.php @@ -356,6 +356,34 @@ public function refundInvoice(Invoice $invoice): Invoice return $this->parseInvoice($iuguInvoice, $invoice); } + /** + * @inheritDoc + */ + public function duplicateInvoice(Invoice $invoice, Carbon $expiresAt, array $gatewayOptions = []): Invoice + { + $iuguInvoice = new \Iugu_Invoice(['id' => $invoice->id]); + + $params = array_merge($gatewayOptions, [ + 'due_date' => $expiresAt->format('Y-m-d'), + ]); + try { + $iuguInvoice = $iuguInvoice->duplicate($params); + } catch (\IuguRequestException | IuguObjectNotFound $e) { + if (str_contains($e->getMessage(), '502 Bad Gateway')) { + throw new GatewayNotAvailableException($e->getMessage()); + } else { + throw new GatewayException($e->getMessage()); + } + } catch (\Exception $e) { + throw new GatewayException("Error getting invoice: {$e->getMessage()}"); + } + if (!empty($iuguInvoice->errors)) { + throw new GatewayException('Error getting invoice', $iuguInvoice->errors); + } + + return $this->parseInvoice($iuguInvoice); + } + /** * @inheritDoc */ diff --git a/src/Models/Invoice.php b/src/Models/Invoice.php index 697c7fc..93868b3 100644 --- a/src/Models/Invoice.php +++ b/src/Models/Invoice.php @@ -284,4 +284,19 @@ public function chargeInvoiceWithCreditCard(?CreditCard $creditCard = null): Inv return $gateway->chargeInvoiceWithCreditCard($this); } + + /** + * Duplicate the invoice + * + * @param \Carbon\Carbon $expiresAt + * @param array $gatewayOptions + * @return \Potelo\MultiPayment\Models\Invoice + * @throws \Potelo\MultiPayment\Exceptions\ConfigurationException + * @throws \Potelo\MultiPayment\Exceptions\GatewayException + */ + public function duplicate(Carbon $expiresAt, array $gatewayOptions = []): Invoice + { + $gateway = ConfigurationHelper::resolveGateway($this->gateway); + return $gateway->duplicateInvoice($this, $expiresAt, $gatewayOptions); + } } diff --git a/src/MultiPayment.php b/src/MultiPayment.php index 4911ac6..6bfbd9d 100644 --- a/src/MultiPayment.php +++ b/src/MultiPayment.php @@ -2,6 +2,7 @@ namespace Potelo\MultiPayment; +use Carbon\Carbon; use Potelo\MultiPayment\Exceptions\MultiPaymentException; use Potelo\MultiPayment\Models\CreditCard; use Potelo\MultiPayment\Models\Invoice; @@ -106,6 +107,28 @@ public function getInvoice(string $id): Invoice return Invoice::get($id, $this->gateway); } + /** + * Duplicate an invoice + * + * @param \Potelo\MultiPayment\Models\Invoice|string $invoice + * @param \Carbon\Carbon $expiresAt + * @param array $gatewayOptions + * + * @return \Potelo\MultiPayment\Models\Invoice + * @throws \Potelo\MultiPayment\Exceptions\ConfigurationException + * @throws \Potelo\MultiPayment\Exceptions\GatewayException + */ + public function duplicateInvoice(Invoice|string $invoice, Carbon $expiresAt, array $gatewayOptions = []): Invoice + { + if (is_string($invoice)) { + $invoiceInstance = new Invoice(); + $invoiceInstance->id = $invoice; + $invoice = $invoiceInstance; + } + + return $invoice->duplicate($expiresAt, $gatewayOptions); + } + /** * Return an Customer based on the customer ID * diff --git a/tests/Unit/MultiPaymentTest.php b/tests/Unit/MultiPaymentTest.php index 22e0fcd..eb09e95 100644 --- a/tests/Unit/MultiPaymentTest.php +++ b/tests/Unit/MultiPaymentTest.php @@ -31,6 +31,29 @@ public function testShouldGetInvoice() $this->assertEquals($invoiceFetched->id, $invoice->id); } + /** + * Test if can duplicate the invoice + * + * @return void + * @throws \Potelo\MultiPayment\Exceptions\GatewayException + */ + public function testShouldDuplicateInvoice() + { + $gateway = 'iugu'; + $invoice = MultiPayment::setGateway($gateway)->newInvoice() + ->addAvailablePaymentMethod(Invoice::PAYMENT_METHOD_PIX) + ->addCustomer('Fake Customer', 'email@exemplo.com', '20176996915') + ->addItem('teste', 1000, 1) + ->create(); + + $multiPayment = new \Potelo\MultiPayment\MultiPayment($gateway); + $new = $multiPayment->duplicateInvoice($invoice->id, now()->addDays(7)); + $this->assertNotEquals($new->id, $invoice->id); + $this->assertEquals($new->status, Invoice::STATUS_PENDING); + $this->assertTrue($new->expiresAt->isSameDay((now()->addDays(7)))); + + } + /** * Test if thorws an exception when not find the invoice *