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

425 lines
17 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)
{
$invoices = Invoice::select('invoices.*', 'users.first_name', 'users.last_name')
->leftJoin('users', 'invoices.user_id', '=', 'users.id')
->with(['items' => function ($query) {
$query
->where(function ($query) {
$query->where(function($query) {
$query
->where(function($query) {
$query->where('name', 'Video upload payout')->where('description', 'REGEXP', 'ASIN\s+[A-Z0-9]{10}$');
})
->orWhere(function($query) {
$query->where('name', 'Item')->where('description', 'REGEXP', 'ASIN\s+[A-Z0-9]{10}$');
});
})
->where(function ($query) {
$query->whereHas('video', function($query) {
$query->where('is_short', false);
})
->orWhereNull('studio_plus_video_id');
});
})
->orWhere(function ($query) {
$query->where(function ($query) {
$query
->where(function($query) {
$query->where('name', 'Video upload payout')->where('description', 'REGEXP', 'ASIN\s*([A-Z0-9]{10},)+');
})
->orWhere(function($query) {
$query->where('name', 'Item')->where('description', 'REGEXP', 'ASIN\s*([A-Z0-9]{10},)+');
});
})
->where(function ($query) {
$query->whereHas('video', function($query) {
$query->where('is_short', true);
})
->orWhereNull('studio_plus_video_id');
});
})
->orWhere(function ($query) {
$query->where(fn ($query) => $query->where('name', '<>', 'Video upload payout')->where('description', 'NOT REGEXP', 'ASIN\s+[A-Z0-9]{10}')->where('description', 'NOT REGEXP', 'ASIN\s*([A-Z0-9]{10},)+'));
});
},
'payout',
'user',
'items.incentive',
'items.video',
]);
if(!permissionCheck('invoices.view.all')){
$invoices = $invoices->where('user_id', auth()->user()->id);
}
if (permissionCheck('hide-pending-invoices') && !is_admin_user(auth()->id())) {
$invoices = $invoices->where('invoices.is_approved', true);
}
$invoices = $invoices->orderBy('users.first_name')
->orderBy('users.last_name')
->orderBy('invoices.id', 'desc')
->get();
return InvoiceResource::collection($invoices);
// $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 show(Invoice $invoice)
{
$invoice->load(['user.staff']);
$videpUploadPayout = InvoiceItem::query()
//->selectRaw('name, description, SUM(quantity) as quantity, SUM(amount) as amount, issue_date')
//->groupBy('name', 'description')
->where('invoice_id', $invoice->id)
->where(fn ($query) => $query->where('name', 'Video upload payout'))
->orderBy('issue_date', 'asc')
->get();
$otherInvoiceItems = InvoiceItem::query()
//->selectRaw('name, description, SUM(quantity) as quantity, SUM(amount) as amount, issue_date')
//->groupBy('name', 'description')
->where('invoice_id', $invoice->id)
->where(fn ($query) => $query->where('name', '!=', 'Video upload payout'))
->orderBy('issue_date', 'asc')
->get();
$invoiceItems = collect($videpUploadPayout)->merge($otherInvoiceItems);
/*$invoiceItems = collect($invoiceItems)->map(function ($item) {
$item->issue_date = \Carbon\Carbon::parse($item->issue_date)->format('m-d-Y');
return $item;
});*/
$totalItemsAmount = $invoiceItems->pluck('amount')->sum();
$logoSetting = InvoiceSetting::query()
->where('name', 'logo')
->first();
$logo = $logoSetting
? asset("/public/storage/{$logoSetting->value}")
: asset('/Modules/StaffPayroll/Public/icons/wti.png');
$generalSetting = GeneralSetting::query()->first();
return [
'invoice' => $invoice,
'user' => $invoice->user,
'items' => $invoiceItems,
'total' => number_format($totalItemsAmount, 2),
'logo' => $logo,
'generalSetting' => $generalSetting,
'notes' => $invoice->notes,
];
}
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)
{
$invoice->status = $invoice->status == Invoice::STATUS_UNPAID ? Invoice::STATUS_PAID : Invoice::STATUS_UNPAID;
$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.',
]);
}
}