mivita/app/Services/Invoice.php
2026-02-20 17:55:06 +01:00

179 lines
5.1 KiB
PHP

<?php
namespace App\Services;
use App\Mail\MailInvoice;
use App\Models\Setting;
use App\Models\ShoppingOrder;
use Illuminate\Support\Facades\Mail;
class Invoice
{
public static function getInvoiceNumber()
{
return (int) Setting::getContentBySlug('invoice-number');
}
/**
* Atomically get and increment the invoice number with database locking
* to prevent race conditions when multiple invoices are created simultaneously
*/
public static function makeNextInvoiceNumber()
{
return \DB::transaction(function () {
// Lock the setting row for update to prevent concurrent reads
$setting = Setting::where('slug', 'invoice-number')
->lockForUpdate()
->first();
if (! $setting) {
// Create if not exists
$setting = Setting::create([
'slug' => 'invoice-number',
'type' => 'int',
'int' => 1,
]);
return 1;
}
$invoice_number = (int) $setting->int;
$invoice_number = $invoice_number + 1;
// Update directly on the locked row
$setting->int = $invoice_number;
$setting->save();
return $invoice_number;
});
}
public static function createInvoiceNumber($invoice_number, $invoice_date)
{
$prefix = \Carbon::parse($invoice_date)->format('Y');
$invoice_number = str_pad($invoice_number, 5, '0', STR_PAD_LEFT);
return $prefix.$invoice_number;
}
public static function getInvoiceStorageDir($invoice_date)
{
return 'invoice/'.\Carbon::parse($invoice_date)->format('Y/m/');
}
public static function getDeliveryStorageDir($invoice_date)
{
return 'delivery/'.\Carbon::parse($invoice_date)->format('Y/m/');
}
public static function makeInvoiceFilename($invoice_number)
{
return $invoice_number.'-MIVITA-Rechnung.pdf';
}
public static function makeDeliveryFilename($invoice_number)
{
return $invoice_number.'-MIVITA-Lieferschein.pdf';
}
/**
* Erstellt den Dateinamen für eine Stornorechnung
*
* @param string $invoice_number
* @return string
*/
public static function makeCancellationFilename($invoice_number)
{
return $invoice_number.'-MIVITA-Stornorechnung.pdf';
}
/**
* Erstellt den Dateinamen für einen Storno-Lieferschein
*
* @param string $invoice_number
* @return string
*/
public static function makeCancellationDeliveryFilename($invoice_number)
{
return $invoice_number.'-MIVITA-Storno-Lieferschein.pdf';
}
/**
* Erstellt den Dateinamen für eine lokalisierte Rechnung.
* Deutsch (de) ist das Original ohne Suffix.
*
* @param string $invoice_number
* @param string $locale
* @return string
*/
public static function makeInvoiceFilenameLocale($invoice_number, $locale)
{
if ($locale === 'de' || ! $locale) {
return self::makeInvoiceFilename($invoice_number);
}
return $invoice_number.'-MIVITA-Rechnung-'.$locale.'.pdf';
}
/**
* Erstellt den Dateinamen für einen lokalisierten Lieferschein.
* Deutsch (de) ist das Original ohne Suffix.
*
* @param string $invoice_number
* @param string $locale
* @return string
*/
public static function makeDeliveryFilenameLocale($invoice_number, $locale)
{
if ($locale === 'de' || ! $locale) {
return self::makeDeliveryFilename($invoice_number);
}
return $invoice_number.'-MIVITA-Lieferschein-'.$locale.'.pdf';
}
public static function isInvoice(ShoppingOrder $shopping_order)
{
return $shopping_order->isInvoice();
}
/**
* Holt die Rechnungsnummer einer Bestellung
*
* @return string|null
*/
public static function getNumber(ShoppingOrder $shopping_order)
{
return $shopping_order->user_invoice ? $shopping_order->user_invoice->full_number : null;
}
/**
* Holt das Rechnungsdatum einer Bestellung
*
* @return string|null
*/
public static function getDate(ShoppingOrder $shopping_order)
{
return $shopping_order->user_invoice ? $shopping_order->user_invoice->date : null;
}
public static function sendInvoiceMail($shopping_order, $user_invoice)
{
$bcc = [];
$billing_email = $shopping_order->shopping_user->billing_email;
if (! $billing_email) {
if ($shopping_order->mode === 'test') {
$billing_email = config('app.checkout_test_mail');
} else {
$billing_email = config('app.checkout_mail');
}
}
if ($shopping_order->mode === 'test') {
$bcc[] = config('app.checkout_test_mail');
} else {
$bcc[] = config('app.checkout_mail');
}
Mail::to($billing_email)->bcc($bcc)->locale($shopping_order->getLocale())->send(new MailInvoice($shopping_order, $user_invoice));
}
}