diff --git a/app/Http/Controllers/SaleController.php b/app/Http/Controllers/SaleController.php
index 37cb73b..dd0d667 100644
--- a/app/Http/Controllers/SaleController.php
+++ b/app/Http/Controllers/SaleController.php
@@ -124,4 +124,11 @@ class SaleController extends Controller
return redirect()->route('sale.index')
->with('message', ['type' => 'success', 'message' => 'Item has beed deleted']);
}
+
+ public function invoice(Sale $sale)
+ {
+ return view('invoice', [
+ 'sale' => $sale->load(['customer', 'items.product'])
+ ]);
+ }
}
diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php
new file mode 100644
index 0000000..8d9b22b
--- /dev/null
+++ b/app/Http/Controllers/SettingController.php
@@ -0,0 +1,42 @@
+ Setting::all(),
+ ]);
+ }
+
+ public function update(Request $request)
+ {
+ $request->validate([
+ 'name' => 'required|string',
+ 'detail' => 'required|string'
+ ]);
+
+ DB::beginTransaction();
+
+ foreach ($request->input() as $key => $value) {
+ Setting::updateOrCreate(
+ ['key' => $key],
+ [
+ 'value' => $value,
+ 'type' => 'text'
+ ]
+ );
+ }
+
+ DB::commit();
+
+ return redirect()->route('setting.index')
+ ->with('message', ['type' => 'success', 'message' => 'Setting saved']);
+ }
+}
diff --git a/app/Models/Sale.php b/app/Models/Sale.php
index b707b70..17e7fd6 100644
--- a/app/Models/Sale.php
+++ b/app/Models/Sale.php
@@ -2,6 +2,9 @@
namespace App\Models;
+use Illuminate\Database\Eloquent\Casts\Attribute;
+use Illuminate\Support\Carbon;
+
class Sale extends Model
{
protected $fillable = [
@@ -20,4 +23,13 @@ class Sale extends Model
{
return $this->hasMany(SaleItem::class);
}
+
+ public function formatedDate(): Attribute
+ {
+ return Attribute::make(
+ get: function () {
+ return Carbon::parse($this->date)->format('d/m/Y');
+ }
+ );
+ }
}
diff --git a/app/Models/Setting.php b/app/Models/Setting.php
index b47083c..d82cb33 100644
--- a/app/Models/Setting.php
+++ b/app/Models/Setting.php
@@ -11,9 +11,14 @@ class Setting extends Model
{
use HasFactory, SoftDeletes, HasUuids;
- protected $fillalble = [
+ protected $fillable = [
'key',
'value',
'type',
];
+
+ public static function getValue($key)
+ {
+ return Setting::where('key', $key)->value('value');
+ }
}
diff --git a/database/seeders/PermissionSeeder.php b/database/seeders/PermissionSeeder.php
index 82dcaff..30c0ab5 100644
--- a/database/seeders/PermissionSeeder.php
+++ b/database/seeders/PermissionSeeder.php
@@ -50,17 +50,18 @@ class PermissionSeeder extends Seeder
['id' => Str::uuid(), 'label' => 'Update Sale', 'name' => 'update-sale'],
['id' => Str::uuid(), 'label' => 'View Sale', 'name' => 'view-sale'],
['id' => Str::uuid(), 'label' => 'Delete Sale', 'name' => 'delete-sale'],
-
+
+ ['id' => Str::uuid(), 'label' => 'View Setting', 'name' => 'view-setting'],
];
- foreach($permissions as $permission) {
+ foreach ($permissions as $permission) {
Permission::insert($permission);
}
$role = Role::create(['name' => 'admin']);
$permissions = Permission::all();
- foreach($permissions as $permission) {
+ foreach ($permissions as $permission) {
$role->rolePermissions()->create(['permission_id' => $permission->id]);
}
@@ -77,8 +78,7 @@ class PermissionSeeder extends Seeder
'role_id' => $role->id,
]);
- $setting = [
- ];
+ $setting = [];
Setting::insert($setting);
}
diff --git a/resources/js/Layouts/Partials/routes.js b/resources/js/Layouts/Partials/routes.js
index 8e07633..5f400e9 100644
--- a/resources/js/Layouts/Partials/routes.js
+++ b/resources/js/Layouts/Partials/routes.js
@@ -5,70 +5,80 @@ import {
HiUserGroup,
HiViewList,
HiOutlineCash,
-} from "react-icons/hi";
+ HiCode,
+ HiOutlineCog,
+} from 'react-icons/hi'
export default [
{
- name: "Dashboard",
+ name: 'Dashboard',
show: true,
icon: HiChartPie,
- route: route("dashboard"),
- active: "dashboard",
- permission: "view-dashboard",
+ route: route('dashboard'),
+ active: 'dashboard',
+ permission: 'view-dashboard',
},
{
- name: "Transaksi Penjualan",
+ name: 'Transaksi Penjualan',
show: true,
icon: HiOutlineCash,
- route: route("sale.index"),
- active: "sale.*",
- permission: "view-sale",
+ route: route('sale.index'),
+ active: 'sale.*',
+ permission: 'view-sale',
},
{
- name: "Kategori",
+ name: 'Kategori',
show: true,
icon: HiViewList,
- route: route("category.index"),
- active: "category.*",
- permission: "view-category",
+ route: route('category.index'),
+ active: 'category.*',
+ permission: 'view-category',
},
{
- name: "Barang",
+ name: 'Barang',
show: true,
icon: HiViewList,
- route: route("product.index"),
- active: "product.*",
- permission: "view-product",
+ route: route('product.index'),
+ active: 'product.*',
+ permission: 'view-product',
},
{
- name: "Pelangan",
+ name: 'Pelangan',
show: true,
icon: HiViewList,
- route: route("customer.index"),
- active: "customer.*",
- permission: "view-customer",
+ route: route('customer.index'),
+ active: 'customer.*',
+ permission: 'view-customer',
},
{
- name: "User",
+ name: 'User',
show: true,
icon: HiUser,
items: [
{
- name: "Roles",
+ name: 'Roles',
show: true,
icon: HiUserGroup,
- route: route("roles.index"),
- active: "roles.*",
- permission: "view-role",
+ route: route('roles.index'),
+ active: 'roles.*',
+ permission: 'view-role',
},
{
- name: "Users",
+ name: 'Users',
show: true,
icon: HiUsers,
- route: route("user.index"),
- active: "user.index",
- permission: "view-user",
+ route: route('user.index'),
+ active: 'user.index',
+ permission: 'view-user',
},
],
},
-];
+ {
+ name: 'Setting',
+ show: true,
+ icon: HiOutlineCog,
+ route: route('setting.index'),
+ active: 'setting.*',
+ permission: 'view-setting',
+ },
+]
diff --git a/resources/js/Pages/Sale/Index.jsx b/resources/js/Pages/Sale/Index.jsx
index b7046c8..5f0b54f 100644
--- a/resources/js/Pages/Sale/Index.jsx
+++ b/resources/js/Pages/Sale/Index.jsx
@@ -149,6 +149,10 @@ export default function Sale(props) {
scope="col"
className="py-3 px-6"
/>
+
|
@@ -172,6 +176,18 @@ export default function Sale(props) {
{formatIDR(sale.total)}
|
+
+
+ Invoice
+
+ |
{
+ const find = set.find((s) => s.key === key)
+ if (find !== null) {
+ if (find.type === 'image') {
+ return find?.url
+ }
+ return find?.value
+ }
+ return ''
+}
+
+export default function Setting(props) {
+ const { setting } = props
+
+ const { data, setData, post, processing, errors } = useForm({
+ name: extractValue(setting, 'name'),
+ detail: extractValue(setting, 'detail'),
+ })
+
+ const handleOnChange = (event) => {
+ setData(
+ event.target.name,
+ event.target.type === 'checkbox'
+ ? event.target.checked
+ ? 1
+ : 0
+ : event.target.value
+ )
+ }
+
+ const handleSubmit = () => {
+ post(route('setting.update'))
+ }
+
+ return (
+
+
+
+
+
+
+ Setting
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/resources/views/invoice.blade.php b/resources/views/invoice.blade.php
new file mode 100644
index 0000000..2d3a519
--- /dev/null
+++ b/resources/views/invoice.blade.php
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+ Invoice
+
+
+
+
+
+ @vite(['resources/css/app.css'])
+
+
+
+
+
+ {{ \App\Models\Setting::getValue('name') }}
+
+
+ {!! \App\Models\Setting::getValue('detail') !!}
+
+
+
+
+
+ FAKTUR # |
+ : |
+ {{ $sale->code }} |
+
+
+ TANGGAL |
+ : |
+ {{ $sale->formated_date }} |
+
+
+
+
+
+
+
+
+ PELANGGAN
+
+
+
+ NAMA |
+ {{ $sale->customer?->name }} |
+
+
+ ALAMAT |
+ {{ $sale->customer?->address }} |
+
+
+ TELP |
+ {{ $sale->customer?->phone }} |
+
+
+ FAX |
+ |
+
+
+
+
+
+ KETERANGAN
+
+
+
+ |
+ |
+
+
+ JATUH TEMPO |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+
+
+
+
+
+
+
+ NO. |
+ KETERANGAN |
+ QTY |
+ HARGA SATUAN (Rp.) |
+ JUMLAH (Rp.) |
+
+ @foreach($sale->items as $index => $item)
+
+ {{ $index + 1 }} |
+ {{ $item->product->name }} |
+ {{ number_format($item->quantity, 0, ',', '.') }} |
+ {{ number_format($item->price, 0, ',', '.') }} |
+ {{ number_format($item->quantity * $item->price, 0, ',', '.') }} |
+
+ @endforeach
+
+ |
+ |
+ |
+ Subtotal |
+ {{ number_format($sale->total, 0, ',', '.') }} |
+
+
+ |
+ |
+ |
+ TOTAL |
+ {{ number_format($sale->total, 0, ',', '.') }} |
+
+
+ |
+ |
+ |
+ Bayaran Diterima |
+ {{ number_format($sale->total, 0, ',', '.') }} |
+
+
+ |
+ |
+ |
+ Sisa Tagihan |
+ 0 |
+
+
+
+
+
+
+
+
+ PESAN |
+
+
+ |
+
+
+ TERBILANG |
+
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/routes/web.php b/routes/web.php
index 58af926..0a20e75 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -8,6 +8,7 @@ use App\Http\Controllers\CategoryController;
use App\Http\Controllers\CustomerController;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\SaleController;
+use App\Http\Controllers\SettingController;
use Illuminate\Support\Facades\Route;
/*
@@ -62,6 +63,11 @@ Route::middleware(['auth'])->group(function () {
Route::post('/sales', [SaleController::class, 'store'])->name('sale.store');
Route::get('/sales/{sale}', [SaleController::class, 'show'])->name('sale.show');
Route::delete('/sales/{sale}', [SaleController::class, 'destroy'])->name('sale.destroy');
+ Route::get('/sales/{sale}/invoice', [SaleController::class, 'invoice'])->name('sale.invoice');
+
+ // Setting
+ Route::get('/setting', [SettingController::class, 'index'])->name('setting.index');
+ Route::post('/setting', [SettingController::class, 'update'])->name('setting.update');
});
Route::middleware('auth')->group(function () {
@@ -70,4 +76,4 @@ Route::middleware('auth')->group(function () {
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
-require __DIR__.'/auth.php';
+require __DIR__ . '/auth.php';
|