diff --git a/app/Exports/ExpensesExport.php b/app/Exports/ExpensesExport.php index 59d126a..a842ea6 100644 --- a/app/Exports/ExpensesExport.php +++ b/app/Exports/ExpensesExport.php @@ -11,11 +11,11 @@ use Maatwebsite\Excel\Concerns\WithHeadings; class ExpensesExport implements WithHeadings, FromView { + public $begining_balance = 0; + public function view(): View { - $this->begining_balance = 0; - $expenses = Expense::all(); - $today = \Carbon\Carbon::now(); + $today = now(); $query = Expense::query()->orderBy('date_expense', 'ASC'); diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php index 5ac320c..024e3b4 100644 --- a/app/Http/Controllers/ExpenseController.php +++ b/app/Http/Controllers/ExpenseController.php @@ -2,11 +2,14 @@ namespace App\Http\Controllers; +use App\Exports\ExpensesExport; use App\Models\Expense; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; +use Maatwebsite\Excel\Facades\Excel; class ExpenseController extends Controller { @@ -24,11 +27,10 @@ class ExpenseController extends Controller $query->where('isIncome', 0)->orderBy('created_at', 'DESC'); } - if ($request->q) { + if ($request->q != null) { $query->where('name', 'like', '%'.$request->q.'%') ->orWhere('description', 'like', '%'.$request->q.'%') - ->orWhere('job_number', 'like', '%'.$request->q.'%') - ->orWhere('amount', 'like', '%'.$request->q.'%'); + ->orWhere('job_number', 'like', '%'.$request->q.'%'); } $endDate = Carbon::now()->toDateString(); @@ -43,17 +45,89 @@ class ExpenseController extends Controller ->whereDate('date_expense', '>=', $startDate); $limit = $request->limit ? $request->limit : 10; - + return inertia('Expense/Index', [ 'expenses' => $query->paginate($limit), '_startDate' => $startDate, '_endDate' => $endDate, - '_limit' => $limit + '_limit' => $limit, + '_q' => $request->q + ]); + } + + public function store(Request $request) + { + $request->validate([ + 'description' => ['required'], + 'date_expense' => ['required', 'date'], + 'amount' => ['required', 'numeric'], + 'is_paid' => ['required', 'in:0,1,2,3'], + 'isIncome' => ['required', 'in:0,1'], + ]); + + if ($request->isIncome === 0) { + $request->validate([ + 'name' => ['required'], + 'job_number' => ['required'], + ]); + } + + Expense::create([ + 'name' => $request->name, + 'description' => $request->description, + 'job_number' => $request->job_number, + 'date_expense' => Carbon::parse($request->date_expense)->toDateString(), + 'amount' => $request->amount, + 'is_paid' => $request->is_paid, + 'isIncome' => $request->isIncome, + ]); + + return redirect()->route('expenses.index'); + } + + public function update(Request $request, Expense $expense) + { + $request->validate([ + 'description' => ['required'], + 'date_expense' => ['required', 'date'], + 'amount' => ['required', 'numeric'], + 'is_paid' => ['required', 'in:0,1,2,3'], + 'isIncome' => ['required', 'in:0,1'], ]); + + if ($request->isIncome === 0) { + $request->validate([ + 'name' => ['required'], + 'job_number' => ['required'], + ]); + } + + $expense->update([ + 'name' => $request->name, + 'description' => $request->description, + 'job_number' => $request->job_number, + 'date_expense' => Carbon::parse($request->date_expense)->toDateString(), + 'amount' => $request->amount, + 'is_paid' => $request->is_paid, + 'isIncome' => $request->isIncome, + ]); + + return redirect()->route('expenses.index'); + } + + public function decision(Expense $expense, $status) + { + $expense->update(['is_paid' => $status]); + return redirect()->route('expenses.index'); } public function destroy(Expense $expense) { $expense->delete(); } + + public function export() + { + return Excel::download(new ExpensesExport, 'expenses.xlsx'); + } } diff --git a/app/Models/Expense.php b/app/Models/Expense.php index e0c4dc9..c65faf9 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -9,11 +9,11 @@ class Expense extends Model { use HasFactory; - const IS_PAID_DRAFT = 1; - const IS_PAID_UNPAID = 1; - const IS_PAID_PAID = 2; - const IS_PAID_APPROVE = 3; - const IS_PAID_REJECT = 4; + const IS_PAID_DRAFT = 0; + const IS_PAID_UNPAID = 0; + const IS_PAID_PAID = 1; + const IS_PAID_APPROVE = 2; + const IS_PAID_REJECT = 3; /** * The attributes that are mass assignable. @@ -30,4 +30,16 @@ class Expense extends Model 'isIncome', 'is_paid', ]; + + protected $appends = ['status']; + + public function getStatusAttribute() + { + return [ + self::IS_PAID_DRAFT => 'Draft', + self::IS_PAID_PAID => 'Paid', + self::IS_PAID_APPROVE => 'Approve', + self::IS_PAID_REJECT => 'Reject', + ][$this->is_paid]; + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ee8ca5b..40c4154 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -23,6 +25,17 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - // + if (app()->isProduction() == false) { + DB::listen(function ($query) { + Log::info( + $query->sql, + [ + 'bindings' => $query->bindings, + 'time' => $query->time, + 'connectionName' => $query->connectionName + ] + ); + }); + } } } diff --git a/resources/css/app.css b/resources/css/app.css index c903134..7c1d6b5 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -8,7 +8,7 @@ } .react-datepicker-popper { - @apply z-40 w-72 text-sm bg-white shadow px-3 py-2 border-2 border-gray-200 rounded; + @apply z-10 w-72 text-sm bg-white shadow px-3 py-2 border-2 border-gray-200 rounded; } .react-datepicker-left { diff --git a/resources/js/Components/DatePickerInput.jsx b/resources/js/Components/DatePickerInput.jsx index eab2a28..bdfdf8c 100644 --- a/resources/js/Components/DatePickerInput.jsx +++ b/resources/js/Components/DatePickerInput.jsx @@ -35,3 +35,21 @@ export const DatePickerRangeInput = ({ ); }; + +export const DatePickerInput = ({ + value, + onChange, +}) => { + return ( +