From 8b8a0357f07a13896dd87cb01a70696c789d0ebb Mon Sep 17 00:00:00 2001 From: Focuslinkstech <45756999+Focuslinkstech@users.noreply.github.com> Date: Tue, 18 Mar 2025 13:08:19 +0100 Subject: [PATCH] Fix custom login page image uploading --- debug_invoice.html | 188 +++++++++++++++++++++++++++++ system/autoload/Invoice.php | 235 ++++++++++++++++++++++++++++++++++++ system/lan/english.json | 3 +- 3 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 debug_invoice.html create mode 100644 system/autoload/Invoice.php diff --git a/debug_invoice.html b/debug_invoice.html new file mode 100644 index 00000000..8d81acc1 --- /dev/null +++ b/debug_invoice.html @@ -0,0 +1,188 @@ + + + + + + Invoice No: INV-284 + + + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + Invoice #: INV-284
+ Created: March 16, 2025
+ Due: March 23, 2025 +
+
+ + + + + + +
+ PHPNuxBill
+ No 2, udo wogu street chevy view estate, Road c17 mercyland, losoro lakowe
+ +2347054020007
+
+ admin
+ admin
+ admin@gmail.com
+ 9006721321
+
+
+ + + + + + + + + + + + + + +
Service + DescriptionPlan Details + Amount
Test PlanMonthly Subscription₦200
+ + +
+

Subtotal: ₦202.00
+ TAX (1%): ₦2.00
+ Total Due: ₦202.00 +

+
+ +
+

Payment Options:

+

Online Portal: pay.phpnuxbill.com
+ Bank Transfer: Account # 1234-567890
+ Auto Pay: Enabled (Next payment: 2023-11-12)

+
+ + +
+ + + \ No newline at end of file diff --git a/system/autoload/Invoice.php b/system/autoload/Invoice.php new file mode 100644 index 00000000..51e54750 --- /dev/null +++ b/system/autoload/Invoice.php @@ -0,0 +1,235 @@ +$template"; + } + + $processedHtml = self::renderTemplate($template, $invoiceData); + + // Debugging: Save processed HTML to file for review + // file_put_contents('debug_invoice.html', $processedHtml); + + // Generate PDF + $mpdf = new Mpdf([ + 'mode' => 'utf-8', + 'format' => 'A4', + 'margin_left' => 10, + 'margin_right' => 10, + 'margin_top' => 10, + 'margin_bottom' => 10, + 'default_font' => 'helvetica', + 'orientation' => 'P', + ]); + + $mpdf->SetDisplayMode('fullpage'); + $mpdf->SetProtection(['print']); + $mpdf->shrink_tables_to_fit = 1; + $mpdf->SetWatermarkText(strtoupper($invoiceData['status'] ?? 'UNPAID'), 0.15); + $mpdf->showWatermarkText = true; + $mpdf->WriteHTML($processedHtml); + + // Save PDF + $filename = "invoice_{$invoiceData['id']}.pdf"; + $outputPath = "system/uploads/invoices/{$filename}"; + $mpdf->Output($outputPath, 'F'); + + if (!file_exists($outputPath)) { + throw new Exception("Failed to save PDF file"); + } + + return $filename; + + } catch (\Exception $e) { + _log("Invoice generation failed: " . $e->getMessage()); + sendTelegram("Invoice generation failed: " . $e->getMessage()); + return false; + } + } + + private static function renderTemplate($template, $invoiceData) + { + return preg_replace_callback('/\[\[(\w+)\]\]/', function ($matches) use ($invoiceData) { + $key = $matches[1]; + if (!isset($invoiceData[$key])) { + _log("Missing invoice key: $key"); + return ''; + } + + if (in_array($key, ['created_at', 'due_date'])) { + return date('F j, Y', strtotime($invoiceData[$key])); + } + + if (in_array($key, ['amount', 'total', 'subtotal', 'tax'])) { + return $invoiceData['currency_code'] . number_format((float) $invoiceData[$key], 2); + } + + if ($key === 'bill_rows') { + return html_entity_decode($invoiceData[$key]); + } + + + return htmlspecialchars($invoiceData[$key] ?? ''); + }, $template); + } + + public static function sendInvoice($userId, $status = "Unpaid") + { + global $config; + + if (empty($config['currency_code'])) { + $config['currency_code'] = '$'; + } + + $account = ORM::for_table('tbl_customers')->find_one($userId); + + if (!$account) { + _log("Failed to send invoice: User not found"); + sendTelegram("Failed to send invoice: User not found"); + return false; + } + + $invoice = ORM::for_table("tbl_transactions")->where("username", $account->username)->find_one(); + + if (!$invoice) { + _log("Failed to send invoice: Transaction not found"); + sendTelegram("Failed to send invoice: Transaction not found"); + return false; + } + + [$additionalBills, $add_cost] = User::getBills($account->id); + + $invoiceItems = [ + [ + 'description' => $invoice->plan_name, + 'details' => 'Monthly Subscription', + 'amount' => (float) $invoice->price + ] + ]; + $subtotal = (float) $invoice->price; + + if ($add_cost > 0 && $invoice->routers != 'balance') { + foreach ($additionalBills as $description => $amount) { + if (is_numeric($amount)) { + $invoiceItems[] = [ + 'description' => $description, + 'details' => 'Additional Bill', + 'amount' => (float) $amount + ]; + $subtotal += (float) $amount; + } else { + _log("Invalid bill amount for {$description}: {$amount}"); + } + } + } + + $tax_rate = (float) ($config['tax_rate'] ?? 0); + $tax = $config['enable_tax'] ? Package::tax($subtotal) : 0; + $total = ($tax > 0) ? $subtotal + $tax : $subtotal + $tax; + + $invoiceData = [ + 'id' => "INV-" . Package::_raid(), + 'fullname' => $account->fullname, + 'email' => $account->email, + 'address' => $account->address, + 'phone' => $account->phonenumber, + 'bill_rows' => self::generateBillRows($invoiceItems, $config['currency_code'], $subtotal, $tax_rate, $tax, $total), + 'status' => $status, + 'created_at' => date('Y-m-d H:i:s'), + 'due_date' => date('Y-m-d H:i:s', strtotime('+7 days')), + 'currency' => $config['currency_code'], + 'company_address' => $config['address'], + 'company_name' => $config['CompanyName'], + 'company_phone' => $config['phone'], + 'logo' => $config['logo'], + ]; + + if (!isset($invoiceData['bill_rows']) || empty($invoiceData['bill_rows'])) { + _log("Invoice Error: Bill rows data is empty."); + } + + $filename = self::generateInvoice($invoiceData); + + if ($filename) { + $pdfPath = "system/uploads/invoices/{$filename}"; + + try { + Message::sendEmail( + $account->email, + "Invoice for Account {$account->fullname}", + "Please find your invoice attached", + $pdfPath + ); + return true; + } catch (\Exception $e) { + _log("Failed to send invoice email: " . $e->getMessage()); + sendTelegram("Failed to send invoice email: " . $e->getMessage()); + return false; + } + } + + return false; + } + + private static function generateBillRows($items, $currency, $subtotal, $tax_rate, $tax, $total) + { + $html = " + + + + + + + + "; + + foreach ($items as $item) { + $html .= " + + + + "; + } + + $html .= " + + + + + + + + + + + "; + + $html .= "
DescriptionDetailsAmount
{$item['description']}{$item['details']}{$currency}" . number_format((float) $item['amount'], 2) . "
Subtotal:{$currency}" . number_format($subtotal, 2) . "
TAX ({$tax_rate}%):{$currency}" . number_format($tax, 2) . "
Total:{$currency}" . number_format($total, 2) . "
"; + + return $html; + } + + + +} diff --git a/system/lan/english.json b/system/lan/english.json index 7dbb534a..0ea29526 100644 --- a/system/lan/english.json +++ b/system/lan/english.json @@ -1148,5 +1148,6 @@ "Continue_the_process_of_sending_messages": "Continue the process of sending messages", "Yours_Balances": "Yours Balances", "Friend_username": "Friend username", - "This_will_sync_dan_send_Customer_active_package_to_Mikrotik": "This will sync dan send Customer active package to Mikrotik" + "This_will_sync_dan_send_Customer_active_package_to_Mikrotik": "This will sync dan send Customer active package to Mikrotik", + "Email_not_sent__Mailer_Error__": "Email not sent, Mailer Error: " } \ No newline at end of file