Files
wticreatorstudio/Modules/StaffPayroll/Http/Controllers/API/InvoiceController.php
T

410 lines
16 KiB
PHP

<?php
namespace Modules\StaffPayroll\Http\Controllers\API;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Modules\StaffPayroll\Entities\Invoice;
use Illuminate\Contracts\Support\Renderable;
use Modules\StaffPayroll\Entities\InvoiceItem;
use Modules\StaffPayroll\Entities\InvoiceSetting;
use Modules\GeneralSetting\Entities\GeneralSetting;
use Modules\StaffPayroll\Http\Requests\InvoiceRequest;
use Modules\StaffPayroll\Services\InvoiceService;
use Modules\StaffPayroll\Transformers\InvoiceResource;
class InvoiceController extends Controller
{
public function index(Request $request)
{
$invoiceQuery = Invoice::query()->select('invoices.*', 'users.first_name', 'users.last_name')->leftJoin('users', 'invoices.user_id', '=', 'users.id')->with(['items',
'payout',
'user',
'items.incentive',
'items.video',
]);
if(!permissionCheck('invoices.view.all')){
$invoiceQuery = $invoiceQuery->where('user_id', auth()->user()->id);
}
if (permissionCheck('hide-pending-invoices') && !is_admin_user(auth()->id())) {
$invoiceQuery = $invoiceQuery->where('invoices.is_approved', true);
}
if ($request->has('filter')) {
$filter = json_decode($request->filter);
$invoiceQuery = $invoiceQuery->where(function($query) use($filter) {
if(isset($filter->invoice_no) && $filter->invoice_no->value != null){
$invoice_no = $filter->invoice_no->value;
$query->where('invoices.id', $invoice_no);
}
if(isset($filter->creator) && $filter->creator->value != null){
$creator = $filter->creator->value;
$query->where('invoices.user_id', $creator);
}
if(isset($filter->status) && $filter->status->value != null){
$status = $filter->status->value;
$query->where('invoices.status', $status);
}
if(isset($filter->issue_date) && $filter->issue_date->value != null && count($filter->issue_date->value) > 0){
if(count($filter->issue_date->value) == 2){
$startDate = Carbon::parse($filter->issue_date->value[0])->format('Y-m-d');
$endDate = Carbon::parse($filter->issue_date->value[1])->format('Y-m-d');
$query->whereBetween('issue_date', [$startDate, $endDate]);
} else {
$issue_date = Carbon::parse($filter->issue_date->value[0])->format('Y-m-d');
$query->whereDate('issue_date', $issue_date);
}
}
if(isset($filter->is_approved) && is_numeric($filter->is_approved->value)){
$is_approved = $filter->is_approved->value;
$query->where('invoices.is_approved', $is_approved);
}
});
}
$statistics['total_paid_sum'] = (float)$invoiceQuery->clone()->where('invoices.status','PAID')->sum('total_amount');
$statistics['total_paid_count'] = $invoiceQuery->clone()->where('invoices.status','PAID')->count();
$statistics['total_unpaid_sum'] = 0;
$statistics['total_unpaid_count'] = 0;
foreach ($invoiceQuery->clone()->where('invoices.status','UNPAID')->get() as $statistic) {
if($statistic->status == 'UNPAID'){
$invoice_sum = 0;
foreach ($statistic->items as $item) {
$invoice_sum += $item->quantity * $item->amount;
}
$statistics['total_unpaid_sum'] += $invoice_sum;
$statistics['total_unpaid_count']++;
}
}
$statistics['total_amount'] = $statistics['total_paid_sum'] + $statistics['total_unpaid_sum'];
$invoices = $invoiceQuery->clone()->orderBy('users.first_name')
->orderBy('users.last_name')
->orderBy('invoices.id', 'desc')
->paginate($request->rows);
return response()->json([
'invoices' => InvoiceResource::collection($invoices)->response()->getData(),
'statistics' => $statistics
]);
// $page = 0;
// $rows = 10;
// if ($request->has('paging')) {
// $paging = json_decode($request->paging);
// $page = $paging->page;
// $rows = $paging->rows;
// }
// $invoices = Invoice::query()
// ->select('invoices.*', 'users.first_name', 'users.last_name')
// ->leftJoin('users', 'invoices.user_id', '=', 'users.id')
// ->with(['payout', 'user', 'items.incentive', 'items.video'])
// ->when(!permissionCheck('invoices.view.all'), fn ($query) => $query->where('user_id', auth()->id()))
// ->when($request->filled('search'), function ($query) use ($request) {
// $search = $request->search;
// $query->whereHas('user', function( $query ) use ( $search ){
// $query->where('first_name', 'LIKE', "%{$search}%");
// $query->orWhere('last_name', 'LIKE', "%{$search}%");
// })->orWhere('id', 'LIKE', "%{$search}%");
// })
// ->when($request->filled('created_at'), function ($query) use ($request) {
// $createdAt = explode(',', $request->created_at);
// $query->whereBetween(DB::raw('DATE(invoices.created_at)'), $createdAt);
// })
// ->when($request->filled('due_date'), function ($query) use ($request) {
// $dueDate = explode(',', $request->due_date);
// $query->whereBetween(DB::raw('DATE(due_date)'), $dueDate);
// })
// ->when($request->filled('statuses'), fn ($query) => $query->whereIn('status', explode(',', $request->statuses)))
// ->when($request->filled('user'), fn ($query) => $query->where('user_id', $request->user))
// ->when($request->filled('paid_range'), function ($query) use ($request) {
// $paidRange = explode(',', $request->paid_range);
// $query->whereHas('items', function ($query) use ($paidRange) {
// $query->whereBetween(DB::raw('amount * quantity'), $paidRange);
// });
// })
// ->when($request->filled('invoice_no'), function($query) use($request) {
// $query->where('invoices.id', $request->invoice_no);
// })
// ->when($request->filled('creators'), function($query) use($request) {
// $query->whereIn('user_id', $request->creators);
// })
// ->when($request->filled('start_date') && $request->filled('end_date'), fn ($query) => $query->whereBetween(DB::raw('DATE(invoices.created_at)'), [$request->start_date, $request->end_date]))
// ->when($request->filled('status') && $request->status != 'ALL', function($query) use($request) {
// $query->where('invoices.status', $request->status);
// })
// ->when($request->filled('approval') && $request->approval != 'ALL', function($query) use($request) {
// $approval = $request->approval;
// if ($approval == 'APPROVED') {
// $query->where('is_approved', true);
// }
// else {
// $query->where('is_approved', false);
// }
// })
// //->latest('invoices.created_at')
// ->orderBy('users.first_name')
// ->orderBy('users.last_name')
// ->orderBy('invoices.id', 'desc')
// //->orderBy('user.last_name')
// //->getOrPaginate($request->per_page);
// ->skip($page * $rows)
// ->take($rows)
// ->get();
// return InvoiceResource::collection($invoices);
}
public function store(InvoiceRequest $request)
{
$validated = $request->validated();
try {
DB::beginTransaction();
$latestInvoice = Invoice::query()
->latest()
->first();
$validated['invoice_number'] = $latestInvoice ? $latestInvoice->id + 1 : 1;
$validated['created_by'] = auth()->id();
foreach ($validated['items'] as $key => $item) {
if ($item['label'] == 'item') {
$validated['items'][$key]['name'] = 'Item';
}
}
$invoice = Invoice::create($validated);
$invoice->items()->createMany($validated['items']);
DB::commit();
return response()->noContent();
} catch (\Exception $ex) {
DB::rollBack();
throw new \Exception($ex->getMessage());
}
}
public function details(Invoice $invoice)
{
$invoice->load(['user.staff', 'items']);
return response()->json([
'invoice' => $invoice
]);
}
public function update(InvoiceRequest $request, Invoice $invoice)
{
try {
DB::beginTransaction();
$validated = $request->validated();
$invoice->update($validated);
$validated['items'] = collect($validated['items'])->map(function ($item) {
$item['issue_date'] = Carbon::parse($item['issue_date'])->toDateString();
return $item;
})
->toArray();
foreach ($validated['items'] as $key => $item) {
if ($item['label'] == 'item') {
$item['name'] = 'Item';
}
$invoice->items()->updateOrCreate(
[
'id' => $item['id'] ?? null,
],
$item
);
}
$itemsId = collect($validated['items'])->pluck('id')->toArray();
$invoice->items()
->whereNotIn('id', $itemsId)
->delete();
DB::commit();
return response()->noContent();
} catch (\Exception $ex) {
DB::rollBack();
throw new \Exception($ex->getMessage());
}
}
public function latestInvoiceNo()
{
$latestInvoiceNumber = 1;
$invoice = Invoice::query()
->select('id')
->latest()
->first();
if (!$invoice) {
$invoiceSetting = InvoiceSetting::query()
->select('value')
->where('name', 'start_invoice_number')
->first();
return [
'invoice_number' => $invoiceSetting ? $invoiceSetting->value : $latestInvoiceNumber
];
}
return [
'invoice_number' => $invoice->id + 1
];
}
public function statistics(Request $request)
{
return Invoice::query()
->select(DB::raw('status, count(*) as invoices'))
->groupBy('status')
->when(!permissionCheck('invoices.view.all') && permissionCheck('invoices.index'), function($query) {
$query->where('user_id', auth()->id());
})
->when($request->filled('invoice_no'), function($query) use($request) {
$query->where('id', $request->invoice_no);
})
->when($request->filled('creators'), function($query) use($request) {
$creators = $request->creators;
$query->whereIn('user_id', $creators);
})
->when($request->filled('start_date') && $request->filled('end_date'), fn ($query) => $query->whereBetween(DB::raw('DATE(invoices.created_at)'), [$request->start_date, $request->end_date]))
->when($request->filled('status') && $request->status != 'ALL', function($query) use($request) {
$query->where('status', $request->status);
})
->when($request->filled('approval') && $request->approval != 'ALL', function($query) use($request) {
$approval = $request->approval;
if ($approval == 'APPROVED') {
$query->where('is_approved', true);
}
else {
$query->where('is_approved', false);
}
})
->get();
}
public function changeStatus(Invoice $invoice)
{
if($invoice->status == Invoice::STATUS_UNPAID){
$invoice->status = Invoice::STATUS_PAID;
$invoice->total_amount = (new InvoiceService)->getInvoiceAmount($invoice);
} else {
$invoice->status = Invoice::STATUS_UNPAID;
$invoice->total_amount = 0;
}
$invoice->update();
return response()->json([
'message' => 'Status has been successfully updated.',
'invoice' => InvoiceResource::make($invoice->load(['payout', 'user', 'items']))
]);
}
public function changeApproval(Invoice $invoice)
{
$invoice->is_approved = $invoice->is_approved ? false : true;
$invoice->update();
return response()->json([
'message' => 'Approval status has been successfully updated.',
'invoice' => InvoiceResource::make($invoice->load(['payout', 'user', 'items']))
]);
}
public function destroy(Invoice $invoice)
{
$invoice->items()->delete();
$invoice->delete();
return response()->noContent();
}
public function getInvoiceCount(Request $request)
{
return Invoice
::when($request->filled('invoice_no'), function($query) use($request) {
$query->where('id', $request->invoice_no);
})
->when($request->filled('start_date') && $request->filled('end_date'), fn ($query) => $query->whereBetween(DB::raw('DATE(created_at)'), [$request->start_date, $request->end_date]))
->when($request->filled('creators'), function($query) use($request) {
$query->whereIn('user_id', $request->creators);
})
->when($request->filled('status') && $request->status != 'ALL', function($query) use($request) {
$query->where('status', $request->status);
})
->when($request->filled('approval') && $request->approval != 'ALL', function($query) use($request) {
$approval = $request->approval;
if ($approval == 'APPROVED') {
$query->where('is_approved', true);
}
else {
$query->where('is_approved', false);
}
})
->when(!permissionCheck('invoices.view.all') && permissionCheck('invoices.index'), function($query) {
$query->where('user_id', auth()->id());
})
->get()->count();
}
public function reprocess(Invoice $invoice)
{
$service = new InvoiceService();
return $service->reprocess($invoice);
}
public function applyReprocessedItems(Invoice $invoice)
{
$invoice->applyReprocessedItems();
return response()->json([
'invoice' => InvoiceResource::make($invoice->load(['payout', 'user', 'items'])->unsetRelation('reprocessedItems'))
]);
}
public function reprocessAllPending()
{
$service = new InvoiceService();
$service->reprocessAllPending();
return response()->json([
'message' => 'All pending invoices have been reprocessed.',
]);
}
}