1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00
invoiceninja/app/Helpers/SwissQr/SwissQrGenerator.php

218 lines
6.8 KiB
PHP
Raw Normal View History

2022-06-30 06:37:08 +02:00
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
2023-01-28 23:21:40 +01:00
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
2022-06-30 06:37:08 +02:00
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Helpers\SwissQr;
2022-06-30 08:09:06 +02:00
use App\Models\Client;
2022-06-30 06:37:08 +02:00
use App\Models\Company;
use App\Models\Invoice;
use Sprain\SwissQrBill as QrBill;
/**
* SwissQrGenerator.
*/
class SwissQrGenerator
2022-06-30 06:37:08 +02:00
{
protected Company $company;
2022-06-30 12:12:23 +02:00
protected $invoice;
2022-06-30 06:37:08 +02:00
2022-06-30 08:09:06 +02:00
protected Client $client;
2022-06-30 12:12:23 +02:00
public function __construct($invoice, Company $company)
2022-06-30 06:37:08 +02:00
{
$this->company = $company;
$this->invoice = $invoice;
2022-06-30 08:09:06 +02:00
$this->client = $invoice->client;
}
private function calcDueAmount()
{
2023-02-16 02:36:09 +01:00
if ($this->invoice->partial > 0) {
2022-06-30 08:09:06 +02:00
return $this->invoice->partial;
2023-02-16 02:36:09 +01:00
}
2022-06-30 08:09:06 +02:00
2023-02-16 02:36:09 +01:00
if ($this->invoice->status_id == Invoice::STATUS_DRAFT) {
2022-06-30 08:09:06 +02:00
return $this->invoice->amount;
2023-02-16 02:36:09 +01:00
}
2022-06-30 08:09:06 +02:00
return $this->invoice->balance;
2022-06-30 06:37:08 +02:00
}
public function run()
{
2023-02-16 02:36:09 +01:00
// This is an example how to create a typical qr bill:
// - with reference number
// - with known debtor
// - with specified amount
// - with human-readable additional information
// - using your QR-IBAN
2023-10-26 04:57:44 +02:00
//
2023-02-16 02:36:09 +01:00
// Likely the most common use-case in the business world.
2022-06-30 06:37:08 +02:00
2023-02-16 02:36:09 +01:00
// Create a new instance of QrBill, containing default headers with fixed values
$qrBill = QrBill\QrBill::create();
2022-06-30 06:37:08 +02:00
2023-02-16 02:36:09 +01:00
// Add creditor information
// Who will receive the payment and to which bank account?
$qrBill->setCreditor(
QrBill\DataGroup\Element\CombinedAddress::create(
$this->company->present()->name(),
$this->company->present()->address1(),
$this->company->present()->getCompanyCityState(),
'CH'
)
);
2022-06-30 06:37:08 +02:00
2023-02-16 02:36:09 +01:00
$qrBill->setCreditorInformation(
QrBill\DataGroup\Element\CreditorInformation::create(
$this->company->present()->qr_iban() ?: '' // This is a special QR-IBAN. Classic IBANs will not be valid here.
)
);
2022-06-30 06:37:08 +02:00
2023-02-16 02:36:09 +01:00
// Add debtor information
// Who has to pay the invoice? This part is optional.
2023-10-26 04:57:44 +02:00
//
2023-02-16 02:36:09 +01:00
// Notice how you can use two different styles of addresses: CombinedAddress or StructuredAddress
// They are interchangeable for creditor as well as debtor.
$qrBill->setUltimateDebtor(
QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
substr($this->client->present()->name(), 0, 70),
$this->client->address1 ? substr($this->client->address1, 0, 70) : ' ',
$this->client->address2 ? substr($this->client->address2, 0, 16) : ' ',
$this->client->postal_code ? substr($this->client->postal_code, 0, 16) : ' ',
$this->client->city ? substr($this->client->city, 0, 35) : ' ',
'CH'
)
);
// Add payment amount information
// What amount is to be paid?
$qrBill->setPaymentAmountInformation(
QrBill\DataGroup\Element\PaymentAmountInformation::create(
'CHF',
$this->calcDueAmount()
)
);
// Add payment reference
// This is what you will need to identify incoming payments.
2024-01-14 05:05:00 +01:00
2023-02-16 02:36:09 +01:00
if (stripos($this->invoice->number, "Live") === 0) {
// we're currently in preview status. Let's give a dummy reference for now
$invoice_number = "123456789";
} else {
$tempInvoiceNumber = $this->invoice->number;
$tempInvoiceNumber = preg_replace('/[^A-Za-z0-9]/', '', $tempInvoiceNumber);
// $tempInvoiceNumber = substr($tempInvoiceNumber, 1);
2024-01-14 05:05:00 +01:00
2023-02-16 02:36:09 +01:00
$calcInvoiceNumber = "";
$array = str_split($tempInvoiceNumber);
foreach ($array as $char) {
if (is_numeric($char)) {
2023-10-26 04:57:44 +02:00
//
2023-02-16 02:36:09 +01:00
} else {
if ($char) {
$char = strtolower($char);
$char = ord($char) - 96;
} else {
return 0;
}
}
$calcInvoiceNumber .= $char;
}
2024-01-14 05:05:00 +01:00
2023-02-16 02:36:09 +01:00
$invoice_number = $calcInvoiceNumber;
}
2022-06-30 06:37:08 +02:00
2023-02-16 02:36:09 +01:00
if (strlen($this->company->present()->besr_id()) > 1) {
$referenceNumber = QrBill\Reference\QrPaymentReferenceGenerator::generate(
$this->company->present()->besr_id() ?: '', // You receive this number from your bank (BESR-ID). Unless your bank is PostFinance, in that case use NULL.
$invoice_number// A number to match the payment with your internal data, e.g. an invoice number
);
$qrBill->setPaymentReference(
QrBill\DataGroup\Element\PaymentReference::create(
QrBill\DataGroup\Element\PaymentReference::TYPE_QR,
$referenceNumber
)
);
} else {
$qrBill->setPaymentReference(
QrBill\DataGroup\Element\PaymentReference::create(
QrBill\DataGroup\Element\PaymentReference::TYPE_NON
)
);
}
2023-02-16 02:36:09 +01:00
// Optionally, add some human-readable information about what the bill is for.
$qrBill->setAdditionalInformation(
QrBill\DataGroup\Element\AdditionalInformation::create(
$this->invoice->public_notes ? substr($this->invoice->public_notes, 0, 139) : ctrans('texts.invoice_number_placeholder', ['invoice' => $this->invoice->number])
)
);
2022-06-30 06:37:08 +02:00
2023-02-16 02:36:09 +01:00
// Now get the QR code image and save it as a file.
2022-06-30 12:12:23 +02:00
try {
2023-11-01 02:14:58 +01:00
$output = new QrBill\PaymentPart\Output\HtmlOutput\HtmlOutput($qrBill, $this->resolveLanguage());
2022-06-30 12:12:23 +02:00
$html = $output
->setPrintable(false)
->getPaymentPart();
2023-02-16 02:36:09 +01:00
return $html;
2022-06-30 12:12:23 +02:00
} catch (\Exception $e) {
2023-10-18 11:03:26 +02:00
if(is_iterable($qrBill->getViolations())) {
2024-01-14 05:05:00 +01:00
2023-10-18 11:03:26 +02:00
foreach ($qrBill->getViolations() as $key => $violation) {
nlog("qr");
nlog($violation);
}
2022-06-30 12:12:23 +02:00
}
2022-06-30 06:37:08 +02:00
nlog($e->getMessage());
2024-01-14 05:05:00 +01:00
2022-06-30 12:12:23 +02:00
return '';
// return $e->getMessage();
}
2022-06-30 06:37:08 +02:00
}
2023-11-01 02:14:58 +01:00
private function resolveLanguage(): string
{
$language = $this->client->locale() ?: 'en';
switch ($language) {
case 'de':
return 'de';
case 'en':
case 'en_GB':
return 'en';
case 'it':
return 'it';
case 'fr':
case 'fr_CA':
case 'fr_CH':
return 'fr';
2024-01-14 05:05:00 +01:00
2023-11-01 02:14:58 +01:00
default:
return 'en';
}
}
2022-10-03 22:55:07 +02:00
}