gitea init
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// ინვოისის ნომრის გენერაცია
|
||||
$generatedInvoiceNumber = InvoicesModel::generateNextInvoiceNumber();
|
||||
|
||||
// კლიენტების სია dropdown-სთვის
|
||||
$clients = InvoicesModel::getClientsList();
|
||||
|
||||
// პროდუქტების სია
|
||||
$products = InvoicesModel::getProductList();
|
||||
|
||||
require_once __DIR__ . '/../../views/invoices/create.php';
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
// კონტროლერი: ინვოისის წაშლა
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
// ბაზასთან დაკავშირება
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// GET ID გადამოწმება
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
exit('არასწორი ID.');
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
|
||||
// წაშლა
|
||||
InvoicesModel::deleteInvoice($id);
|
||||
|
||||
// გადამისამართება ინვოისების სიაზე
|
||||
|
||||
require_once __DIR__ . '/../../views/invoices/list.php';
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// 📄 რედაქტირება
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// ID შემოწმება
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
exit('არასწორი ID.');
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
|
||||
// ინვოისის წამოღება
|
||||
$invoice = InvoicesModel::getInvoiceById($id);
|
||||
if (!$invoice) {
|
||||
exit('ინვოისი ვერ მოიძებნა.');
|
||||
}
|
||||
|
||||
// სელექტისთვის საჭირო მონაცემები
|
||||
$clients = InvoicesModel::getClientsList();
|
||||
$products = InvoicesModel::getProductList();
|
||||
|
||||
// ვიუ ჩატვირთვა
|
||||
require_once __DIR__ . '/../../views/invoices/edit.php';
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
// 📄 ინვოისის PDF გენერაცია - Controller
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../vendor/autoload.php';
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
use App\Config;
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// 🧾 ინვოისის ID გადმოსვლა GET-ით
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
exit('არასწორი ID');
|
||||
}
|
||||
|
||||
$id = (int)$_GET['id'];
|
||||
|
||||
// 🧾 ინვოისის მონაცემების წამოღება
|
||||
$invoice = InvoicesModel::getInvoiceById($id);
|
||||
if (!$invoice) {
|
||||
exit('ინვოისი ვერ მოიძებნა.');
|
||||
}
|
||||
|
||||
$client_name = $invoice['first_name'] . ' ' . $invoice['last_name'];
|
||||
|
||||
// 📄 PDF კონფიგურაცია
|
||||
$options = new Options();
|
||||
$options->set('isHtml5ParserEnabled', true);
|
||||
$options->set('isRemoteEnabled', true);
|
||||
|
||||
$dompdf = new Dompdf($options);
|
||||
|
||||
// 📄 შაბლონის HTML ჩატვირთვა
|
||||
ob_start();
|
||||
require_once realpath(Config::basePath() . '/admin/modules/billing/models/invoices/invoice_template.php');
|
||||
$html = ob_get_clean();
|
||||
|
||||
$dompdf->loadHtml($html, 'UTF-8');
|
||||
$dompdf->setPaper('A4', 'portrait');
|
||||
$dompdf->render();
|
||||
|
||||
// 📄 PDF-ის შენახვა დროებით
|
||||
$pdfOutput = $dompdf->output();
|
||||
$pdfPath = '/tmp/invoice_' . $invoice['id'] . '.pdf';
|
||||
file_put_contents($pdfPath, $pdfOutput);
|
||||
|
||||
// გადამისამართება ან ჩამოტვირთვა შეგიძლიათ დაამატოთ აქ
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
// ვუკავშირებთ ბაზას მოდელს
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// ინვოისების წამოღება
|
||||
$invoices = InvoicesModel::getAllInvoices();
|
||||
|
||||
// ვიუს ჩატვირთვა
|
||||
require_once __DIR__ . '/../../views/invoices/list.php';
|
||||
@@ -0,0 +1,104 @@
|
||||
<!-- გაგზავნის ლოგიკა -->
|
||||
<?php
|
||||
|
||||
// ინვოისის გაგზავნა ელფოსტაზე PDF-ით
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../../../../libs/phpmailer/src/PHPMailer.php';
|
||||
require_once __DIR__ . '/../../../../libs/phpmailer/src/SMTP.php';
|
||||
require_once __DIR__ . '/../../../../libs/phpmailer/src/Exception.php';
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// use Dompdf\Dompdf;
|
||||
|
||||
// use Dompdf\Options;
|
||||
|
||||
// $options = new Options();
|
||||
// $options->set('isRemoteEnabled', true);
|
||||
|
||||
// // ️➡️ უთხარი Dompdf-ს სად არის შენი შრიფტი
|
||||
// $options->setChroot(__DIR__ . '/../../'); // აქედან იმუშავებს relative path-ებით
|
||||
// $options->set('defaultFont', 'bpg_glaho');
|
||||
|
||||
// $dompdf = new Dompdf($options);
|
||||
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// 1. აიდი
|
||||
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||
if (!$id) {
|
||||
exit("არასწორი ინვოისის ID.");
|
||||
}
|
||||
|
||||
// 2. მოიტანე ინვოისი და ნივთები
|
||||
$invoice = InvoicesModel::getInvoiceWithItems($id);
|
||||
if (!$invoice) {
|
||||
exit("ინვოისი ვერ მოიძებნა.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 3. გენერაცია PDF ფაილის
|
||||
$pdfPath = InvoicesModel::generateInvoicePDF($invoice);
|
||||
|
||||
// Email გაგზავნა
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
try {
|
||||
$mail->isSMTP();
|
||||
$mail->Host = 'vps-7146dd3a.vps.ovh.ca'; // შეცვალე
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = 'noreply@selfhosting.ge'; // შეცვალე
|
||||
$mail->Password = 'FSZtTIIIlubk'; // შეცვალე
|
||||
$mail->SMTPSecure = 'ssl'; // ან ssl
|
||||
$mail->Port = 465; // ან 465
|
||||
|
||||
$mail->setFrom('noreply@selfhosting.ge', 'ბილინგ სერვისი');
|
||||
$mail->addAddress($invoice['email'], $invoice['first_name'] . ' ' . $invoice['last_name']);
|
||||
|
||||
$mail->CharSet = 'UTF-8'; // ✅ ეს არის მთავარი!
|
||||
$mail->Encoding = 'base64'; // ხშირად დაეხმარება UTF-8-ის სწორ გადაცემას
|
||||
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = "ინვოისი #" . $invoice['invoice_number'];
|
||||
$mail->Body = "
|
||||
გამარჯობა {$invoice['first_name']},<br><br>
|
||||
თქვენთვის შემუშავებულია ახალი ინვოისი ჯამური თანხით <strong>{$invoice['total_amount']} ₾</strong>.<br>
|
||||
გადახდის ვადა: {$invoice['due_date']}<br><br>
|
||||
იხილეთ დეტალურად: ინვოისის სანახავად იხილეთ მიმაგრებული ფაილი<br><br>
|
||||
მადლობა თანამშრომლობისთვის.
|
||||
";
|
||||
|
||||
$invoice = InvoicesModel::getInvoiceWithClientById($id);
|
||||
|
||||
$invoice['company_name'] = $invoice['client_company_name'];
|
||||
$invoice['vat_number'] = $invoice['client_vat_number'];
|
||||
$invoice['address1'] = $invoice['client_address1'];
|
||||
$client_name = $invoice['first_name'] . ' ' . $invoice['last_name'];
|
||||
// ინვოისის HTML
|
||||
$html = InvoicesModel::renderInvoiceHTML($invoice);
|
||||
|
||||
|
||||
$mail->addAttachment($pdfPath, 'Invoice_' . $invoice['invoice_number'] . '.pdf');
|
||||
$mail->send();
|
||||
|
||||
// ✅ წარმატებული გაგზავნის შემდეგ
|
||||
header("Location: dashboard.php?module=billing&submodule=invoices&action=view&id={$invoice['id']}&sent=1");
|
||||
exit;
|
||||
} catch (Exception $e) {
|
||||
echo "შეცდომა გაგზავნისას: {$mail->ErrorInfo}";
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// 📬 გადახდის შეხსენების გაგზავნა
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require '../../libs/phpmailer/src/PHPMailer.php';
|
||||
require '../../libs/phpmailer/src/SMTP.php';
|
||||
require '../../libs/phpmailer/src/Exception.php';
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
try {
|
||||
// SMTP პარამეტრები
|
||||
$mail->isSMTP();
|
||||
$mail->Host = 'vps-7146dd3a.vps.ovh.ca';
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = 'levan@arabuli.info';
|
||||
$mail->Password = 'Aqsxcs@1211';
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
$mail->Port = 465;
|
||||
|
||||
$clientName = $invoice['first_name'] . ' ' . $invoice['last_name'];
|
||||
|
||||
$mail->setFrom('levan@arabuli.info', 'Billing System');
|
||||
$mail->addAddress($invoice['email'], $clientName);
|
||||
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = "გადახდის შეხსენება ინვოისზე #{$invoice['invoice_number']}";
|
||||
$mail->Body = "
|
||||
გამარჯობა {$clientName},<br><br>
|
||||
გთხოვთ გადაიხადოთ ინვოისი #{$invoice['invoice_number']} <strong>{$invoice['total_amount']} ₾</strong><br>
|
||||
გადახდის ბოლო ვადაა: <strong>{$invoice['due_date']}</strong><br><br>
|
||||
იხილეთ ინვოისი: <a href='https://yourdomain.com/dashboard.php?module=billing&submodule=invoices&action=view&id={$invoice['id']}'>იხილეთ ინვოისი</a>
|
||||
";
|
||||
|
||||
$mail->send();
|
||||
echo "✅ შეხსენება გაიგზავნა {$clientName} ({$invoice['email']})<br>";
|
||||
} catch (Exception $e) {
|
||||
echo "❌ შეცდომა: {$mail->ErrorInfo}<br>";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// POST მონაცემების დამუშავება
|
||||
$data = $_POST;
|
||||
$data['recurring'] = isset($data['recurring']) ? 1 : 0;
|
||||
|
||||
// სტატუსის ვალიდაცია
|
||||
if (!InvoicesModel::isValidStatus($data['status'])) {
|
||||
die('არასწორი სტატუსის მნიშვნელობა');
|
||||
}
|
||||
|
||||
// 🔢 ინვოისის ნომრის გენერაცია
|
||||
if (empty($data['invoice_number'])) {
|
||||
$data['invoice_number'] = InvoicesModel::generateInvoiceNumber();
|
||||
}
|
||||
|
||||
|
||||
// დუბლიკატის შემოწმება
|
||||
if (InvoicesModel::isDuplicateInvoiceNumber($data['invoice_number'])) {
|
||||
die('ინვოისის ნომერი უკვე გამოიყენება!');
|
||||
}
|
||||
|
||||
// ჩასმა მოდელის მეშვეობით
|
||||
$invoice_id = InvoicesModel::createInvoiceWithItems($data);
|
||||
|
||||
// გადამისამართება
|
||||
header("Location: dashboard.php?module=billing&submodule=invoices&action=view&id=" . $invoice_id);
|
||||
exit;
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// ⚙️ ინვოისის განახლება
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// 📨 მონაცემების მიღება
|
||||
if (!isset($_POST['id']) || !is_numeric($_POST['id'])) {
|
||||
exit('არასწორი ID.');
|
||||
}
|
||||
|
||||
$id = (int)$_POST['id'];
|
||||
$data = $_POST;
|
||||
|
||||
// ინვოისის განახლება
|
||||
InvoicesModel::updateInvoice($id, $data);
|
||||
|
||||
// ↪️ გადამისამართება
|
||||
header("Location: dashboard.php?module=billing&submodule=invoices&action=view&id=$id");
|
||||
exit;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
// ბაზასთან დაკავშირება
|
||||
InvoicesModel::setDb($pdo);
|
||||
|
||||
// ID შემოწმება
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo "არასწორი ID.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = (int) $_GET['id'];
|
||||
$showAlert = isset($_GET['sent']) && $_GET['sent'] == 1;
|
||||
|
||||
// ინვოისის წამოღება
|
||||
$invoice = InvoicesModel::getInvoiceWithClient($id);
|
||||
|
||||
if (!$invoice) {
|
||||
echo "ინვოისი ვერ მოიძებნა.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// პროდუქტის items
|
||||
$productItems = InvoicesModel::getInvoiceItems($id);
|
||||
|
||||
// ვიუ ფაილის ჩატვირთვა
|
||||
require_once __DIR__ . '/../../views/invoices/view.php';
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
|
||||
TransactionsModel::setDb($pdo);
|
||||
|
||||
// მომხმარებლები და ინვოისები ფორმის select-ებისთვის
|
||||
$clients = TransactionsModel::getClients();
|
||||
$invoices = TransactionsModel::getInvoices();
|
||||
|
||||
// POST დამუშავება
|
||||
$errors = TransactionsModel::handleTransactionFormSubmission();
|
||||
|
||||
|
||||
require_once __DIR__ . '/../../views/transactions/create.php';
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
TransactionsModel::setDb($pdo);
|
||||
|
||||
// ID გადმოსვლის შემოწმება
|
||||
$id = $_GET['id'] ?? null;
|
||||
|
||||
if (!$id || !is_numeric($id)) {
|
||||
exit('არასწორი ID.');
|
||||
}
|
||||
|
||||
// წაშლის მცდელობა
|
||||
TransactionsModel::deleteTransaction((int)$id);
|
||||
|
||||
// გადამისამართება
|
||||
header('Location: dashboard.php?module=billing&submodule=transactions&action=list&deleted=1');
|
||||
exit;
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
|
||||
TransactionsModel::setDb($pdo);
|
||||
|
||||
$id = $_GET['id'] ?? null;
|
||||
|
||||
$transaction = TransactionsModel::getTransactionById($id);
|
||||
|
||||
if (!$transaction) {
|
||||
echo "ტრანზაქცია ვერ მოიძებნა.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// შენახვა
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$data = [
|
||||
'status' => $_POST['status'],
|
||||
'method' => $_POST['method'],
|
||||
'notes' => $_POST['notes'],
|
||||
];
|
||||
|
||||
TransactionsModel::updateTransaction($id, $data);
|
||||
|
||||
header("Location: dashboard.php?module=billing&submodule=transactions&action=list&updated=1");
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../../views/transactions/edit.php';
|
||||
@@ -0,0 +1,25 @@
|
||||
<!-- გადახდების ისტორია -->
|
||||
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
|
||||
TransactionsModel::setDb($pdo);
|
||||
|
||||
$clientId = $_GET['client_id'] ?? null;
|
||||
|
||||
$client = TransactionsModel::getClientInfo($clientId);
|
||||
if (!$client) {
|
||||
echo "კლიენტი ვერ მოიძებნა.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$transactions = TransactionsModel::getClientTransactions($clientId);
|
||||
|
||||
require_once __DIR__ . '/../../views/transactions/history.php';
|
||||
@@ -0,0 +1,29 @@
|
||||
<!-- ტრანზაქციების სია -->
|
||||
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../../../includes/init.php';
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
require_once __DIR__ . '/../../../../../vendor/autoload.php';
|
||||
|
||||
|
||||
// წაკითხვა GET-პარამეტრებიდან
|
||||
$successMessage = null;
|
||||
|
||||
if (isset($_GET['added']) && $_GET['added'] == 1) {
|
||||
$successMessage = "ტრანზაქცია წარმატებით დაემატა.";
|
||||
} elseif (isset($_GET['updated']) && $_GET['updated'] == 1) {
|
||||
$successMessage = "ტრანზაქცია წარმატებით განახლდა.";
|
||||
} elseif (isset($_GET['deleted']) && $_GET['deleted'] == 1) {
|
||||
$successMessage = "ტრანზაქცია წარმატებით წაიშალა.";
|
||||
}
|
||||
|
||||
TransactionsModel::setDb($pdo);
|
||||
|
||||
$transactions = TransactionsModel::getAllTransactions();
|
||||
|
||||
require_once __DIR__ . '/../../views/transactions/list.php';
|
||||
@@ -0,0 +1 @@
|
||||
<!-- გენერირება, გამოთვლები -->
|
||||
@@ -0,0 +1,2 @@
|
||||
<!-- გენერირება, გამოთვლები -->
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
class InvoicesModel
|
||||
{
|
||||
protected static $db;
|
||||
|
||||
public static function setDb($pdo)
|
||||
{
|
||||
self::$db = $pdo;
|
||||
}
|
||||
|
||||
// ყველა ინვოისის წამოღება
|
||||
public static function getAllInvoicesWithClientNames()
|
||||
{
|
||||
$stmt = self::$db->query("
|
||||
SELECT i.*, CONCAT(c.first_name, ' ', c.last_name) AS client_name
|
||||
FROM invoices i
|
||||
JOIN clients c ON i.client_id = c.id
|
||||
ORDER BY i.id DESC
|
||||
");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
// ყველა ინვოისის წამოღება
|
||||
public static function getAllInvoices()
|
||||
{
|
||||
$stmt = self::$db->query("SELECT i.*, c.first_name, c.last_name FROM invoices i JOIN clients c ON i.client_id = c.id ORDER BY i.id DESC");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
// ერთი ინვოისის წამოღება დეტალურად
|
||||
public static function getInvoiceById($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT * FROM invoices WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
// ინვოისის დამატება
|
||||
public static function createInvoice($data)
|
||||
{
|
||||
$stmt = self::$db->prepare("INSERT INTO invoices (invoice_number, client_id, description, payment_method, status, total_amount, is_recurring, issue_date, due_date, payment_date, recurring) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
$stmt->execute([
|
||||
$data['invoice_number'],
|
||||
$data['client_id'],
|
||||
$data['description'],
|
||||
$data['payment_method'],
|
||||
$data['status'],
|
||||
$data['total_amount'],
|
||||
$data['is_recurring'],
|
||||
$data['issue_date'],
|
||||
$data['due_date'],
|
||||
$data['payment_date'],
|
||||
$data['recurring']
|
||||
]);
|
||||
|
||||
return self::$db->lastInsertId();
|
||||
}
|
||||
|
||||
// ინვოისის განახლება
|
||||
public static function updateInvoice($id, $data)
|
||||
{
|
||||
$stmt = self::$db->prepare("UPDATE invoices SET
|
||||
client_id = ?, invoice_number = ?, description = ?, status = ?,
|
||||
total_amount = ?, payment_method = ?, issue_date = ?, due_date = ?, recurring = ?
|
||||
WHERE id = ?");
|
||||
|
||||
return $stmt->execute([
|
||||
$data['client_id'],
|
||||
$data['invoice_number'],
|
||||
$data['description'],
|
||||
$data['status'],
|
||||
$data['total_amount'],
|
||||
$data['payment_method'],
|
||||
$data['issue_date'],
|
||||
$data['due_date'],
|
||||
isset($data['recurring']) ? 1 : 0,
|
||||
$id
|
||||
]);
|
||||
}
|
||||
|
||||
// ინვოისის წაშლა
|
||||
public static function deleteInvoice($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("DELETE FROM invoices WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
// ინვოისთან დაკავშირებული ნივთების წამოღება
|
||||
public static function getInvoiceItems2($invoice_id)
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT * FROM invoice_items WHERE invoice_id = ?");
|
||||
$stmt->execute([$invoice_id]);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
// ინვოისის ნივთების დამატება
|
||||
public static function addInvoiceItem($invoice_id, $item)
|
||||
{
|
||||
$stmt = self::$db->prepare("INSERT INTO invoice_items (invoice_id, product_id, description, amount) VALUES (?, ?, ?, ?)");
|
||||
return $stmt->execute([
|
||||
$invoice_id,
|
||||
$item['product_id'],
|
||||
$item['description'],
|
||||
$item['amount']
|
||||
]);
|
||||
}
|
||||
|
||||
// ინვოისის ნივთების წაშლა
|
||||
public static function deleteInvoiceItems($invoice_id)
|
||||
{
|
||||
$stmt = self::$db->prepare("DELETE FROM invoice_items WHERE invoice_id = ?");
|
||||
return $stmt->execute([$invoice_id]);
|
||||
}
|
||||
|
||||
public static function getInvoiceWithClient($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT i.*, c.first_name, c.last_name, c.email
|
||||
FROM invoices i
|
||||
JOIN clients c ON c.id = i.client_id
|
||||
WHERE i.id = ?
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
public static function getInvoiceItems($invoiceId)
|
||||
{
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT ii.*, p.name
|
||||
FROM invoice_items ii
|
||||
JOIN products p ON p.id = ii.product_id
|
||||
WHERE ii.invoice_id = ?
|
||||
");
|
||||
$stmt->execute([$invoiceId]);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function generateNextInvoiceNumber(): string
|
||||
{
|
||||
$currentYear = date('Y');
|
||||
$prefix = 'INV-' . $currentYear . '-';
|
||||
|
||||
$stmt = self::$db->prepare("SELECT invoice_number FROM invoices WHERE invoice_number LIKE ? ORDER BY invoice_number DESC LIMIT 1");
|
||||
$stmt->execute([$prefix . '%']);
|
||||
$lastInvoice = $stmt->fetchColumn();
|
||||
|
||||
if ($lastInvoice) {
|
||||
$lastNumber = (int) substr($lastInvoice, strrpos($lastInvoice, '-') + 1);
|
||||
$newNumber = str_pad($lastNumber + 1, 3, '0', STR_PAD_LEFT);
|
||||
} else {
|
||||
$newNumber = '001';
|
||||
}
|
||||
|
||||
return $prefix . $newNumber;
|
||||
}
|
||||
|
||||
public static function getClientsList(): array
|
||||
{
|
||||
$stmt = self::$db->query("SELECT id, first_name, last_name FROM clients ORDER BY first_name");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function getProductList(): array
|
||||
{
|
||||
$stmt = self::$db->query("SELECT id, name, price FROM products ORDER BY name");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function createInvoiceWithItems($data)
|
||||
{
|
||||
$stmt = self::$db->prepare("INSERT INTO invoices
|
||||
(client_id, invoice_number, description, total_amount, payment_method, status, issue_date, due_date, recurring)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
$stmt->execute([
|
||||
$data['client_id'],
|
||||
$data['invoice_number'],
|
||||
$data['description'],
|
||||
$data['total_amount'],
|
||||
$data['payment_method'],
|
||||
$data['status'],
|
||||
$data['issue_date'],
|
||||
$data['due_date'],
|
||||
$data['recurring']
|
||||
]);
|
||||
|
||||
$invoice_id = self::$db->lastInsertId();
|
||||
|
||||
$stmtItem = self::$db->prepare("INSERT INTO invoice_items (invoice_id, product_id, amount, description) VALUES (?, ?, ?, ?)");
|
||||
|
||||
for ($i = 0; $i < count($data['products']); $i++) {
|
||||
$stmtItem->execute([
|
||||
$invoice_id,
|
||||
$data['products'][$i],
|
||||
$data['amounts'][$i],
|
||||
$data['descriptions'][$i]
|
||||
]);
|
||||
}
|
||||
|
||||
return $invoice_id;
|
||||
}
|
||||
|
||||
public static function generateInvoiceNumber(): string
|
||||
{
|
||||
$year = date('Y');
|
||||
$prefix = 'INV-' . $year . '-';
|
||||
|
||||
$stmt = self::$db->prepare("SELECT invoice_number FROM invoices WHERE invoice_number LIKE ? ORDER BY invoice_number DESC LIMIT 1");
|
||||
$stmt->execute([$prefix . '%']);
|
||||
$last = $stmt->fetchColumn();
|
||||
|
||||
$lastNumber = $last ? (int) substr($last, strrpos($last, '-') + 1) : 0;
|
||||
$newNumber = str_pad($lastNumber + 1, 3, '0', STR_PAD_LEFT);
|
||||
|
||||
return $prefix . $newNumber;
|
||||
}
|
||||
|
||||
|
||||
public static function isValidStatus(string $status): bool
|
||||
{
|
||||
$allowed = ['დრაფტი', 'გადაუხდელი', 'გადასახდელი', 'გადახდილი', 'გაუქმებული'];
|
||||
return in_array($status, $allowed);
|
||||
}
|
||||
|
||||
|
||||
public static function isDuplicateInvoiceNumber(string $invoice_number): bool
|
||||
{
|
||||
$stmt = self::$db->prepare("SELECT COUNT(*) FROM invoices WHERE invoice_number = ?");
|
||||
$stmt->execute([$invoice_number]);
|
||||
return $stmt->fetchColumn() > 0;
|
||||
}
|
||||
|
||||
public static function getInvoicesDueTomorrow()
|
||||
{
|
||||
$tomorrow = date('Y-m-d', strtotime('+1 day'));
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT invoices.*, clients.first_name, clients.last_name, clients.email
|
||||
FROM invoices
|
||||
JOIN clients ON invoices.client_id = clients.id
|
||||
WHERE invoices.due_date = ? AND invoices.status IN ('გადაუხდელი', 'გადასახდელი')
|
||||
");
|
||||
$stmt->execute([$tomorrow]);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function getInvoiceWithItems($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT invoices.*, clients.email, clients.first_name, clients.last_name
|
||||
FROM invoices
|
||||
JOIN clients ON invoices.client_id = clients.id
|
||||
WHERE invoices.id = ?
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
$invoice = $stmt->fetch();
|
||||
|
||||
if (!$invoice) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmtItems = self::$db->prepare("
|
||||
SELECT products.name, ii.description, ii.amount
|
||||
FROM invoice_items ii
|
||||
JOIN products ON products.id = ii.product_id
|
||||
WHERE ii.invoice_id = ?
|
||||
");
|
||||
$stmtItems->execute([$id]);
|
||||
$invoice['items'] = $stmtItems->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
|
||||
public static function generateInvoicePDF($invoice)
|
||||
{
|
||||
$html = self::renderInvoiceHTML($invoice);
|
||||
|
||||
$options = new \Dompdf\Options();
|
||||
$options->set('isRemoteEnabled', true);
|
||||
$options->set('defaultFont', 'DejaVu Sans');
|
||||
|
||||
$dompdf = new \Dompdf\Dompdf($options);
|
||||
$dompdf->loadHtml($html, 'UTF-8');
|
||||
$dompdf->setPaper('A4', 'portrait');
|
||||
$dompdf->render();
|
||||
|
||||
$pdfPath = '/tmp/invoice_' . $invoice['id'] . '.pdf';
|
||||
file_put_contents($pdfPath, $dompdf->output());
|
||||
|
||||
return $pdfPath;
|
||||
}
|
||||
|
||||
public static function renderInvoiceHTML($invoice)
|
||||
{
|
||||
ob_start();
|
||||
include __DIR__ . '/../views/invoices/pdf_template.php'; // თუ გინდა გამოყავი ცალკე template ფაილად
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
// მოაქვს პდფ ფაილში კლიენტის ბაზიდან დამატებითი მონაცემები
|
||||
public static function getInvoiceWithClientById($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT
|
||||
invoices.*,
|
||||
clients.company_name,
|
||||
clients.vat_number,
|
||||
clients.address1,
|
||||
clients.first_name AS client_first_name,
|
||||
clients.last_name AS client_last_name
|
||||
FROM invoices
|
||||
LEFT JOIN clients ON invoices.client_id = clients.id
|
||||
WHERE invoices.id = ?
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
class TransactionsModel
|
||||
{
|
||||
private static $db;
|
||||
|
||||
public static function setDb($pdo)
|
||||
{
|
||||
self::$db = $pdo;
|
||||
}
|
||||
|
||||
public static function getClients()
|
||||
{
|
||||
$stmt = self::$db->query("SELECT id, first_name, last_name FROM clients ORDER BY first_name ASC");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function getInvoices()
|
||||
{
|
||||
$stmt = self::$db->query("SELECT id, invoice_number FROM invoices ORDER BY invoice_number ASC");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function handleTransactionFormSubmission()
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$invoice_id = $_POST['invoice_id'] ?? '';
|
||||
$client_id = $_POST['client_id'] ?? '';
|
||||
$amount = $_POST['amount'] ?? '';
|
||||
$method = $_POST['method'] ?? '';
|
||||
$status = $_POST['status'] ?? '';
|
||||
$notes = $_POST['notes'] ?? '';
|
||||
|
||||
if (!$invoice_id || !$client_id || !$amount || !$method || !$status) {
|
||||
$errors[] = "გთხოვ შეავსო ყველა სავალდებულო ველი.";
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
$stmt = self::$db->prepare("INSERT INTO transactions (invoice_id, client_id, amount, method, status, notes) VALUES (?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$invoice_id, $client_id, $amount, $method, $status, $notes]);
|
||||
|
||||
header("Location: dashboard.php?module=billing&submodule=transactions&action=list&added=1");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public static function getTransactionById($id)
|
||||
{
|
||||
if (!$id || !is_numeric($id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT t.*, c.first_name, c.last_name, i.invoice_number
|
||||
FROM transactions t
|
||||
JOIN clients c ON c.id = t.client_id
|
||||
JOIN invoices i ON i.id = t.invoice_id
|
||||
WHERE t.id = ?
|
||||
");
|
||||
$stmt->execute([$id]);
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
public static function updateTransaction($id, $data)
|
||||
{
|
||||
$stmt = self::$db->prepare("
|
||||
UPDATE transactions
|
||||
SET status = ?, method = ?, notes = ?
|
||||
WHERE id = ?
|
||||
");
|
||||
return $stmt->execute([
|
||||
$data['status'],
|
||||
trim($data['method']),
|
||||
trim($data['notes']),
|
||||
$id
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getClientInfo($clientId)
|
||||
{
|
||||
if (!$clientId || !is_numeric($clientId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt = self::$db->prepare("SELECT first_name, last_name FROM clients WHERE id = ?");
|
||||
$stmt->execute([$clientId]);
|
||||
return $stmt->fetch();
|
||||
}
|
||||
|
||||
public static function getClientTransactions($clientId)
|
||||
{
|
||||
if (!$clientId || !is_numeric($clientId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$stmt = self::$db->prepare("
|
||||
SELECT t.*, i.invoice_number
|
||||
FROM transactions t
|
||||
JOIN invoices i ON i.id = t.invoice_id
|
||||
WHERE t.client_id = ?
|
||||
ORDER BY t.created_at DESC
|
||||
");
|
||||
$stmt->execute([$clientId]);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function getAllTransactions()
|
||||
{
|
||||
$stmt = self::$db->query("
|
||||
SELECT t.*, c.first_name, c.last_name, i.invoice_number
|
||||
FROM transactions t
|
||||
JOIN clients c ON t.client_id = c.id
|
||||
JOIN invoices i ON t.invoice_id = i.id
|
||||
ORDER BY t.created_at DESC
|
||||
");
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function deleteTransaction($id)
|
||||
{
|
||||
$stmt = self::$db->prepare("DELETE FROM transactions WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
?>
|
||||
|
||||
|
||||
<!-- CONTENT START -->
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<h2 class="mb-4">ახალი ინვოისის დამატება</h2>
|
||||
|
||||
<form action="dashboard.php?module=billing&submodule=invoices&action=store" method="POST">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">კლიენტი</label>
|
||||
<select name="client_id" class="form-select" required>
|
||||
<option value="">აირჩიე კლიენტი</option>
|
||||
<?php foreach ($clients as $client): ?>
|
||||
<option value="<?= $client['id'] ?>">
|
||||
<?= htmlspecialchars($client['first_name'] . ' ' . $client['last_name']) ?>
|
||||
</option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label">პროდუქტები</label>
|
||||
|
||||
<div id="product-container">
|
||||
<div class="row product-item mb-2">
|
||||
<div class="col-md-5">
|
||||
<select name="products[]" class="form-select" required>
|
||||
<option value="">აირჩიე პროდუქტი</option>
|
||||
<?php foreach ($products as $product): ?>
|
||||
<option value="<?= $product['id'] ?>">
|
||||
<?= htmlspecialchars($product['name']) ?> (<?= $product['price'] ?> ₾)
|
||||
</option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="number" name="amounts[]" step="0.01" class="form-control" placeholder="თანხა ₾" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="descriptions[]" class="form-control" placeholder="აღწერა (არასავალდებულო)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-danger btn-remove">-</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" id="add-product" class="btn btn-secondary btn-sm mt-2">+ პროდუქტის დამატება</button>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ინვოისის ნომერი (არასავალდებულო)</label>
|
||||
<input type="text" name="invoice_number" class="form-control"
|
||||
placeholder="მაგ: INV-2025-001"
|
||||
value="<?= htmlspecialchars($generatedInvoiceNumber) ?>" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ინვოისის აღწერა</label>
|
||||
<textarea name="description" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">გადასახდელი თანხა (₾)</label>
|
||||
<input type="number" step="0.01" name="total_amount" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">გადახდის მეთოდი</label>
|
||||
<input type="text" name="payment_method" class="form-control" value="საბანკო გადმორიცხვა" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">სტატუსი</label>
|
||||
<select name="status" class="form-select" required>
|
||||
<option value="დრაფტი">დრაფტი</option>
|
||||
<option value="გადაუხდელი">გადაუხდელი</option>
|
||||
<option value="გადასახდელი">გადასახდელი</option>
|
||||
<option value="გადახდილი">გადახდილი</option>
|
||||
<option value="გაუქმებული">გაუქმებული</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="col">
|
||||
<label class="form-label">ინვოისის თარიღი</label>
|
||||
<input type="date" name="issue_date" class="form-control" value="<?= date('Y-m-d') ?>" required>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">გადახდის ბოლო ვადა</label>
|
||||
<input type="date" name="due_date" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-check">
|
||||
<input type="checkbox" name="recurring" value="1" class="form-check-input">
|
||||
<span class="form-check-label">გადახდა განმეორებით (ყოველთვიურად)</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-primary">ინვოისის შექმნა</button>
|
||||
<a href="list.php" class="btn btn-secondary">გაუქმება</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div></div>
|
||||
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
|
||||
<script>
|
||||
document.getElementById('add-product').addEventListener('click', function () {
|
||||
const container = document.getElementById('product-container');
|
||||
const item = container.querySelector('.product-item');
|
||||
const clone = item.cloneNode(true);
|
||||
|
||||
// reset values
|
||||
clone.querySelectorAll('input, select').forEach(el => el.value = '');
|
||||
container.appendChild(clone);
|
||||
});
|
||||
|
||||
// remove button
|
||||
document.addEventListener('click', function (e) {
|
||||
if (e.target.classList.contains('btn-remove')) {
|
||||
const allItems = document.querySelectorAll('.product-item');
|
||||
if (allItems.length > 1) {
|
||||
e.target.closest('.product-item').remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../models/invoicesmodel.php';
|
||||
|
||||
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
|
||||
?>
|
||||
|
||||
<!-- CONTENT START -->
|
||||
<div class="page-wrapper">
|
||||
<div class="container-xl mt-4">
|
||||
<h2 class="mb-4">ინვოისის რედაქტირება</h2>
|
||||
|
||||
<form action="dashboard.php?module=billing&submodule=invoices&action=update" method="POST">
|
||||
<input type="hidden" name="id" value="<?= $invoice['id'] ?>">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">კლიენტი</label>
|
||||
<select name="client_id" class="form-select" required>
|
||||
<?php foreach ($clients as $client): ?>
|
||||
<option value="<?= $client['id'] ?>" <?= $invoice['client_id'] == $client['id'] ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($client['first_name'] . ' ' . $client['last_name']) ?>
|
||||
</option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ინვოისის ნომერი</label>
|
||||
<input type="text" name="invoice_number" class="form-control" value="<?= htmlspecialchars($invoice['invoice_number']) ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">აღწერა</label>
|
||||
<textarea name="description" class="form-control"><?= htmlspecialchars($invoice['description']) ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">გადახდის მეთოდი</label>
|
||||
<input type="text" name="payment_method" class="form-control" value="<?= htmlspecialchars($invoice['payment_method']) ?>" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">სტატუსი</label>
|
||||
<select name="status" class="form-select">
|
||||
<?php foreach (['დრაფტი', 'გადაუხდელი', 'გადასახდელი', 'გადახდილი', 'გაუქმებული'] as $status): ?>
|
||||
<option value="<?= $status ?>" <?= $invoice['status'] == $status ? 'selected' : '' ?>><?= $status ?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">თანხა (₾)</label>
|
||||
<input type="number" name="total_amount" class="form-control" step="0.01" value="<?= $invoice['total_amount'] ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">ინვოისის თარიღი</label>
|
||||
<input type="date" name="issue_date" class="form-control" value="<?= $invoice['issue_date'] ?>" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">გადახდის ბოლო ვადა</label>
|
||||
<input type="date" name="due_date" class="form-control" value="<?= $invoice['due_date'] ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="recurring" value="1" <?= $invoice['recurring'] ? 'checked' : '' ?>>
|
||||
<span class="form-check-label">გადახდა განმეორებით (ყოველთვიურად)</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-primary">შენახვა</button>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=view&id=<?= $invoice['id'] ?>" class="btn btn-secondary">უკან</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
@@ -0,0 +1,64 @@
|
||||
<!-- ინვოისების სია + ფილტრები -->
|
||||
<?php require_once __DIR__ . '/../../models/invoicesmodel.php'; ?>
|
||||
<?php
|
||||
use App\Config;
|
||||
|
||||
InvoicesModel::setDb($pdo);
|
||||
$invoices = InvoicesModel::getAllInvoicesWithClientNames();
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
?>
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<div class="d-flex justify-content-between mb-3">
|
||||
<h2>ინვოისების სია</h2>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=create" class="btn btn-primary">+ ახალი ინვოისი</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>კლიენტი</th>
|
||||
<th>თანხა</th>
|
||||
<th>სტატუსი</th>
|
||||
<th>თარიღი</th>
|
||||
<th>ვადა</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($invoices as $invoice): ?>
|
||||
<tr>
|
||||
<td><?= $invoice['id'] ?></td>
|
||||
<td><?= htmlspecialchars($invoice['client_name']) ?></td>
|
||||
<td><?= number_format($invoice['total_amount'], 2) ?> ₾</td>
|
||||
<td>
|
||||
<span class="badge bg-light">
|
||||
<?= htmlspecialchars($invoice['status']) ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?= $invoice['issue_date'] ?></td>
|
||||
<td><?= $invoice['due_date'] ?></td>
|
||||
<td>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=view&id=<?= $invoice['id'] ?>" class="btn btn-sm btn-info">ნახვა</a>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=edit&id=<?= $invoice['id'] ?>" class="btn btn-sm btn-warning">რედაქტირება</a>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=delete&id=<?= $invoice['id'] ?>" class="btn btn-sm btn-danger" onclick="return confirm('ნამდვილად გსურს წაშლა?')">წაშლა</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content END -->
|
||||
</div>
|
||||
</div>
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
@@ -0,0 +1,167 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ka">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ინვოისი</title>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: DejaVu Sans;
|
||||
}
|
||||
body {
|
||||
font-family: DejaVu Sans;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
.invoice-box {
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
padding: 30px;
|
||||
border: 1px solid #eee;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.top-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.top-header img {
|
||||
max-width: 250px;
|
||||
}
|
||||
.bank-info {
|
||||
text-align: right;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.green-banner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
padding: 5px 20px;
|
||||
transform: rotate(45deg);
|
||||
transform-origin: top right;
|
||||
font-size: 16px;
|
||||
}
|
||||
.section {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.gray-box {
|
||||
background: #eee;
|
||||
padding: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 15px;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
th, td {
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 30px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
color: #777;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="invoice-box">
|
||||
<!-- <div class="green-banner">გადახდილია</div> -->
|
||||
<div class="top-header">
|
||||
<div>
|
||||
<h3>SELFHOSTING.GE</h3>
|
||||
</div>
|
||||
<div class="bank-info">
|
||||
ი/მ ლევან არაბული<br>
|
||||
პ/ნ: 01001080490<br><br>
|
||||
ბანკი: თიბისი ბანკი<br>
|
||||
ა/ნ: GE79TB7902736010100047<br><br>
|
||||
ბანკი: საქართველოს ბანკი<br>
|
||||
ა/ნ: GE85BG0000000534211842<br>
|
||||
იდენტიფიკატორი: 01001080490
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section gray-box">
|
||||
ინვოისი #: <?= htmlspecialchars($invoice['invoice_number']) ?><br>
|
||||
ინვოისის თარიღი: <?= htmlspecialchars($invoice['issue_date']) ?><br>
|
||||
გადახდის თარიღი: <?= htmlspecialchars($invoice['due_date']) ?>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<strong>მიმღები:</strong><br>
|
||||
<?= htmlspecialchars($invoice['first_name'] . ' ' . $invoice['last_name']) ?><br>
|
||||
<?php if (!empty($invoice['company_name'])): ?>
|
||||
<?= htmlspecialchars($invoice['company_name']) ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($invoice['address1'])): ?>
|
||||
<?= htmlspecialchars($invoice['address1']) ?><br>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($invoice['vat_number'])): ?>
|
||||
VAT: <?= htmlspecialchars($invoice['vat_number']) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>დასახელება</th>
|
||||
<th>აღწერა</th>
|
||||
<th>თანხა</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($invoice['items'] as $item): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($item['name']) ?></td>
|
||||
<td><?= htmlspecialchars($item['description']) ?></td>
|
||||
<td><?= number_format($item['amount'], 2) ?> ლარი</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>ტრანზაქციები</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ინვოისის ნომერი</th>
|
||||
<th>გადახდის მეთოდი</th>
|
||||
<th>ტრანზაქციის ID</th>
|
||||
<th>თანხა</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td># <?= htmlspecialchars($invoice['invoice_number']) ?></td>
|
||||
<td><?= htmlspecialchars($invoice['payment_method']) ?></td>
|
||||
<td>-</td>
|
||||
<td><?= number_format($invoice['total_amount'], 2) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">ბალანსი</td>
|
||||
<td>0.00 GEL</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
Powered By Stack.ge | შექმნილია Stack.ge-ს მიერ
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,69 @@
|
||||
<!-- კონკრეტული ინვოისის ხილვა -->
|
||||
<?php require_once __DIR__ . '/../../models/invoicesmodel.php'; ?>
|
||||
|
||||
<?php
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
?>
|
||||
|
||||
|
||||
<!-- CONTENT START -->
|
||||
<?php if ($showAlert): ?>
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert" id="invoiceAlert">
|
||||
✅ ინვოისი წარმატებით გაიგზავნა!
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(() => {
|
||||
const alertBox = document.getElementById('invoiceAlert');
|
||||
if (alertBox) alertBox.remove();
|
||||
}, 5000);
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<h2>ინვოისი # <?= $invoice['invoice_number'] ? htmlspecialchars($invoice['invoice_number']) : '' ?></h2>
|
||||
<p><strong>კლიენტი:</strong> <?= htmlspecialchars($invoice['first_name'] . ' ' . $invoice['last_name']) ?></p>
|
||||
<p><strong>სტატუსი:</strong> <?= htmlspecialchars($invoice['status']) ?></p>
|
||||
<p><strong>თარიღი:</strong> <?= $invoice['issue_date'] ?></p>
|
||||
<p><strong>ბოლო ვადა:</strong> <?= $invoice['due_date'] ?></p>
|
||||
<p><strong>გადასახდელი თანხა:</strong> <?= number_format($invoice['total_amount'], 2) ?> ₾</p>
|
||||
<p><strong>გადახდის მეთოდი:</strong> <?= htmlspecialchars($invoice['payment_method']) ?></p>
|
||||
<p><strong>აღწერა:</strong> <?= nl2br(htmlspecialchars($invoice['description'])) ?></p>
|
||||
|
||||
<?php if (!empty($productItems)): ?>
|
||||
<h4 class="mt-4">პროდუქტები</h4>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>პროდუქტი</th>
|
||||
<th>თანხა</th>
|
||||
<th>აღწერა</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($productItems as $item): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($item['name']) ?></td>
|
||||
<td><?= number_format($item['amount'], 2) ?> ₾</td>
|
||||
<td><?= htmlspecialchars($item['description']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mt-4">
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=send&id=<?= $invoice['id'] ?>" class="btn btn-primary">გაგზავნა</a>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=edit&id=<?= $invoice['id'] ?>" class="btn btn-secondary">რედაქტირება</a>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=delete&id=<?= $invoice['id'] ?>" class="btn btn-danger">წაშლა</a>
|
||||
<a href="dashboard.php?module=billing&submodule=invoices&action=list" class="btn btn-light">უკან</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<h2>ტრანზაქციის დამატება</h2>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger"><?= implode('<br>', $errors) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ინვოისი</label>
|
||||
<select name="invoice_id" class="form-select" required>
|
||||
<option value="">აირჩიე</option>
|
||||
<?php foreach ($invoices as $inv): ?>
|
||||
<option value="<?= $inv['id'] ?>"><?= htmlspecialchars($inv['invoice_number']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">კლიენტი</label>
|
||||
<select name="client_id" class="form-select" required>
|
||||
<option value="">აირჩიე</option>
|
||||
<?php foreach ($clients as $cl): ?>
|
||||
<option value="<?= $cl['id'] ?>"><?= htmlspecialchars($cl['first_name'] . ' ' . $cl['last_name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">თანხა</label>
|
||||
<input type="number" name="amount" step="0.01" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">მეთოდი</label>
|
||||
<input type="text" name="method" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">სტატუსი</label>
|
||||
<select name="status" class="form-select" required>
|
||||
<option value="success">წარმატებული</option>
|
||||
<option value="failed">წარუმატებელი</option>
|
||||
<option value="pending">მოლოდინში</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">შენიშვნა</label>
|
||||
<textarea name="notes" class="form-control"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-success">შენახვა</button>
|
||||
<a href="list.php" class="btn btn-secondary">გაუქმება</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
|
||||
?>
|
||||
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<h2>ტრანზაქციის რედაქტირება</h2>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ინვოისი</label>
|
||||
<input type="text" class="form-control" value="#<?= $transaction['invoice_number'] ?>" disabled>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">კლიენტი</label>
|
||||
<input type="text" class="form-control" value="<?= $transaction['first_name'] . ' ' . $transaction['last_name'] ?>" disabled>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">თანხა</label>
|
||||
<input type="text" class="form-control" value="<?= number_format($transaction['amount'], 2) ?> ₾" disabled>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">სტატუსი</label>
|
||||
<select name="status" class="form-select" required>
|
||||
<option value="success" <?= $transaction['status'] === 'success' ? 'selected' : '' ?>>დადასტურებული</option>
|
||||
<option value="failed" <?= $transaction['status'] === 'failed' ? 'selected' : '' ?>>ჩავარდა</option>
|
||||
<option value="pending" <?= $transaction['status'] === 'pending' ? 'selected' : '' ?>>მოლოდინში</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">გადახდის მეთოდი</label>
|
||||
<input type="text" name="method" class="form-control" value="<?= htmlspecialchars($transaction['method']) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">შენიშვნა</label>
|
||||
<textarea name="notes" class="form-control"><?= htmlspecialchars($transaction['notes']) ?></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">შენახვა</button>
|
||||
<a href="list.php" class="btn btn-secondary">უკან</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<h2>ტრანზაქციების ისტორია - <?= htmlspecialchars($client['first_name'] . ' ' . $client['last_name']) ?></h2>
|
||||
|
||||
<?php if (empty($transactions)): ?>
|
||||
<div class="alert alert-info">ტრანზაქცია არ მოიძებნა.</div>
|
||||
<?php else: ?>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ინვოისი</th>
|
||||
<th>თანხა</th>
|
||||
<th>მეთოდი</th>
|
||||
<th>სტატუსი</th>
|
||||
<th>შენიშვნა</th>
|
||||
<th>თარიღი</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($transactions as $t): ?>
|
||||
<tr>
|
||||
<td>#<?= htmlspecialchars($t['invoice_number']) ?></td>
|
||||
<td><?= number_format($t['amount'], 2) ?> ₾</td>
|
||||
<td><?= htmlspecialchars($t['method']) ?></td>
|
||||
<td>
|
||||
<span class="badge bg-<?= $t['status'] === 'success' ? 'success' : ($t['status'] === 'failed' ? 'danger' : 'warning') ?>">
|
||||
<?= htmlspecialchars($t['status']) ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?= nl2br(htmlspecialchars($t['notes'])) ?></td>
|
||||
<td><?= $t['created_at'] ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="/admin/clients/view.php?id=<?= $clientId ?>" class="btn btn-light">🔙 უკან კლიენტის პროფილში</a>
|
||||
</div>
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../models/transactionsmodel.php';
|
||||
|
||||
use App\Config;
|
||||
|
||||
require_once Config::includePath('head.php');
|
||||
require_once Config::includePath('navbar.php');
|
||||
require_once Config::includePath('pageheader.php');
|
||||
require_once Config::includePath('pagebodystart.php');
|
||||
|
||||
?>
|
||||
|
||||
<?php if (!empty($successMessage)): ?>
|
||||
<div class="alert alert-success">
|
||||
<?= htmlspecialchars($successMessage) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="container-xl mt-4">
|
||||
<h2>ტრანზაქციები</h2>
|
||||
<a href="dashboard.php?module=billing&submodule=transactions&action=create" class="btn btn-primary mb-3">➕ დამატება</a>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ინვოისი</th>
|
||||
<th>კლიენტი</th>
|
||||
<th>თანხა</th>
|
||||
<th>მეთოდი</th>
|
||||
<th>სტატუსი</th>
|
||||
<th>თარიღი</th>
|
||||
<th>ქმედებები</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($transactions as $tx): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($tx['invoice_number']) ?></td>
|
||||
<td><?= htmlspecialchars($tx['first_name'] . ' ' . $tx['last_name']) ?></td>
|
||||
<td><?= number_format($tx['amount'], 2) ?> ₾</td>
|
||||
<td><?= htmlspecialchars($tx['method']) ?></td>
|
||||
<td><?= htmlspecialchars($tx['status']) ?></td>
|
||||
<td><?= $tx['created_at'] ?></td>
|
||||
<td>
|
||||
<a href="dashboard.php?module=billing&submodule=transactions&action=edit&id=<?= $tx['id'] ?>" class="btn btn-sm btn-warning">✏️</a>
|
||||
<a href="dashboard.php?module=billing&submodule=transactions&action=delete&id=<?= $tx['id'] ?>" class="btn btn-sm btn-danger" onclick="return confirm('დარწმუნებული ხარ?')">🗑️</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php require_once Config::includePath('footer.php'); ?>
|
||||
Reference in New Issue
Block a user