diff --git a/TODO.md b/TODO.md index 5ac1453..2a396ba 100644 --- a/TODO.md +++ b/TODO.md @@ -19,9 +19,9 @@ - [x] Voucher Sales (index: customer, total, jumlah voucher, detail: customer, list voucher, payment) - [x] Dashboard (gafik hasil penjualan : disorting tanggal, lokasi dan customer) - [x] Notification ([x]manual deposit, [x]deposit success, [x]stock voucher, [x]sale) -- [ ] View Customer Coin History -- [ ] Voucher - harga per level +- [x] Voucher - harga per level , fixing detail transaksi - [ ] Voucher - harga coin +- [ ] View Customer Coin History ### Adds diff --git a/app/Http/Controllers/Customer/CartController.php b/app/Http/Controllers/Customer/CartController.php index 08cdd56..cb0bc1f 100644 --- a/app/Http/Controllers/Customer/CartController.php +++ b/app/Http/Controllers/Customer/CartController.php @@ -25,7 +25,7 @@ class CartController extends Controller { $carts = collect(session('carts') ?? []); $total = $carts->sum(function ($item) { - return $item['quantity'] * $item['voucher']->price; + return $item['quantity'] * $item['voucher']->validate_price; }); $customer = Customer::find(auth()->id()); @@ -119,7 +119,7 @@ class CartController extends Controller }; $total = $carts->sum(function ($item) { - return $item['quantity'] * $item['voucher']->price; + return $item['quantity'] * $item['voucher']->validate_price; }); $customer = Customer::find(auth()->id()); @@ -149,7 +149,7 @@ class CartController extends Controller $sale->items()->create([ 'entity_type' => $voucher::class, 'entity_id' => $voucher->id, - 'price' => $voucher->price, + 'price' => $voucher->validate_price, 'quantity' => 1, 'additional_info_json' => json_encode($item), ]); diff --git a/app/Http/Controllers/GeneralController.php b/app/Http/Controllers/GeneralController.php index 14f747b..d0aafcb 100644 --- a/app/Http/Controllers/GeneralController.php +++ b/app/Http/Controllers/GeneralController.php @@ -79,6 +79,16 @@ class GeneralController extends Controller $charts->where('customer_id', $request->customer_id); } + $ca = []; + $date = Carbon::parse($startDate); + $end = Carbon::parse($endDate); + $data = $charts->get(); + while ($date <= $end) { + $da = $data->where('date', $date->format('d/m/Y'))?->value('sale_total') ?? 0; + $ca[] = ['sale_total' => $da, 'date' => $date->format('d/m/Y')]; + $date = $date->addDay(); + } + return inertia('Dashboard', [ 'total_voucher' => $total_voucher, 'total_customer' => $total_customer, @@ -91,9 +101,11 @@ class GeneralController extends Controller 'month' => $month, 'deposites' => $deposites, 'sales' => $sales, - 'charts' => $charts->get(), + 'charts' => $ca, '_startDate' => $startDate, '_endDate' => $endDate, + 'c' => $charts, + 'd' => $data, ]); } diff --git a/app/Http/Controllers/VoucherController.php b/app/Http/Controllers/VoucherController.php index 51b2277..f116889 100644 --- a/app/Http/Controllers/VoucherController.php +++ b/app/Http/Controllers/VoucherController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Models\CustomerLevel; use App\Models\Voucher; use App\Services\GeneralService; use Illuminate\Http\Request; @@ -31,7 +32,9 @@ class VoucherController extends Controller public function create() { - return inertia('Voucher/Form'); + return inertia('Voucher/Form', [ + 'levels' => CustomerLevel::all() + ]); } public function store(Request $request) @@ -49,9 +52,13 @@ class VoucherController extends Controller 'comment' => 'required|string', 'expired' => 'required|numeric', 'expired_unit' => 'required|string', + 'prices' => 'nullable|array', + 'prices.*.customer_level_id' => 'required|exists:customer_levels,id', + 'prices.*.display_price' => 'required|numeric' ]); - Voucher::create([ + DB::beginTransaction(); + $voucher = Voucher::create([ 'name' => $request->name, 'description' => $request->description, 'location_id' => $request->location_id, @@ -66,6 +73,19 @@ class VoucherController extends Controller 'expired_unit' => $request->expired_unit, ]); + foreach (collect($request->prices) as $price) { + $finalPrice = $price['display_price']; + if ($voucher->discount > 0) { + $finalPrice = $finalPrice - round($finalPrice * ($voucher->discount / 100), 2); + } + $voucher->prices()->create([ + 'customer_level_id' => $price['customer_level_id'], + 'price' => $finalPrice, + 'display_price' => $price['display_price'], + ]); + } + DB::commit(); + return redirect()->route('voucher.index') ->with('message', ['type' => 'success', 'message' => 'Item has beed saved']); } @@ -73,7 +93,8 @@ class VoucherController extends Controller public function edit(Voucher $voucher) { return inertia('Voucher/Form', [ - 'voucher' => $voucher, + 'voucher' => $voucher->load(['prices.level']), + 'levels' => CustomerLevel::all() ]); } @@ -92,8 +113,12 @@ class VoucherController extends Controller 'comment' => 'required|string', 'expired' => 'required|numeric', 'expired_unit' => 'required|string', + 'prices' => 'nullable|array', + 'prices.*.customer_level_id' => 'required|exists:customer_levels,id', + 'prices.*.display_price' => 'required|numeric' ]); + DB::beginTransaction(); $voucher->update([ 'name' => $request->name, 'description' => $request->description, @@ -108,6 +133,20 @@ class VoucherController extends Controller 'expired' => $request->expired, ]); + $voucher->prices()->delete(); + foreach (collect($request->prices) as $price) { + $finalPrice = $price['display_price']; + if ($voucher->discount > 0) { + $finalPrice = $finalPrice - round($finalPrice * ($voucher->discount / 100), 2); + } + $voucher->prices()->create([ + 'customer_level_id' => $price['customer_level_id'], + 'price' => $finalPrice, + 'display_price' => $price['display_price'], + ]); + } + DB::commit(); + return redirect()->route('voucher.index') ->with('message', ['type' => 'success', 'message' => 'Item has beed updated']); } @@ -122,7 +161,9 @@ class VoucherController extends Controller public function form_import() { - return inertia('Voucher/Import'); + return inertia('Voucher/Import', [ + 'levels' => CustomerLevel::all() + ]); } public function import(Request $request) @@ -134,6 +175,9 @@ class VoucherController extends Controller 'display_price' => 'required|numeric', 'expired' => 'required|numeric', 'expired_unit' => 'required|string', + 'prices' => 'nullable|array', + 'prices.*.customer_level_id' => 'required|exists:customer_levels,id', + 'prices.*.display_price' => 'required|numeric' ]); $batchId = Str::ulid(); @@ -141,7 +185,7 @@ class VoucherController extends Controller DB::beginTransaction(); foreach ($vouchers as $voucher) { - Voucher::create([ + $voucher = Voucher::create([ 'location_id' => $request->location_id, 'username' => $voucher['username'], 'password' => $voucher['password'], @@ -154,6 +198,18 @@ class VoucherController extends Controller 'expired_unit' => $request->expired_unit, 'batch_id' => $batchId, ]); + + foreach (collect($request->prices) as $price) { + $finalPrice = $price['display_price']; + if ($voucher->discount > 0) { + $finalPrice = $finalPrice - round($finalPrice * ($voucher->discount / 100), 2); + } + $voucher->prices()->create([ + 'customer_level_id' => $price['customer_level_id'], + 'price' => $finalPrice, + 'display_price' => $price['display_price'], + ]); + } } DB::commit(); diff --git a/app/Models/SaleItem.php b/app/Models/SaleItem.php index c0aa2d0..2234a63 100644 --- a/app/Models/SaleItem.php +++ b/app/Models/SaleItem.php @@ -37,17 +37,19 @@ class SaleItem extends Model public function shareWord(): Attribute { return Attribute::make(get: function () { - $string = "Hai, aku baru beli voucher {$this->voucher->location->name} di " . route('home.index'); - $string .= " voucher {$this->voucher->display_quota} buat {$this->voucher->display_expired} + $item = json_decode($this->additional_info_json); + ds($item); + $string = "Hai, aku baru beli voucher {$item->voucher->location->name} di " . route('home.index'); + $string .= " voucher {$item->voucher->display_quota} buat {$item->voucher->display_expired} -Username : {$this->voucher->username} -Password : {$this->voucher->password} +Username : {$item->voucher->username} +Password : {$item->voucher->password} "; $string .= "Cuman Rp" . number_format($this->price, '0', ',', '.') . " aja, "; - if ($this->voucher->discount > 0) { - $string .= "lagi ada discount {$this->voucher->discount}% loh. + if ($item->voucher->discount > 0) { + $string .= "lagi ada discount {$item->voucher->discount}% loh. "; } diff --git a/app/Models/Voucher.php b/app/Models/Voucher.php index aa39cff..053f1e7 100644 --- a/app/Models/Voucher.php +++ b/app/Models/Voucher.php @@ -32,7 +32,7 @@ class Voucher extends Model 'batch_id', ]; - protected $appends = ['display_quota', 'display_expired']; + protected $appends = ['display_quota', 'display_expired', 'validate_price', 'validate_display_price']; protected static function booted(): void { @@ -74,11 +74,44 @@ class Voucher extends Model }); } + public function validatePrice(): Attribute + { + return Attribute::make(get: function () { + if (auth('customer')->check()) { + if ($this->prices()->count() > 0) { + $price = $this->prices()->where('customer_level_id', auth()->user()->customer_level_id)->value('price'); + return $price; + } + } + + return $this->price; + }); + } + + public function validateDisplayPrice(): Attribute + { + return Attribute::make(get: function () { + if (auth('customer')->check()) { + if ($this->prices()->count() > 0) { + $price = $this->prices()->where('customer_level_id', auth()->user()->customer_level_id)->value('display_price'); + return $price; + } + } + + return $this->display_price; + }); + } + public function location() { return $this->belongsTo(Location::class)->withTrashed(); } + public function prices() + { + return $this->hasMany(VoucherPrice::class); + } + public function shuffle_unsold() { $voucher = Voucher::where([ diff --git a/app/Models/VoucherPrice.php b/app/Models/VoucherPrice.php index e037b5c..bf00819 100644 --- a/app/Models/VoucherPrice.php +++ b/app/Models/VoucherPrice.php @@ -8,5 +8,11 @@ class VoucherPrice extends Model 'customer_level_id', 'voucher_id', 'price', + 'display_price', ]; + + public function level() + { + return $this->belongsTo(CustomerLevel::class, 'customer_level_id'); + } } diff --git a/database/migrations/2023_05_24_130523_create_voucher_prices_table.php b/database/migrations/2023_05_24_130523_create_voucher_prices_table.php index 2c048d9..2316553 100644 --- a/database/migrations/2023_05_24_130523_create_voucher_prices_table.php +++ b/database/migrations/2023_05_24_130523_create_voucher_prices_table.php @@ -16,7 +16,8 @@ return new class extends Migration $table->ulid('customer_level_id')->nullable(); $table->ulid('voucher_id')->nullable(); - $table->decimal('price', 20, 2)->nullable(); + $table->decimal('price', 20, 2)->default(0); + $table->decimal('display_price', 20, 2)->default(0); $table->timestamps(); $table->softDeletes(); diff --git a/resources/js/Customer/Cart/VoucherCard.jsx b/resources/js/Customer/Cart/VoucherCard.jsx index eafa2d5..a5894a7 100644 --- a/resources/js/Customer/Cart/VoucherCard.jsx +++ b/resources/js/Customer/Cart/VoucherCard.jsx @@ -25,7 +25,7 @@ export default function VoucherCard({ item: { voucher, quantity } }) { {voucher.profile}
- IDR {formatIDR(voucher.price)} + IDR {formatIDR(voucher.validate_price)}
{+voucher.discount !== 0 && (
@@ -33,7 +33,7 @@ export default function VoucherCard({ item: { voucher, quantity } }) { {voucher.discount}%
- {formatIDR(voucher.display_price)} + {formatIDR(voucher.validate_display_price)}
)} @@ -49,10 +49,10 @@ export default function VoucherCard({ item: { voucher, quantity } }) {
-
{formatIDR(voucher.price)}
+
{formatIDR(voucher.validate_price)}
x
{quantity}
-
{formatIDR(+voucher.price * +quantity)}
+
{formatIDR(+voucher.validate_price * +quantity)}
- IDR {formatIDR(voucher.price)} + IDR {formatIDR(voucher.validate_price)}
{+voucher.discount !== 0 && (
@@ -26,7 +26,7 @@ export default function VoucherCard({ voucher }) { {voucher.discount}%
- {formatIDR(voucher.display_price)} + {formatIDR(voucher.validate_display_price)}
)} diff --git a/resources/js/Customer/Trx/VoucherCard.jsx b/resources/js/Customer/Trx/VoucherCard.jsx index 335ae20..8e023e0 100644 --- a/resources/js/Customer/Trx/VoucherCard.jsx +++ b/resources/js/Customer/Trx/VoucherCard.jsx @@ -4,11 +4,13 @@ import { toast } from 'react-toastify' export default function VoucherCard(props) { const { - item: { voucher, quantity, share_word }, + item: { share_word, additional_info_json }, } = props + const sale_item = JSON.parse(additional_info_json) + const voucher = sale_item?.voucher + const handleShare = () => { - console.log(share_word) if (navigator.canShare) { navigator.share({ title: share_word, @@ -41,7 +43,7 @@ export default function VoucherCard(props) { {voucher.profile}
- IDR {formatIDR(voucher.price)} + IDR {formatIDR(voucher.validate_price)}
{+voucher.discount !== 0 && (
@@ -49,7 +51,7 @@ export default function VoucherCard(props) { {voucher.discount}%
- {formatIDR(voucher.display_price)} + {formatIDR(voucher.validate_display_price)}
)} diff --git a/resources/js/Pages/Dashboard.jsx b/resources/js/Pages/Dashboard.jsx index 7ad35b0..08c42bd 100644 --- a/resources/js/Pages/Dashboard.jsx +++ b/resources/js/Pages/Dashboard.jsx @@ -63,7 +63,9 @@ export default function Dashboard(props) { } const data = { - labels: charts.map((item) => moment(item.date).format('DD MMM YYYY')), + labels: charts.map((item) => + moment(item.date, 'DD/MM/YYYY').format('DD MMM YYYY') + ), datasets: [ { label: 'Penjualan', @@ -78,8 +80,8 @@ export default function Dashboard(props) { router.get( route(route().current()), { - startDate: dates.startDate, - endDate: dates.endDate, + start_date: dates.startDate, + end_date: dates.endDate, customer_id, location_id, }, diff --git a/resources/js/Pages/Voucher/Form.jsx b/resources/js/Pages/Voucher/Form.jsx index 974d1e0..56a320b 100644 --- a/resources/js/Pages/Voucher/Form.jsx +++ b/resources/js/Pages/Voucher/Form.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react' +import React, { useEffect, useState } from 'react' import { isEmpty } from 'lodash' import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout' @@ -7,10 +7,12 @@ import Button from '@/Components/Button' import { Head, useForm } from '@inertiajs/react' import FormInputWith from '@/Components/FormInputWith' import LocationSelectionInput from '../Location/SelectionInput' +import Checkbox from '@/Components/Checkbox' export default function Form(props) { - const { voucher } = props + const { voucher, levels } = props + const [use_level, setUseLevel] = useState(false) const { data, setData, post, processing, errors } = useForm({ username: '', password: '', @@ -22,6 +24,7 @@ export default function Form(props) { expired: '', expired_unit: 'Hari', location_id: null, + prices: null, }) const handleOnChange = (event) => { @@ -34,6 +37,38 @@ export default function Form(props) { : event.target.value ) } + + const handleUseLevel = () => { + setUseLevel(!use_level) + if (!use_level === true) { + const prices = levels.map((level) => { + return { + name: level.name, + customer_level_id: level.id, + display_price: '0', + } + }) + setData('prices', prices) + return + } + setData('prices', null) + } + + const handleSetLevelPrice = (id, value) => { + setData( + 'prices', + data.prices.map((price) => { + if (price.customer_level_id === id) { + return { + ...price, + display_price: value, + } + } + return price + }) + ) + } + const handleSubmit = () => { if (isEmpty(voucher) === false) { post(route('voucher.update', voucher)) @@ -44,6 +79,17 @@ export default function Form(props) { useEffect(() => { if (isEmpty(voucher) === false) { + let prices = null + if (voucher.prices.length > 0) { + setUseLevel(true) + prices = voucher.prices.map((price) => { + return { + ...price, + name: price.level.name, + } + }) + } + setData({ username: voucher.username, password: voucher.password, @@ -55,6 +101,7 @@ export default function Form(props) { expired: voucher.expired, expired_unit: voucher.expired_unit, location_id: voucher.location_id, + prices: prices, }) } }, [voucher]) @@ -136,7 +183,7 @@ export default function Form(props) { label="Comment" error={errors.comment} /> -
+
@@ -166,6 +213,36 @@ export default function Form(props) {
+ handleUseLevel(e.target.value)} + /> +
+ {data.prices?.map((price) => ( + + handleSetLevelPrice( + price.customer_level_id, + e.target.value + ) + } + label={price.name} + /> + ))} + {errors.prices && ( +

+ {errors.prices} +

+ )} +
+ handleUseLevel(e.target.value)} + /> +
+ {data.prices?.map((price) => ( + + handleSetLevelPrice( + price.customer_level_id, + e.target.value + ) + } + label={price.name} + /> + ))} + {errors.prices && ( +

+ {errors.prices} +

+ )} +