progress laporan

This commit is contained in:
JokoPrasetio 2025-08-05 16:00:45 +07:00
parent 3e5fb5be1d
commit 4d476bea75
34 changed files with 2022 additions and 169 deletions

View File

@ -2,12 +2,15 @@
namespace App\Http\Controllers;
use App\Mail\NotifikasiCustomer;
use App\Mail\NotifikasiPembayaran;
use App\Models\Karbohidrat;
use App\Models\Order;
use App\Models\OrderDetail;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
class CustomerController extends Controller
@ -255,7 +258,8 @@ class CustomerController extends Controller
$payloadOrderDetail['jumlah'] = $value['jumlah'];
$payloadOrderDetail['tgl_antar'] = $value['tgl'];
$payloadOrderDetail['type'] = $value['kategoriPemesanan'];
$payloadOrderDetail['karbohidrat_id'] = $value['karbohidrat_id'];
$payloadOrderDetail['karbohidrat_id'] = $value['karbohidrat_id'] ?? null;
$payloadOrderDetail['catatan'] = $value['catatan'] ?? null;
if($cart['jenis_menu'] === "paket"){
$payloadOrderDetail['master_paket_menu_id'] = $cart['id_menu'];
}else{
@ -265,7 +269,9 @@ class CustomerController extends Controller
}
}
//code...
if($order->email){
Mail::to($order->email)->queue(new NotifikasiCustomer($order->nama_pemesan, $order->no_order, $order->total_harga));
}
DB::commit();
return response()->json([
'status' => true,
@ -319,6 +325,9 @@ class CustomerController extends Controller
// Update data order
$order->update($payload);
if($order->email){
Mail::to($order->email)->queue(new NotifikasiPembayaran($order->nama_pemesan, $order->no_order));
}
DB::commit();
session()->flash('payment_success', true);
session()->flash('no_order', $noOrder);
@ -328,7 +337,6 @@ class CustomerController extends Controller
], 200);
return back()->with('success', 'Bukti pembayaran berhasil diunggah.');
} catch (\Throwable $th) {
dd($th);
DB::rollBack();
return response([
'status' => false,

View File

@ -2,12 +2,15 @@
namespace App\Http\Controllers;
use App\Mail\NotifikasiKonfirmasiPembayaran;
use App\Models\Order;
use App\Models\OrderDetail;
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class PesananController extends Controller
{
@ -86,6 +89,11 @@ class PesananController extends Controller
$payload['note_dibatalkan'] = request('note_dibatalkan');
}
$order->update($payload);
if($order->email){
Mail::to($order->email)->queue(new NotifikasiKonfirmasiPembayaran($order->nama_pemesan, $order->no_order, $order->total_harga));
}
DB::connection('dbOrderGizi')->commit();
return response()->json([
'status' => true,
@ -113,6 +121,10 @@ class PesananController extends Controller
'cara_pembayaran' => 'Billing'
];
$order->update($payload);
if($order->email){
Mail::to($order->email)->queue(new NotifikasiKonfirmasiPembayaran($order->nama_pemesan, $order->no_order, $order->total_harga));
}
DB::connection('dbOrderGizi')->commit();
return response()->json([
'status' => true,
@ -239,6 +251,80 @@ class PesananController extends Controller
'data' => $data
]);
}
public function exportPekerjaan(){
$startDate = request('start_date');
$endDate = request('end_date');
$now = Carbon::now()->format('Y-m-d H-i');
$orderDetail = OrderDetail::with(['menu', 'paketMenu', 'order'])->whereHas('order', function($q){
$q->where('status_order', 'Lunas');
})->whereBetween('tgl_antar', [$startDate, $endDate])->get();
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$data = [
'pekerjaan' => $orderDetail,
'waktu_cetak' => $waktu_cetak,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.pekerjaan.pdf', $data);
return $pdf->stream("daftar-pesanan-{$now}.pdf");
}
public function exportPending(){
$startDate = Carbon::parse(request('start_date'))->startOfDay();
$endDate = Carbon::parse(request('end_date'))->endOfDay();
$order = Order::where('statusenabled', true)
->whereBetween('entry_at', [$startDate, $endDate])
->with('orderDetail')
->whereHas('orderDetail', function($q) {
$q->where('status_order', '!=', 'Selesai');
})
->get();
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$data = [
'waktu_cetak' => $waktu_cetak,
'orders' => $order,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.pending.pdf', $data);
return $pdf->stream('laporan-pesanan-' . now()->format('Ymd-His') . '.pdf');
}
public function exportSelesai(){
$startDate = Carbon::parse(request('start_date'))->startOfDay();
$endDate = Carbon::parse(request('end_date'))->endOfDay();
$order = Order::where('statusenabled', true)
->whereBetween('entry_at', [$startDate, $endDate])
->with('orderDetail')
->whereHas('orderDetail') // hanya order yang punya detail
->whereDoesntHave('orderDetail', function($q) {
$q->where('status_order', '!=', 'Selesai');
})
->get();
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$data = [
'waktu_cetak' => $waktu_cetak,
'orders' => $order,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.selesai.pdf', $data);
return $pdf->stream('laporan-pesanan-' . now()->format('Ymd-His') . '.pdf');
}
/**
* Show the form for creating a new resource.
*/

View File

@ -0,0 +1,73 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class NotifikasiCustomer extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public $pemesan;
public $noOrder;
public $total_harga;
public function __construct($pemesan, $noOrder, $total_harga)
{
$this->pemesan = $pemesan;
$this->noOrder = $noOrder;
$this->total_harga = $total_harga;
}
/**
* Get the message content definition.
*/
public function build(){
return $this->subject('Konfirmasi Pesanan Anda')->html("
<div style='font-family: Arial, sans-serif; max-width: 600px; margin: auto; border: 1px solid #eee; padding: 24px;'>
<h2 style='color: #28a745;'> Pesanan Berhasil!</h2>
<p>Halo, <strong>{$this->pemesan}</strong>,</p>
<p>Terima kasih telah melakukan pemesanan. Berikut detail pesanan Anda:</p>
<table style='width: 100%; border-collapse: collapse; margin-top: 16px;'>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>No. Order</td>
<td style='padding: 8px; border: 1px solid #ddd;'>{$this->noOrder}</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Tanggal</td>
<td style='padding: 8px; border: 1px solid #ddd;'>" . now()->format('d M Y H:i') . "</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Status</td>
<td style='padding: 8px; border: 1px solid #ddd; color: green;'>Menunggu Pembayaran</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Nominal Harus Bayar</td>
<td style='padding: 8px; border: 1px solid #ddd; color: green;'>Rp ". number_format($this->total_harga, 0,',', '.')
."</td>
</tr>
</table>
<p style='margin-top: 24px;'>Silakan segera lakukan pembayaran ke rekening berikut:</p>
<ul style='list-style: none; padding: 0;'>
<li><strong>Bank:</strong> BCA</li>
<li><strong>Nomor Rekening:</strong> 1234-5678-9101</li>
<li><strong>Atas Nama:</strong> RSAB Harapan Kita</li>
</ul>
<p style='margin-top: 24px; font-size: 14px; color: #555;'>Jika Anda tidak merasa melakukan pesanan ini, abaikan email ini.</p>
<hr style='margin-top: 40px;'>
<p style='text-align: center; font-size: 12px; color: #888;'>© " . date('Y') . " RSAB Harapan Kita</p>
</div>
");
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class NotifikasiKonfirmasiPembayaran extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public $pemesan;
public $noOrder;
public $total_harga;
public function __construct($pemesan, $noOrder, $total_harga)
{
$this->pemesan = $pemesan;
$this->noOrder = $noOrder;
$this->total_harga = $total_harga;
}
/**
* Get the message content definition.
*/
public function build(){
return $this->subject('Pembayaran Telah Dikonfirmasi')->html("
<div style='font-family: Arial, sans-serif; max-width: 600px; margin: auto; border: 1px solid #eee; padding: 24px;'>
<h2 style='color: #28a745;'> Pembayaran Berhasil Diverifikasi</h2>
<p>Halo, <strong>{$this->pemesan}</strong>,</p>
<p>Pembayaran kamu untuk pesanan <strong>#{$this->noOrder}</strong> telah berhasil kami verifikasi.</p>
<table style='margin-top: 16px; width: 100%; border-collapse: collapse;'>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Nomor Order</td>
<td style='padding: 8px; border: 1px solid #ddd;'>{$this->noOrder}</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Total Pembayaran</td>
<td style='padding: 8px; border: 1px solid #ddd;'>Rp " . number_format($this->total_harga, 0, ',', '.') . "</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Status</td>
<td style='padding: 8px; border: 1px solid #ddd; color: green;'>Pembayaran Diterima</td>
</tr>
</table>
<p style='margin-top: 24px;'>Pesanan kamu sedang kami proses. Silakan tunggu pemberitahuan berikutnya untuk pengambilan makanan.</p>
<hr style='margin-top: 40px;'>
<p style='text-align: center; font-size: 12px; color: #888;'>© " . date('Y') . " RSAB Harapan Kita</p>
</div>
");
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class NotifikasiPembayaran extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public $pemesan;
public $noOrder;
public function __construct($pemesan, $noOrder)
{
$this->pemesan = $pemesan;
$this->noOrder = $noOrder;
}
/**
* Get the message content definition.
*/
public function build(){
return $this->subject('Pembayaran Diterima - Menunggu Konfirmasi')->html("
<div style='font-family: Arial, sans-serif; max-width: 600px; margin: auto; border: 1px solid #eee; padding: 24px;'>
<h2 style='color: #0787ffff;'>Menunggu Konfirmasi Pembayaran</h2>
<p>Halo, <strong>{$this->pemesan}</strong>,</p>
<p>Kami telah menerima bukti pembayaran untuk pesanan kamu dengan nomor <strong>{$this->noOrder}</strong>.</p>
<p><strong>Tim kami akan segera memverifikasi pembayaran tersebut.</strong></p>
<p style='margin-top: 16px;'>Mohon tunggu konfirmasi selanjutnya dari admin. Kami akan kirimkan email ketika pembayaran telah diverifikasi.</p>
<p style='margin-top: 32px; font-size: 14px; color: #555;'>Terima kasih telah melakukan pemesanan.</p>
<hr style='margin-top: 40px;'>
<p style='text-align: center; font-size: 12px; color: #888;'>© " . date('Y') . " RSAB Harapan Kita</p>
</div>
");
}
}

View File

@ -7,8 +7,10 @@
"license": "MIT",
"require": {
"php": "^8.2",
"barryvdh/laravel-dompdf": "^3.1",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1"
"laravel/tinker": "^2.10.1",
"phpoffice/phpspreadsheet": "^4.5"
},
"require-dev": {
"fakerphp/faker": "^1.23",

737
composer.lock generated
View File

@ -4,8 +4,85 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "88970a0117c062eed55fa8728fc43833",
"content-hash": "696ae0d1187bc1634529f1760a11ffd0",
"packages": [
{
"name": "barryvdh/laravel-dompdf",
"version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-dompdf.git",
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
"shasum": ""
},
"require": {
"dompdf/dompdf": "^3.0",
"illuminate/support": "^9|^10|^11|^12",
"php": "^8.1"
},
"require-dev": {
"larastan/larastan": "^2.7|^3.0",
"orchestra/testbench": "^7|^8|^9|^10",
"phpro/grumphp": "^2.5",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"PDF": "Barryvdh\\DomPDF\\Facade\\Pdf",
"Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf"
},
"providers": [
"Barryvdh\\DomPDF\\ServiceProvider"
]
},
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Barryvdh\\DomPDF\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "A DOMPDF Wrapper for Laravel",
"keywords": [
"dompdf",
"laravel",
"pdf"
],
"support": {
"issues": "https://github.com/barryvdh/laravel-dompdf/issues",
"source": "https://github.com/barryvdh/laravel-dompdf/tree/v3.1.1"
},
"funding": [
{
"url": "https://fruitcake.nl",
"type": "custom"
},
{
"url": "https://github.com/barryvdh",
"type": "github"
}
],
"time": "2025-02-13T15:07:54+00:00"
},
{
"name": "brick/math",
"version": "0.13.1",
@ -135,6 +212,85 @@
],
"time": "2024-02-09T16:56:22+00:00"
},
{
"name": "composer/pcre",
"version": "3.3.2",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<1.11.10"
},
"require-dev": {
"phpstan/phpstan": "^1.12 || ^2",
"phpstan/phpstan-strict-rules": "^1 || ^2",
"phpunit/phpunit": "^8 || ^9"
},
"type": "library",
"extra": {
"phpstan": {
"includes": [
"extension.neon"
]
},
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Pcre\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
"keywords": [
"PCRE",
"preg",
"regex",
"regular expression"
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
"source": "https://github.com/composer/pcre/tree/3.3.2"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2024-11-12T16:29:46+00:00"
},
{
"name": "dflydev/dot-access-data",
"version": "v3.0.3",
@ -378,6 +534,161 @@
],
"time": "2024-02-05T11:56:58+00:00"
},
{
"name": "dompdf/dompdf",
"version": "v3.1.0",
"source": {
"type": "git",
"url": "https://github.com/dompdf/dompdf.git",
"reference": "a51bd7a063a65499446919286fb18b518177155a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
"reference": "a51bd7a063a65499446919286fb18b518177155a",
"shasum": ""
},
"require": {
"dompdf/php-font-lib": "^1.0.0",
"dompdf/php-svg-lib": "^1.0.0",
"ext-dom": "*",
"ext-mbstring": "*",
"masterminds/html5": "^2.0",
"php": "^7.1 || ^8.0"
},
"require-dev": {
"ext-gd": "*",
"ext-json": "*",
"ext-zip": "*",
"mockery/mockery": "^1.3",
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
"squizlabs/php_codesniffer": "^3.5",
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
},
"suggest": {
"ext-gd": "Needed to process images",
"ext-gmagick": "Improves image processing performance",
"ext-imagick": "Improves image processing performance",
"ext-zlib": "Needed for pdf stream compression"
},
"type": "library",
"autoload": {
"psr-4": {
"Dompdf\\": "src/"
},
"classmap": [
"lib/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "The Dompdf Community",
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
}
],
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
"homepage": "https://github.com/dompdf/dompdf",
"support": {
"issues": "https://github.com/dompdf/dompdf/issues",
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
},
"time": "2025-01-15T14:09:04+00:00"
},
{
"name": "dompdf/php-font-lib",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/dompdf/php-font-lib.git",
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "^7.1 || ^8.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
},
"type": "library",
"autoload": {
"psr-4": {
"FontLib\\": "src/FontLib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "The FontLib Community",
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
}
],
"description": "A library to read, parse, export and make subsets of different types of font files.",
"homepage": "https://github.com/dompdf/php-font-lib",
"support": {
"issues": "https://github.com/dompdf/php-font-lib/issues",
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.1"
},
"time": "2024-12-02T14:37:59+00:00"
},
{
"name": "dompdf/php-svg-lib",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/dompdf/php-svg-lib.git",
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "^7.1 || ^8.0",
"sabberworm/php-css-parser": "^8.4"
},
"require-dev": {
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Svg\\": "src/Svg"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0-or-later"
],
"authors": [
{
"name": "The SvgLib Community",
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
}
],
"description": "A library to read, parse and export to PDF SVG files.",
"homepage": "https://github.com/dompdf/php-svg-lib",
"support": {
"issues": "https://github.com/dompdf/php-svg-lib/issues",
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0"
},
"time": "2024-04-29T13:26:35+00:00"
},
{
"name": "dragonmantank/cron-expression",
"version": "v3.4.0",
@ -2006,6 +2317,258 @@
],
"time": "2024-12-08T08:18:47+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f",
"reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-zlib": "*",
"php-64bit": "^8.2"
},
"require-dev": {
"brianium/paratest": "^7.7",
"ext-zip": "*",
"friendsofphp/php-cs-fixer": "^3.16",
"guzzlehttp/guzzle": "^7.5",
"mikey179/vfsstream": "^1.6",
"php-coveralls/php-coveralls": "^2.5",
"phpunit/phpunit": "^11.0",
"vimeo/psalm": "^6.0"
},
"suggest": {
"guzzlehttp/psr7": "^2.4",
"psr/http-message": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2"
},
"funding": [
{
"url": "https://github.com/maennchen",
"type": "github"
}
],
"time": "2025-01-27T12:07:53+00:00"
},
{
"name": "markbaker/complex",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
},
"time": "2022-12-06T16:21:08+00:00"
},
{
"name": "markbaker/matrix",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
},
"time": "2022-12-02T22:17:43+00:00"
},
{
"name": "masterminds/html5",
"version": "2.10.0",
"source": {
"type": "git",
"url": "https://github.com/Masterminds/html5-php.git",
"reference": "fcf91eb64359852f00d921887b219479b4f21251"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
"reference": "fcf91eb64359852f00d921887b219479b4f21251",
"shasum": ""
},
"require": {
"ext-dom": "*",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
}
},
"autoload": {
"psr-4": {
"Masterminds\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matt Butcher",
"email": "technosophos@gmail.com"
},
{
"name": "Matt Farina",
"email": "matt@mattfarina.com"
},
{
"name": "Asmir Mustafic",
"email": "goetas@gmail.com"
}
],
"description": "An HTML5 parser and serializer.",
"homepage": "http://masterminds.github.io/html5-php",
"keywords": [
"HTML5",
"dom",
"html",
"parser",
"querypath",
"serializer",
"xml"
],
"support": {
"issues": "https://github.com/Masterminds/html5-php/issues",
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
},
"time": "2025-07-25T09:04:22+00:00"
},
{
"name": "monolog/monolog",
"version": "3.9.0",
@ -2507,6 +3070,112 @@
],
"time": "2025-05-08T08:14:37+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "2ea9786632e6fac1aee601b6e426bcc723d8ce13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/2ea9786632e6fac1aee601b6e426bcc723d8ce13",
"reference": "2ea9786632e6fac1aee601b6e426bcc723d8ce13",
"shasum": ""
},
"require": {
"composer/pcre": "^1||^2||^3",
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"maennchen/zipstream-php": "^2.1 || ^3.0",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^8.1",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
"dompdf/dompdf": "^2.0 || ^3.0",
"friendsofphp/php-cs-fixer": "^3.2",
"mitoteam/jpgraph": "^10.3",
"mpdf/mpdf": "^8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1 || ^2.0",
"phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
"phpunit/phpunit": "^10.5",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.5"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"ext-intl": "PHP Internationalization Functions",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/4.5.0"
},
"time": "2025-07-24T05:15:59+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.3",
@ -3271,6 +3940,72 @@
},
"time": "2025-06-25T14:20:11+00:00"
},
{
"name": "sabberworm/php-css-parser",
"version": "v8.9.0",
"source": {
"type": "git",
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9",
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9",
"shasum": ""
},
"require": {
"ext-iconv": "*",
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"require-dev": {
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41",
"rawr/cross-data-providers": "^2.0.0"
},
"suggest": {
"ext-mbstring": "for parsing UTF-8 CSS"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "9.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Sabberworm\\CSS\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Raphael Schweikert"
},
{
"name": "Oliver Klee",
"email": "github@oliverklee.de"
},
{
"name": "Jake Hotson",
"email": "jake.github@qzdesign.co.uk"
}
],
"description": "Parser for CSS Files written in PHP",
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
"keywords": [
"css",
"parser",
"stylesheet"
],
"support": {
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0"
},
"time": "2025-07-11T13:20:48+00:00"
},
{
"name": "symfony/clock",
"version": "v7.3.0",

View File

@ -85,11 +85,11 @@ return [
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'host' => env('DB_HOST_ORDER_GIZI', '127.0.0.1'),
'port' => env('DB_PORT_ORDER_GIZI', '5432'),
'database' => env('DB_DATABASE_ORDER_GIZI', 'laravel'),
'username' => env('DB_USERNAME_ORDER_GIZI', 'root'),
'password' => env('DB_PASSWORD_ORDER_GIZI', ''),
'charset' => env('DB_CHARSET', 'utf8'),
'prefix' => '',
'prefix_indexes' => true,

View File

@ -36,7 +36,7 @@ return [
'database' => [
'driver' => 'database',
'connection' => env('DB_QUEUE_CONNECTION'),
'connection' => env('DB_CONNECTION_ORDER_GIZI'),
'table' => env('DB_QUEUE_TABLE', 'jobs'),
'queue' => env('DB_QUEUE', 'default'),
'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90),

BIN
public/gambar/qris.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -7,6 +7,16 @@ let order_id = sessionStorage.getItem('order_id') || '[]';
// EVENT ON LOAD
// =======================
document.addEventListener('DOMContentLoaded', () => {
const checkCart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const validChart = checkCart.length > 0 && checkCart.every(item =>
Array.isArray(item.pesanan) &&
item.pesanan.length > 0
);
if(!validChart){
window.location.href ='/';
return
}
$("#cartButton").addClass('d-none');
$("#no_order_result").val(order_id)
let currentStep = 0;
@ -57,7 +67,7 @@ document.addEventListener('DOMContentLoaded', () => {
}
}
if (!sessionStorage.getItem('order_id')) {
await submitOrderToServer(); // async function simpan ke server
@ -241,105 +251,114 @@ function renderCartSummary() {
const countDate = pesananList.length;
pesananHTML += `
<div class=" rounded p-2 mb-2" data-item-id="${item.id}" data-index="${i}">
<div class="row g-2 align-items-center">
<div class="rounded border p-3 mb-3 shadow-sm" data-item-id="${item.id}" data-index="${i}">
<div class="row g-3 align-items-center">
<!-- Tanggal -->
<div class="col-12 col-md-3">
<input type="text" class="form-control form-control-sm tanggal-input" id="tanggal-${item.id}-${i}" readonly>
</div>
<!-- Note -->
<div class="col-12 col-md-2">
<button type="button" class="btn btn-outline-success" onclick="notedOrder(${item.id}, ${i})" title="Catatan">
<i class="fa-solid fa-note-sticky"></i> Catatan
</button>
</div>
<!-- Karbohidrat -->
${item.apakah_someday ? `` : `
<div class="col-12 col-md-3">
<select class="form-select form-select-sm karbohidrat-input" onchange="onKarbohidratChange(${item.id}, ${i})">
<option value="">Pilih Karbohidrat</option>
${(karhohidrats || []).map(k => `
<option value="${k.karbohidrat_id}" ${p.karbohidrat_id === k.karbohidrat_id ? 'selected' : ''}>
${k.nama_karbohidrat} (${k.nilai_kalori} kkal)
</option>`).join('')}
</select>
</div>`}
<!-- Tanggal -->
<div class="col-12 col-md-2">
<input type="text" class="form-control form-control-sm tanggal-input" id="tanggal-${item.id}-${i}" readonly placeholder="Pilih Tanggal">
</div>
<!-- Waktu Makan -->
<div class="col-12 col-md-3">
<select class="form-select form-select-sm kategori-pemesanan-input"
data-item-id="${item.id}" data-index="${i}"
onchange="onKategoriChange(${item.id}, ${i}, ${isToday})"
onfocus="this.dataset.previousValue = this.value"
${item.apakah_menu_siang || item.apakah_menu_sore ? '' : 'disabled'}>
<!-- Karbohidrat -->
${item.apakah_someday ? `` : `
<div class="col-12 col-md-3">
<select class="form-select form-select-sm karbohidrat-input" onchange="onKarbohidratChange(${item.id}, ${i})">
<option value="">Pilih Karbohidrat</option>
${(karhohidrats || []).map(k => `
<option value="${k.karbohidrat_id}" ${p.karbohidrat_id === k.karbohidrat_id ? 'selected' : ''}>
${k.nama_karbohidrat} (${k.nilai_kalori} kkal)
</option>
`).join('')}
</select>
</div>`}
${
item.apakah_someday
? (
item.apakah_menu_siang && item.apakah_menu_sore
? `
<option value="Makan Siang" ${p.kategoriPemesanan === 'Makan Siang' ? 'selected' : ''} ${disableSiang ? 'disabled' : ''}>Makan Siang</option>
<option value="Makan Sore" ${p.kategoriPemesanan === 'Makan Sore' ? 'selected' : ''} ${disableSore ? 'disabled' : ''}>Makan Sore</option>
`
: item.apakah_menu_siang
? `<option value="Makan Siang" selected ${disableSiang ? 'disabled' : ''}>Makan Siang</option>`
<!-- Waktu Makan -->
<div class="col-12 col-md-2">
<select class="form-select form-select-sm kategori-pemesanan-input"
data-item-id="${item.id}" data-index="${i}"
onchange="onKategoriChange(${item.id}, ${i}, ${isToday})"
onfocus="this.dataset.previousValue = this.value"
${item.apakah_menu_siang || item.apakah_menu_sore ? '' : 'disabled'}>
${
item.apakah_someday
? (
item.apakah_menu_siang && item.apakah_menu_sore
? `
<option value="Makan Siang" ${p.kategoriPemesanan === 'Makan Siang' ? 'selected' : ''} ${disableSiang ? 'disabled' : ''}>Makan Siang</option>
<option value="Makan Sore" ${p.kategoriPemesanan === 'Makan Sore' ? 'selected' : ''} ${disableSore ? 'disabled' : ''}>Makan Sore</option>
`
: item.apakah_menu_siang
? `<option value="Makan Siang" selected ${disableSiang ? 'disabled' : ''}>Makan Siang</option>`
: item.apakah_menu_sore
? `<option value="Makan Sore" selected ${disableSore ? 'disabled' : ''}>Makan Sore</option>`
? `<option value="Makan Sore" selected ${disableSore ? 'disabled' : ''}>Makan Sore</option>`
: `<option value="" disabled selected>Tidak tersedia</option>`
)
: (
item.apakah_menu_siang && item.apakah_menu_sore
? `
<option value="Makan Siang" ${p.kategoriPemesanan === 'Makan Siang' ? 'selected' : ''}>Makan Siang</option>
<option value="Makan Sore" ${p.kategoriPemesanan === 'Makan Sore' ? 'selected' : ''}>Makan Sore</option>
`
: item.apakah_menu_siang
? `<option value="Makan Siang" selected>Makan Siang</option>`
)
: (
item.apakah_menu_siang && item.apakah_menu_sore
? `
<option value="Makan Siang" ${p.kategoriPemesanan === 'Makan Siang' ? 'selected' : ''}>Makan Siang</option>
<option value="Makan Sore" ${p.kategoriPemesanan === 'Makan Sore' ? 'selected' : ''}>Makan Sore</option>
`
: item.apakah_menu_siang
? `<option value="Makan Siang" selected>Makan Siang</option>`
: item.apakah_menu_sore
? `<option value="Makan Sore" selected>Makan Sore</option>`
? `<option value="Makan Sore" selected>Makan Sore</option>`
: `<option value="" disabled selected>Tidak tersedia</option>`
)
}
</select>
</div>
)
}
</select>
</div>
<!-- Jumlah -->
<div class="col-6 col-md-2">
<div class="d-flex align-items-center justify-content-between">
<button class="btn btn-sm btn-outline-success" onclick="decrement(${item.id}, ${i})">
<i class="fa fa-minus"></i>
</button>
<input type="text" class="form-control form-control-sm text-center mx-2 jumlah-input"
value="${p.jumlah}" readonly style="width: 70px;" id="jumlah-${item.id}-${i}">
<button class="btn btn-sm btn-outline-success" onclick="increment(${item.id}, ${i})">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
<!-- Jumlah -->
<div class="col-6 col-md-2">
<div class="d-flex align-items-center justify-content-between">
<button class="btn btn-sm btn-outline-success" onclick="decrement(${item.id}, ${i})">
<i class="fa fa-minus"></i>
</button>
<input type="text" class="form-control form-control-sm text-center mx-2 jumlah-input"
value="${p.jumlah}" readonly style="width: 60px;" id="jumlah-${item.id}-${i}">
<button class="btn btn-sm btn-outline-success" onclick="increment(${item.id}, ${i})">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
<!-- Hapus -->
<div class="col-6 col-md-1 text-end">
${countDate > 1
? `<button class="btn btn-sm btn-danger" onclick="removeOrderDate(${item.id}, ${i}, ${countDate})">
<i class="fa fa-trash"></i>
</button>`
: ''}
</div>
<!-- Tombol Hapus -->
<div class="col-6 col-md-1 text-end">
${countDate > 1
? `<button class="btn btn-sm btn-danger" onclick="removeOrderDate(${item.id}, ${i}, ${countDate})" title="Hapus">
<i class="fa fa-trash"></i>
</button>`
: ''
}
</div>
</div>
</div>
</div>
</div>
`;
});
const itemHTML = `
<div class="card mb-3 shadow-sm position-relative">
<div class="d-flex flex-column flex-md-row">
<button type="button" class="btn btn-sm btn-outline-danger position-absolute top-0 end-0 m-2"
onclick="removeCartItem(${item.id})">
Hapus
</button>
<div class="p-2 d-flex justify-content-center align-items-center" style="flex: 0 0 300px;">
<img src="gambar/${item.foto || 'default.jpg'}" alt="${item.nama_menu}"
class="img-fluid rounded" style="max-height: 180px; width: 100%; object-fit: cover;">
</div>
<div class="flex-grow-1 position-relative">
<button type="button" class="btn btn-sm btn-outline-danger position-absolute top-0 end-0 m-2"
onclick="removeCartItem(${item.id})">
Hapus
</button>
<div class="card-body">
<h5 class="card-title">${item.nama_menu}</h5>
@ -356,15 +375,15 @@ function renderCartSummary() {
${item.kalori
? `<div class="mb-2 small text-muted"><i class="fa-solid fa-bolt me-1"></i> Kalori: <strong>${item.kalori} kkal</strong></div>`
: ''}
<div class="mb-2 small text-muted"><strong>Silakan isi tanggal pemesanan dan pilih karbohidrat yang diinginkan</strong></div>
<div class="mb-2 small text-muted"><strong>Silakan isi tanggal pemesanan, catatan pemesanan (opsional) dan pilih karbohidrat yang diinginkan</strong></div>
${pesananHTML}
<div class="mt-3 d-flex justify-content-between align-items-center flex-wrap gap-2">
<button class="btn btn-sm btn-outline-success"
onclick="addOrderDate(${item.id}, ${item.apakah_menu_sore})">
+ Tambah Tanggal
</button>'
<div><strong>Total:</strong> <span class="text-success">Rp ${itemTotal.toLocaleString('id-ID')}</span></div>
</div>
</div>
@ -422,7 +441,6 @@ function onKategoriChange(itemId, index, isToday) {
const kategori = selectEl.value;
let now = new Date();
let jam = now.getHours();
console.log(isToday);
if (kategori === "Makan Siang" && isToday && jam >= 10) {
batasLewat = true;
@ -554,6 +572,8 @@ function validateCartBeforeSubmit() {
let errorMessage = "";
cart.forEach((item, index) => {
console.log(item.apakah_someday);
const pesananList = item.pesanan || [];
pesananList.forEach((pesanan, i) => {
if (!pesanan.tgl) {
@ -565,7 +585,7 @@ function validateCartBeforeSubmit() {
} else if (!pesanan.jumlah || pesanan.jumlah <= 0) {
isValid = false;
errorMessage = `Jumlah harus lebih dari 0 pada item "${item.nama_menu}" (baris ${i + 1})`;
}else if(!pesanan.karbohidrat_id){
}else if(!pesanan.karbohidrat_id && !item?.apakah_someday){
isValid = false;
errorMessage = `Karbohidrat belum diisi pada item "${item.nama_menu}" (baris ${i + 1})`
}
@ -582,7 +602,9 @@ function hitungTotalHarga(){
let total =0;
cart.forEach(item => {
const harga = biodata.jenis_customer === "Karyawan RSAB Harapan Kita" ? item.harga_karyawan || 0 : item.harga_public || 0
const harga = biodata.jenis_customer === "Karyawan RSAB Harapan Kita" ? item.harga_karyawan : item.harga_public || 0
console.log(harga);
const itemTotal = item.pesanan?.reduce((sum, p) => sum + (p.jumlah * harga), 0);
total += itemTotal
})
@ -619,9 +641,9 @@ function initFlatpickrTersedia(item, i) {
const totalMenitFlatSekarang = jamFlat * 60 + menitFlat;
const menitBatasFlat = 13 * 60;
const lewatBatasNormal = totalMenitFlatSekarang >= menitBatasFlat;
// Ambil string tgl_tersedia dan ubah jadi array tanggal lengkap
const dayNumbers = (item.tgl_tersedia || "")
.split(',')
@ -650,7 +672,8 @@ function initFlatpickrTersedia(item, i) {
availableDates.push(fullDateStr);
} else {
const selisihHari = Math.floor((fullDate - now) / (1000 * 60 * 60 * 24));
console.log(selisihHari);
if (selisihHari >= 1 || (selisihHari === 1 && !lewatBatasNormal)) {
availableDates.push(fullDateStr);
}
@ -659,6 +682,7 @@ function initFlatpickrTersedia(item, i) {
}
let minTanggal = 'today';
// Jika item adalah someday dan waktu sekarang sudah lewat 13:00
@ -669,23 +693,15 @@ function initFlatpickrTersedia(item, i) {
}
if(!item.apakah_someday){
availableDates = availableDates.filter(dateStr => {
const dateObj = new Date(dateStr);
const selisihHari = Math.floor((dateObj - now) / (1000 * 60 * 60 * 24));
return selisihHari >= 1 || (selisihHari === 1 && !lewatBatasNormal);
});
}
flatpickr(`#tanggal-${item.id}-${i}`, {
dateFormat: "Y-m-d",
...(item?.apakah_someday ? { minDate: minTanggal,} : {enable : availableDates}),
...(item?.apakah_someday ? {minDate: minTanggal} : {enable:availableDates}),
defaultDate: item.pesanan[i]?.tgl || null,
onChange: function(selectedDates, dateStr) {
onTanggalChange(item.id, i, dateStr);
}
});
});
}
function increment(itemId, index) {
@ -708,6 +724,7 @@ function decrement(itemId, index) {
}
function toggleBuktiPembayaran() {
const metode = document.getElementById("cara_pembayaran").value;
const buktiSection = document.getElementById("bukti_section");
@ -717,9 +734,11 @@ function toggleBuktiPembayaran() {
if (metode === "billing") {
buktiSection.style.display = "none";
buktiInput.required = false;
$("#modalActionMethodBillingOrder").modal('show')
} else {
buktiSection.style.display = "block";
buktiInput.required = true;
$("#modalActionMethodBillingOrder").modal('hide')
}
}
@ -741,3 +760,39 @@ function validateTanggalPemesanan(item, tglDipilih) {
return { valid: true };
}
function notedOrder(id, i) {
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item = cart.find(item => item.id === id);
const note = item?.pesanan?.[i]?.catatan || '';
$("#note_order").val(note);
$("#submitNote").data('id', id).data('index', i);
$("#notedPOrder").modal('show');
}
document.querySelectorAll('.auto-expand').forEach(function(textarea){
textarea.addEventListener('input', function () {
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
});
})
document.getElementById('submitNote').addEventListener('click', function(e){
e.preventDefault()
const id = $(this).data('id')
const index = $(this).data('index')
const noted = $("#note_order").val()
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item =cart.find(item => item.id === id)
console.log(id, index, item);
if(item && item.pesanan && item.pesanan[index]){
item.pesanan[index].catatan = noted
sessionStorage.setItem('cart', JSON.stringify(cart));
$("#notedPOrder").modal('hide')
}else{
alert('gagal menyimpan catatan')
}
});

View File

@ -376,7 +376,7 @@
id_menu :idMenu,
nama_menu : $("#cathering_order_name").text(),
harga_karyawan : parseRupiahToNumber($("#cathering_order_price_karyawan").text()),
harga_kp : parseRupiahToNumber($("#cathering_order_price_keluarga_pasien").text()),
harga_public : parseRupiahToNumber($("#cathering_order_price_public").text()),
foto: resultFoto,
jenis_menu: $('#cathering_order_jenis_menu').text(),
deskripsi:$("#cathering_order_deskripsi").text(),

View File

@ -3,3 +3,5 @@ const datatablePekerjaan = $("#datatablePekerjaan")
const modalDetailOrder = document.getElementById('modalDetailOrder');
const modalActionOrder = document.getElementById('modalActionApproveOrder');
const modalExport = document.getElementById('modalExportPekerjaan');

View File

@ -106,3 +106,7 @@ document.getElementById('formActionApproveOrder').addEventListener('submit', fun
});
});
});
function exportPekerjaan(){
new bootstrap.Modal(modalExport).show()
}

View File

@ -10,3 +10,6 @@ const formActionApproveBillingOrder = $("#formActionApproveBillingOrder")
const modalActionProgressOrder = document.getElementById('modalActionProgressOrder')
const formActionProgressOrder = $("#formActionProgressOrder")
const modalExport = document.getElementById('modalExportPending');

View File

@ -143,3 +143,7 @@ function approveProgress(order_id){
new bootstrap.Modal(modalActionProgressOrder).show();
fetchDetailOrder(order_id)
}
function exportPending(){
new bootstrap.Modal(modalExport).show();
}

View File

@ -2,3 +2,5 @@ const datatableSelesai = $("#datatablePesananSelesai")
const modalActionSelesaiOrder = document.getElementById('modalActionSelesaiOrder')
const formActionSelesaiOrder = $("#formActionSelesaiOrder")
const modalExport = document.getElementById('modalExportSelesai')

View File

@ -106,3 +106,7 @@ function orderSelesai(order_id){
new bootstrap.Modal(modalActionSelesaiOrder).show();
fetchDetailOrder(order_id)
}
function exportSelesai(){
new bootstrap.Modal(modalExport).show();
}

View File

@ -9,20 +9,34 @@
<!-- Card Master Menu -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Pekerjaan <strong id="confirm_pekerjaan_time"></strong></h5>
<div class="input-group input-group-sm" style="width: 240px;">
<span class="input-group-text bg-white">
<i class="fa fa-calendar-alt"></i>
</span>
<input
type="text"
class="form-control tanggal-input"
id="tanggal"
placeholder="Pilih tanggal"
readonly>
</div>
<div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
<!-- Judul Kiri -->
<h5 class="mb-0">
Pekerjaan <strong id="confirm_pekerjaan_time"></strong>
</h5>
<!-- Kanan: Tombol Export + Input Tanggal -->
<div class="d-flex align-items-center gap-2">
<!-- Tombol Export -->
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="exportPekerjaan()">
<i class="fa fa-download me-1"></i> Export
</button>
<!-- Input Tanggal -->
<div class="input-group input-group-sm" style="width: 240px;">
<span class="input-group-text bg-white">
<i class="fa fa-calendar-alt"></i>
</span>
<input
type="text"
class="form-control tanggal-input"
id="tanggal"
placeholder="Pilih tanggal"
readonly>
</div>
</div>
</div>
<div class="card-body">
<table class="table" id="datatablePekerjaan"></table>
</div>
@ -31,6 +45,7 @@
@include('dashboard.pesanan.pekerjaan.modal.detail')
@include('dashboard.pesanan.pekerjaan.modal.action')
@include('dashboard.pesanan.pekerjaan.modal.export')
<script src="{{ ver('/js/pekerjaan/_init.js') }}"></script>
<script src="{{ ver('/js/pekerjaan/dt.js') }}"></script>

View File

@ -0,0 +1,43 @@
<!-- Modal -->
<div class="modal fade" id="modalExportPekerjaan" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h5 class="modal-title fs-5">Export Data</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<!-- Modal Form -->
<form action="/dashboard/pekerjaan/export" method="POST">
@csrf
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="exampleFormControlInput1">Start Date</label>
<input type="date" class="form-control" name="start_date" required>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="exampleFormControlInput1">End Date</label>
<input type="date" class="form-control" name="end_date" required>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<button type="submit" class="btn btn-primary">Export</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,170 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Daftar Pesanan</title>
<style>
body {
font-family: Arial, sans-serif;
font-size: 10.5px;
line-height: 1.5;
margin: 40px;
color: #333;
}
.header {
text-align: center;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
.header .sub-title {
margin: 4px 0 0;
font-size: 13px;
color: #666;
}
.header h2 {
margin: 0;
font-size: 20px;
text-transform: uppercase;
}
.header p {
margin: 2px 0 0;
font-size: 12px;
color: #666;
}
.meta {
text-align: right;
margin-bottom: 10px;
font-size: 12px;
font-weight: bold;
color: #444;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 8px;
}
th, td {
border: 1px solid #bbb;
padding: 6px 8px;
}
th {
background-color: #d4d4d465;
text-align: center;
}
td {
vertical-align: top;
font-size: 11px;
}
th:nth-child(7), td:nth-child(7) {
width: 15%; /* buat lebih panjang dari kolom lain */
}
th:nth-child(4), td:nth-child(4) { width: 60px; text-align: center; }
th:nth-child(6), td:nth-child(6) { width: 110px; text-align: center; }
.keterangan {
font-size: 10px;
line-height: 1.4;
}
.footer {
position: absolute;
bottom: 30px;
width: 100%;
text-align: center;
font-size: 10px;
color: #999;
}
</style>
</head>
<body>
<div class="header">
<h2>Daftar Pesanan</h2>
@if($startDate === $endDate)
<div class="sub-title">Periode: {{ $startDate }} </div>
@else
<div class="sub-title">Periode: {{ $startDate }} - {{ $endDate }}</div>
@endif
<div class="sub-title">RSAB Harapan Kita</div>
</div>
<div class="meta">
Dicetak pada: {{ $waktu_cetak }}
</div>
<table>
<thead>
<tr>
<th>No</th>
<th>Nama Pemesan</th>
<th>Status Order</th>
<th>Tanggal Antar</th>
<th>Waktu Pemesanan</th>
<th>Menu</th>
<th>Keterangan</th>
<th>Jumlah</th>
<th>Harga Satuan (Rp)</th>
</tr>
</thead>
<tbody>
@forelse ($pekerjaan as $i => $row)
<tr>
<td>{{ $i + 1 }}</td>
<td>
{{ $row['order']['nama_pemesan'] ?? '-' }}
@if (!empty($row['order']['jenis_customer']))
<br><small>({{ $row['order']['jenis_customer'] }})</small>
@endif
</td>
<td>{{ $row['status_order'] ?? '-' }}</td>
<td style="text-align: center;">
{{ isset($row['tgl_antar'])
? \Carbon\Carbon::parse($row['tgl_antar'])->locale('id')->translatedFormat('d F Y')
: '-' }}
</td>
<td>{{ $row['type'] ?? '-' }}</td>
<td>{{ $row['menu']['nama_menu'] ?? '-' }}</td>
<td class="keterangan">
@php
$jenis = strtolower($row['order']['jenis_customer'] ?? '');
@endphp
@if ($jenis === 'keluarga pasien / penunggu pasien')
Nama Pasien: <strong>{{ $row['order']['nama_pasien'] ?? '-' }}</strong><br>
Ruang: <strong>{{ $row['order']['ruang_perawatan'] ?? '-' }} / {{ $row['order']['no_kamar_perawatan'] ?? '-' }}</strong><br>
Kelas: <strong>{{ $row['order']['kelas_perawatan'] ?? '-' }}</strong>
@elseif ($jenis === 'masyarakat umum')
{{ $row['order']['alamat'] ?? '-' }}
@elseif ($jenis === 'karyawan rsab harapan kita')
Bagian: <strong>{{ $row['order']['bagian_instalasi'] ?? '-' }}</strong><br>
Ext: <strong>{{ $row['order']['no_ekstensien'] ?? '-' }}</strong>
@else
-
@endif
</td>
<td>{{ $row['jumlah'] ?? 0 }}</td>
<td>{{ number_format($row['harga_satuan'], 0, ',', '.') }}</td>
</tr>
@empty
<tr>
<td colspan="9" style="text-align: center; color: #888;">Tidak ada data</td>
</tr>
@endforelse
</tbody>
</table>
<div class="footer">
&copy; {{ date('Y') }} RSAB Harapan Kita Sistem Order Gizi
</div>
</body>
</html>

View File

@ -11,6 +11,10 @@
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Pesanan Pending <strong id="confirm_date_pesanan_pending"></strong></h5>
<div class="d-flex align-items-center gap-2">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="exportPending()">
<i class="fa fa-download me-1"></i> Export
</button>
<div class="input-group input-group-sm" style="width: 240px;">
<span class="input-group-text bg-white">
<i class="fa fa-calendar-alt"></i>
@ -22,6 +26,8 @@
placeholder="Pilih tanggal"
readonly>
</div>
</div>
</div>
<div class="card-body">
<table class="table" id="datatablePesananPending"></table>
@ -32,6 +38,7 @@
@include('dashboard.pesanan.pending.modal.action')
@include('dashboard.pesanan.pending.modal.confirmBilling')
@include('dashboard.pesanan.pending.modal.actionProgressPesanan')
@include('dashboard.pesanan.pending.modal.export')
<script src="{{ ver('/js/pesanan_pending/_init.js') }}"></script>
<script src="{{ ver('/js/pesanan_pending/dt.js') }}"></script>

View File

@ -0,0 +1,43 @@
<!-- Modal -->
<div class="modal fade" id="modalExportPending" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h5 class="modal-title fs-5">Export Data</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<!-- Modal Form -->
<form action="/dashboard/pending/export" method="POST">
@csrf
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="exampleFormControlInput1">Start Date</label>
<input type="date" class="form-control" name="start_date" required>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="exampleFormControlInput1">End Date</label>
<input type="date" class="form-control" name="end_date" required>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<button type="submit" class="btn btn-primary">Export</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,162 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Laporan Pesanan</title>
<style>
body {
font-family: Arial, sans-serif;
font-size: 11px;
line-height: 1.5;
margin: 40px;
color: #333;
}
.header {
text-align: center;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
.header h2 {
margin: 0;
font-size: 20px;
text-transform: uppercase;
}
.header .sub-title {
margin: 4px 0 0;
font-size: 13px;
color: #666;
}
.meta {
text-align: right;
margin-bottom: 15px;
font-size: 12px;
font-weight: bold;
color: #444;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 5px;
table-layout: fixed;
}
th, td {
border: 1px solid #ccc;
padding: 6px 8px;
word-wrap: break-word;
word-break: break-word;
}
th {
background-color: #f0f0f0;
text-align: center;
font-size: 11px;
}
td {
font-size: 11px;
vertical-align: top;
}
tr:nth-child(even) td {
background-color: #f9f9f9;
}
th:nth-child(1), td:nth-child(1) { width: 30px; text-align: center; }
th:nth-child(2), td:nth-child(2) { width: 90px; }
th:nth-child(3), td:nth-child(3) { width: 140px; }
th:nth-child(4), td:nth-child(4) { width: 150px; }
th:nth-child(5), td:nth-child(5) { width: 50px; text-align: center; }
th:nth-child(6), td:nth-child(6) { width: 80px; text-align: right; }
th:nth-child(7), td:nth-child(7) { width: 90px; text-align: center; }
th:nth-child(8), td:nth-child(8) { width: 60px; text-align: center; }
.footer {
position: absolute;
bottom: 30px;
width: 100%;
text-align: center;
font-size: 10px;
color: #999;
}
</style>
</head>
<body>
<div class="header">
<h2>Laporan Pesanan Pending</h2>
@if($startDate === $endDate)
<div class="sub-title">Periode: {{ $startDate }} </div>
@else
<div class="sub-title">Periode: {{ $startDate }} - {{ $endDate }}</div>
@endif
<div class="sub-title">RSAB Harapan Kita</div>
</div>
<div class="meta">
Dicetak pada: {{ $waktu_cetak }}
</div>
<table>
<thead>
<tr>
<th>No</th>
<th>No Order</th>
<th>Nama Pemesan</th>
<th>Menu</th>
<th>Status Order</th>
<th>Jumlah</th>
<th>Harga Satuan (Rp)</th>
<th>Tanggal Antar</th>
<th>Waktu</th>
</tr>
</thead>
<tbody>
@php $no = 1; @endphp
@forelse ($orders as $order)
@foreach ($order->orderDetail as $i => $detail)
<tr>
<td style="text-align: center;">{{ $i === 0 ? $no++ : '' }}</td>
<td>{{ $i === 0 ? $order->no_order : '' }}</td>
<td>
@if ($i === 0)
{{ $order->nama_pemesan }}
@if ($order->jenis_customer)
<br><small>({{ $order->jenis_customer }})</small>
@endif
@endif
</td>
<td>{{ $detail->menu->nama_menu ?? '-' }}</td>
<td>{{ $detail->status_order ?? '-' }}</td>
<td style="text-align: center;">{{ $detail->jumlah }}</td>
<td style="text-align: right;">{{ number_format($detail->harga_satuan, 0, ',', '.') }}</td>
<td style="text-align: center;">
{{ $detail->tgl_antar
? \Carbon\Carbon::parse($detail->tgl_antar)->locale('id')->translatedFormat('d F Y')
: '-' }}
</td>
<td style="text-align: center;">{{ $detail->type }}</td>
</tr>
@endforeach
@empty
<tr>
<td colspan="9" style="text-align: center; color: #888;">Tidak ada data pesanan</td>
</tr>
@endforelse
</tbody>
</table>
<div class="footer">
&copy; {{ date('Y') }} RSAB Harapan Kita Sistem Order Gizi
</div>
</body>
</html>

View File

@ -11,6 +11,10 @@
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Pesanan Selesai</h5>
<div class="d-flex align-items-center gap-2">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="exportSelesai()">
<i class="fa fa-download me-1"></i> Export
</button>
<div class="input-group input-group-sm" style="width: 240px;">
<span class="input-group-text bg-white">
<i class="fa fa-calendar-alt"></i>
@ -22,6 +26,8 @@
placeholder="Pilih tanggal"
readonly>
</div>
</div>
</div>
<div class="card-body">
<table class="table" id="datatablePesananSelesai"></table>
@ -30,6 +36,7 @@
</div>
@include('dashboard.pesanan.selesai.modal.actionPesananSelesai')
@include('dashboard.pesanan.selesai.modal.export')
<script src="{{ ver('/js/pesanan_selesai/_init.js') }}"></script>
<script src="{{ ver('/js/pesanan_selesai/dt.js') }}"></script>

View File

@ -0,0 +1,43 @@
<!-- Modal -->
<div class="modal fade" id="modalExportSelesai" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h5 class="modal-title fs-5">Export Data</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<!-- Modal Form -->
<form action="/dashboard/selesai/export" method="POST">
@csrf
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="exampleFormControlInput1">Start Date</label>
<input type="date" class="form-control" name="start_date" required>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="exampleFormControlInput1">End Date</label>
<input type="date" class="form-control" name="end_date" required>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<button type="submit" class="btn btn-primary">Export</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,162 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Laporan Pesanan</title>
<style>
body {
font-family: Arial, sans-serif;
font-size: 11px;
line-height: 1.5;
margin: 40px;
color: #333;
}
.header {
text-align: center;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
.header h2 {
margin: 0;
font-size: 20px;
text-transform: uppercase;
}
.header .sub-title {
margin: 4px 0 0;
font-size: 13px;
color: #666;
}
.meta {
text-align: right;
margin-bottom: 15px;
font-size: 12px;
font-weight: bold;
color: #444;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 5px;
table-layout: fixed;
}
th, td {
border: 1px solid #ccc;
padding: 6px 8px;
word-wrap: break-word;
word-break: break-word;
}
th {
background-color: #f0f0f0;
text-align: center;
font-size: 11px;
}
td {
font-size: 11px;
vertical-align: top;
}
tr:nth-child(even) td {
background-color: #f9f9f9;
}
th:nth-child(1), td:nth-child(1) { width: 30px; text-align: center; }
th:nth-child(2), td:nth-child(2) { width: 90px; }
th:nth-child(3), td:nth-child(3) { width: 140px; }
th:nth-child(4), td:nth-child(4) { width: 150px; }
th:nth-child(5), td:nth-child(5) { width: 50px; text-align: center; }
th:nth-child(6), td:nth-child(6) { width: 80px; text-align: right; }
th:nth-child(7), td:nth-child(7) { width: 90px; text-align: center; }
th:nth-child(8), td:nth-child(8) { width: 60px; text-align: center; }
.footer {
position: absolute;
bottom: 30px;
width: 100%;
text-align: center;
font-size: 10px;
color: #999;
}
</style>
</head>
<body>
<div class="header">
<h2>Laporan Pesanan Selesai</h2>
@if($startDate === $endDate)
<div class="sub-title">Periode: {{ $startDate }} </div>
@else
<div class="sub-title">Periode: {{ $startDate }} - {{ $endDate }}</div>
@endif
<div class="sub-title">RSAB Harapan Kita</div>
</div>
<div class="meta">
Dicetak pada: {{ $waktu_cetak }}
</div>
<table>
<thead>
<tr>
<th>No</th>
<th>No Order</th>
<th>Nama Pemesan</th>
<th>Menu</th>
<th>Status Order</th>
<th>Jumlah</th>
<th>Harga Satuan (Rp)</th>
<th>Tanggal Antar</th>
<th>Waktu</th>
</tr>
</thead>
<tbody>
@php $no = 1; @endphp
@forelse ($orders as $order)
@foreach ($order->orderDetail as $i => $detail)
<tr>
<td style="text-align: center;">{{ $i === 0 ? $no++ : '' }}</td>
<td>{{ $i === 0 ? $order->no_order : '' }}</td>
<td>
@if ($i === 0)
{{ $order->nama_pemesan }}
@if ($order->jenis_customer)
<br><small>({{ $order->jenis_customer }})</small>
@endif
@endif
</td>
<td>{{ $detail->menu->nama_menu ?? '-' }}</td>
<td>{{ $detail->status_order ?? '-' }}</td>
<td style="text-align: center;">{{ $detail->jumlah }}</td>
<td style="text-align: right;">{{ number_format($detail->harga_satuan, 0, ',', '.') }}</td>
<td style="text-align: center;">
{{ $detail->tgl_antar
? \Carbon\Carbon::parse($detail->tgl_antar)->locale('id')->translatedFormat('d F Y')
: '-' }}
</td>
<td style="text-align: center;">{{ $detail->type }}</td>
</tr>
@endforeach
@empty
<tr>
<td colspan="9" style="text-align: center; color: #888;">Tidak ada data pesanan</td>
</tr>
@endforelse
</tbody>
</table>
<div class="footer">
&copy; {{ date('Y') }} RSAB Harapan Kita Sistem Order Gizi
</div>
</body>
</html>

View File

@ -46,6 +46,8 @@
</div>
</div>
</section>
@include('guest.checkout.modal.noteOrder')
@include('guest.checkout.modal.confirmPaymentBilling')
<script>
const karhohidrats = {!! json_encode($karbohidrat) !!}
</script>

View File

@ -0,0 +1,36 @@
<!-- Modal -->
<div class="modal fade" id="modalActionMethodBillingOrder" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-md">
<div class="modal-content shadow rounded-4">
<!-- Modal Header -->
<div class="modal-header bg-warning bg-opacity-10 border-bottom-0">
<h5 class="modal-title fw-bold text-warning">
<i class="fa-solid fa-circle-info me-2"></i> Informasi Pembayaran Billing
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Tutup"></button>
</div>
<!-- Modal Body -->
<div class="modal-body">
<p class="mb-2">
<strong>Perhatian:</strong> Metode pembayaran <strong>Billing</strong> hanya tersedia untuk:
</p>
<ul class="mb-3 ps-3">
<li>Pasien rawat inap dengan jaminan <strong>Umum</strong> atau <strong>Asuransi</strong> Memiliki fasilitas <strong>Makanan Pendamping</strong></li>
</ul>
<p class="text-muted small">
Jika Anda tidak termasuk dalam kriteria tersebut, silakan gunakan metode pembayaran <strong>Transfer Bank</strong> .
</p>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary rounded-pill" data-bs-dismiss="modal">
Saya Mengerti
</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,28 @@
<div class="modal fade" id="notedPOrder" tabindex="-1" aria-labelledby="notedPOrderLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold" id="notedPOrderLabel">Pesanan Catering RSAB Harapan Kita</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="notedForm">
<div class="modal-body">
<div class="row p-3">
<div class="col-md-12">
<div class="form-floating">
<textarea class="form-control auto-expand" id="note_order" placeholder="catatan pemesanan" rows="1" style="resize: none; overflow-y: hidden;"></textarea>
<label>Catatan</label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<button type="button" class="btn btn-success" id="submitNote"> Simpan </button>
</div>
</form>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
<div class="card shadow-sm p-4">
<div class="row justify-content-center text-center">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 mb-3">
<img src="gambar/images.jpg" alt="Pembayaran"
<img src="gambar/qris.jpg" alt="Pembayaran"
class="img-fluid rounded shadow w-100"
style="max-width: 500px; height: auto;">
</div>
@ -15,63 +15,63 @@
<div class="text-center mb-3">
<h6 class="fw-bold">Detail Pembayaran</h6>
</div>
<ul class="list-group list-group-flush mb-3 shadow-sm rounded overflow-hidden">
<!-- No Order -->
<li class="list-group-item">
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-2">
<span>No Order</span>
<div class="d-flex flex-column align-items-sm-end w-80">
<div class="d-flex justify-content-sm-end mb-1">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="copyNoOrder()">
<div class="card shadow-sm mb-3 rounded">
<div class="card-body">
<!-- No Order -->
<div class="row mb-3 align-items-center">
<div class="col-md-6 col-sm-12 fw-semibold">No Order</div>
<div class="col-md-6 col-sm-12 text-sm-end">
<div class="d-flex justify-content-between justify-content-sm-end align-items-center gap-2">
</div>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="copyNoOrder()">
<i class="fa fa-copy me-1"></i> Salin
</button>
</div>
<strong id="no_order_display" class="d-block text-break text-wrap text-start text-sm-end small"></strong>
</div>
</button><strong id="no_order_display" class="d-block small text-break text-wrap text-sm-end"></strong>
</div>
</div>
</li>
<!-- Bank -->
<div class="row mb-3">
<div class="col-md-6 col-sm-12 fw-semibold">Bank</div>
<div class="col-md-6 col-sm-12 text-sm-end">Bank BCA</div>
</div>
<!-- Bank -->
<li class="list-group-item d-flex justify-content-between">
<span>Bank</span>
<strong>Bank BCA</strong>
</li>
<!-- Nama Rekening -->
<div class="row mb-3">
<div class="col-md-6 col-sm-12 fw-semibold">Nama Rek.</div>
<div class="col-md-6 col-sm-12 text-sm-end">RSAB Harapan Kita</div>
</div>
<!-- Nama Rekening -->
<li class="list-group-item d-flex justify-content-between">
<span>Nama Rek.</span>
<strong>RSAB Harapan Kita</strong>
</li>
<!-- No Rek -->
<li class="list-group-item">
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-2">
<span>No.Rek</span>
<div class="d-flex flex-column align-items-sm-end w-80">
<div class="d-flex justify-content-sm-end mb-1">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="copyNoOrder()">
<!-- No Rek -->
<div class="row mb-3 align-items-center">
<div class="col-md-6 col-sm-12 fw-semibold">No.Rek</div>
<div class="col-md-6 col-sm-12 text-sm-end">
<div class="d-flex justify-content-between justify-content-sm-end align-items-center gap-2">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="copyNoRek()">
<i class="fa fa-copy me-1"></i> Salin
</button>
</div>
<strong id="noRekText">1234-5678-9101</strong>
</button>
</div>
<strong id="noRekText" class="d-block text-sm-end">1234-5678-9101</strong>
</div>
</div>
</li>
<!-- Nominal -->
<li class="list-group-item d-flex justify-content-between">
<span>Nominal</span>
<strong id="no_order_price" class=""></strong>
</li>
<!-- Nominal -->
<div class="row mb-3">
<div class="col-md-6 col-sm-12 fw-semibold">Nominal</div>
<div class="col-md-6 col-sm-12 text-sm-end" id="no_order_price">Rp 0</div>
</div>
<!-- Waktu Pembayaran -->
<div class="row mb-2">
<div class="col-md-6 col-sm-12 fw-semibold">Waktu Pembayaran</div>
<div class="col-md-6 col-sm-12 text-sm-end" id="countdownPayment"></div>
</div>
</div>
</div>
<!-- Batas Waktu -->
<li class="list-group-item d-flex justify-content-between">
<span>Waktu Pembayaran</span>
<strong id="countdownPayment"></strong>
</li>
</ul>
<p class="text-muted small text-center px-2">
Mohon untuk melakukan pembayaran sebelum batas waktu yang tertera, lalu unggah bukti pembayaran sebagai konfirmasi.
</p>

View File

@ -0,0 +1,25 @@
<div style='font-family: Arial, sans-serif; max-width: 600px; margin: auto; border: 1px solid #eee; padding: 24px;'>
<h2 style='color: #28a745;'> Pembayaran Berhasil Diverifikasi</h2>
<p>Halo, <strong>{$this->nama}</strong>,</p>
<p>Pembayaran kamu untuk pesanan <strong>#{$this->no_order}</strong> telah berhasil kami verifikasi.</p>
<table style='margin-top: 16px; width: 100%; border-collapse: collapse;'>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Nomor Order</td>
<td style='padding: 8px; border: 1px solid #ddd;'>{$this->no_order}</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Total Pembayaran</td>
<td style='padding: 8px; border: 1px solid #ddd;'>Rp " . number_format($this->total_harga, 0, ',', '.') . "</td>
</tr>
<tr>
<td style='padding: 8px; border: 1px solid #ddd;'>Status</td>
<td style='padding: 8px; border: 1px solid #ddd; color: green;'>Pembayaran Diterima</td>
</tr>
</table>
<p style='margin-top: 24px;'>Pesanan kamu sedang kami proses. Silakan tunggu pemberitahuan berikutnya untuk pengambilan makanan.</p>
<hr style='margin-top: 40px;'>
<p style='text-align: center; font-size: 12px; color: #888;'>© " . date('Y') . " RSAB Harapan Kita</p>
</div>

View File

@ -0,0 +1,12 @@
<x-mail::message>
# Introduction
The body of your message.
<x-mail::button :url="''">
Button Text
</x-mail::button>
Thanks,<br>
{{ config('app.name') }}
</x-mail::message>

View File

@ -8,6 +8,8 @@ use App\Http\Controllers\KarbohidratController;
use App\Http\Controllers\KlasifikasiMenuController;
use App\Http\Controllers\MenuController;
use App\Http\Controllers\PesananController;
use App\Mail\NotifikasiCustomer;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Route;
@ -43,16 +45,19 @@ Route::group(['middleware' => ['auth']], function(){
Route::get('/pending', [PesananController::class, 'index']);
Route::get('datatable/pending', [PesananController::class, 'getDataPending']);
Route::post('pending/export', [PesananController::class, 'exportPending']);
Route::put('/pending/action/{order_id}', [PesananController::class, 'actionOrder']);
Route::put('/pending/action-billing/{order_id}', [PesananController::class, 'actionOrderViaBilling']);
Route::get('/pending/action-progress-order/{order_id}', [PesananController::class, 'getDataOrderDetail']);
Route::post('/pending/update-detail-status/{order_id}', [PesananController::class, 'updateDetailStatusOrder']);
Route::get('/selesai', [PesananController::class, 'indexSelesai']);
Route::post('/selesai/export', [PesananController::class, 'exportSelesai']);
Route::get('datatable/selesai', [PesananController::class, 'getDataSelesai']);
Route::get('/pekerjaan', [PesananController::class, 'pekerjaan']);
Route::get('datatable/pekerjaan', [PesananController::class, 'getPekerjaan']);
Route::post('pekerjaan/export', [PesananController::class, 'exportPekerjaan']);
Route::get('/pekerjaan/detail/{id}', [PesananController::class, 'getPekerjaanDetail']);
});
@ -69,3 +74,10 @@ Route::get('/success-page', [CustomerController::class, 'success']);
Route::get('/check-order', [CustomerController::class, 'checkOrder']);
Route::get('/check-order/search', [CustomerController::class, 'searchOrder']);
// Route::get('/send-mail', function(){
// Mail::to('skyjok14@gmail.com')->queue(new NotifikasiCustomer('Test'));
// });
Route::get('/dumy', function(){
return view('guest.layout_mail');
});