Swiss QR Codes

This commit is contained in:
David Bomba 2022-06-30 16:09:06 +10:00
parent da66fa6271
commit f0c7f4588c
4 changed files with 45 additions and 25 deletions

View File

@ -25,7 +25,8 @@ class CompanySettings extends BaseSettings
/*Invoice*/ /*Invoice*/
public $auto_archive_invoice = false; // @implemented public $auto_archive_invoice = false; // @implemented
public $qr_iban = ''; public $qr_iban = ''; //@implemented
public $besr_id = ''; //@implemented
public $lock_invoices = 'off'; //off,when_sent,when_paid //@implemented public $lock_invoices = 'off'; //off,when_sent,when_paid //@implemented
@ -291,6 +292,7 @@ class CompanySettings extends BaseSettings
public $auto_archive_invoice_cancelled = false; public $auto_archive_invoice_cancelled = false;
public static $casts = [ public static $casts = [
'besr_id' => 'string',
'qr_iban' => 'string', 'qr_iban' => 'string',
'email_subject_purchase_order' => 'string', 'email_subject_purchase_order' => 'string',
'email_template_purchase_order' => 'string', 'email_template_purchase_order' => 'string',

View File

@ -11,6 +11,7 @@
namespace App\Helpers\SwissQr; namespace App\Helpers\SwissQr;
use App\Models\Client;
use App\Models\Company; use App\Models\Company;
use App\Models\Invoice; use App\Models\Invoice;
use Sprain\SwissQrBill as QrBill; use Sprain\SwissQrBill as QrBill;
@ -25,11 +26,26 @@ class SwissQrGenerator
protected Invoice $invoice; protected Invoice $invoice;
protected Client $client;
public function __construct(Invoice $invoice, Company $company) public function __construct(Invoice $invoice, Company $company)
{ {
$this->company = $company; $this->company = $company;
$this->invoice = $invoice; $this->invoice = $invoice;
$this->client = $invoice->client;
}
private function calcDueAmount()
{
if($this->invoice->partial > 0)
return $this->invoice->partial;
if($this->invoice->status_id == Invoice::STATUS_DRAFT)
return $this->invoice->amount;
return $this->invoice->balance;
} }
public function run() public function run()
@ -45,7 +61,7 @@ class SwissQrGenerator
// Likely the most common use-case in the business world. // Likely the most common use-case in the business world.
// Create a new instance of QrBill, containing default headers with fixed values // Create a new instance of QrBill, containing default headers with fixed values
$qrBill = \QrBill\QrBill::create(); $qrBill = QrBill\QrBill::create();
// Add creditor information // Add creditor information
@ -60,21 +76,21 @@ class SwissQrGenerator
$qrBill->setCreditorInformation( $qrBill->setCreditorInformation(
QrBill\DataGroup\Element\CreditorInformation::create( QrBill\DataGroup\Element\CreditorInformation::create(
$this->company->present()->qr_iban() // This is a special QR-IBAN. Classic IBANs will not be valid here. $this->company->present()->qr_iban() ?: '' // This is a special QR-IBAN. Classic IBANs will not be valid here.
)); ));
// Add debtor information // Add debtor information
// Who has to pay the invoice? This part is optional. // Who has to pay the invoice? This part is optional.
// //
// Notice how you can use two different styles of addresses: CombinedAddress or StructuredAddress. // Notice how you can use two different styles of addresses: CombinedAddress or StructuredAddress
// They are interchangeable for creditor as well as debtor. // They are interchangeable for creditor as well as debtor.
$qrBill->setUltimateDebtor( $qrBill->setUltimateDebtor(
QrBill\DataGroup\Element\StructuredAddress::createWithStreet( QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
'Pia-Maria Rutschmann-Schnyder', $this->client->present()->name(),
'Grosse Marktgasse', $this->client->address1 ?: '',
'28', $this->client->address2 ?: '',
'9400', $this->client->postal_code ?: '',
'Rorschach', $this->client->city ?: '',
'CH' 'CH'
)); ));
@ -83,14 +99,14 @@ class SwissQrGenerator
$qrBill->setPaymentAmountInformation( $qrBill->setPaymentAmountInformation(
QrBill\DataGroup\Element\PaymentAmountInformation::create( QrBill\DataGroup\Element\PaymentAmountInformation::create(
'CHF', 'CHF',
2500.25 $this->calcDueAmount()
)); ));
// Add payment reference // Add payment reference
// This is what you will need to identify incoming payments. // This is what you will need to identify incoming payments.
$referenceNumber = QrBill\Reference\QrPaymentReferenceGenerator::generate( $referenceNumber = QrBill\Reference\QrPaymentReferenceGenerator::generate(
'210000', // You receive this number from your bank (BESR-ID). Unless your bank is PostFinance, in that case use NULL. $this->company->present()->besr_id() ?: '', // You receive this number from your bank (BESR-ID). Unless your bank is PostFinance, in that case use NULL.
'313947143000901' // A number to match the payment with your internal data, e.g. an invoice number $this->invoice->number // A number to match the payment with your internal data, e.g. an invoice number
); );
$qrBill->setPaymentReference( $qrBill->setPaymentReference(
@ -102,19 +118,20 @@ class SwissQrGenerator
// Optionally, add some human-readable information about what the bill is for. // Optionally, add some human-readable information about what the bill is for.
$qrBill->setAdditionalInformation( $qrBill->setAdditionalInformation(
QrBill\DataGroup\Element\AdditionalInformation::create( QrBill\DataGroup\Element\AdditionalInformation::create(
'Invoice 123456, Gardening work' $this->invoice->public_notes ?: ''
) )
); );
// Now get the QR code image and save it as a file. // Now get the QR code image and save it as a file.
try { try {
$qrBill->getQrCode()->writeFile(__DIR__ . '/qr.png'); // $qrBill->getQrCode()->writeFile(__DIR__ . '/qr.png');
$qrBill->getQrCode()->writeFile(__DIR__ . '/qr.svg'); // $qrBill->getQrCode()->writeFile(__DIR__ . '/qr.svg');
} catch (Exception $e) { } catch (\Exception $e) {
foreach($qrBill->getViolations() as $violation) { foreach($qrBill->getViolations() as $key => $violation) {
print $violation->getMessage()."\n";
} }
exit;
// return $e->getMessage();
} }
$output = new QrBill\PaymentPart\Output\HtmlOutput\HtmlOutput($qrBill, 'en'); $output = new QrBill\PaymentPart\Output\HtmlOutput\HtmlOutput($qrBill, 'en');
@ -123,11 +140,7 @@ class SwissQrGenerator
->setPrintable(false) ->setPrintable(false)
->getPaymentPart(); ->getPaymentPart();
// Next: Output full payment parts, depending on the format you want to use: return $html;
//
// - FpdfOutput/fpdf-example.php
// - HtmlOutput/html-example.php
// - TcPdfOutput/tcpdf-example.php
} }
} }

View File

@ -141,6 +141,11 @@ class CompanyPresenter extends EntityPresenter
return $this->entity->getSetting('qr_iban'); return $this->entity->getSetting('qr_iban');
} }
public function besr_id()
{
return $this->entity->getSetting('besr_id');
}
public function getSpcQrCode($client_currency, $invoice_number, $balance_due_raw, $user_iban) public function getSpcQrCode($client_currency, $invoice_number, $balance_due_raw, $user_iban)
{ {
$settings = $this->entity->settings; $settings = $this->entity->settings;

2
composer.lock generated
View File

@ -16554,5 +16554,5 @@
"platform-dev": { "platform-dev": {
"php": "^7.4|^8.0" "php": "^7.4|^8.0"
}, },
"plugin-api-version": "2.1.0" "plugin-api-version": "2.3.0"
} }