관리-도구
편집 파일: SubscriptionController.php
<?php namespace App\Http\Controllers; use App\Models\Subscription; use App\Models\Sale; use App\Models\SaleDetail; use App\Models\Product; use App\Models\Client; use App\Models\Warehouse; use App\Models\PaymentSale; use App\Models\product_warehouse; use App\Models\Role; use App\Models\User; use Carbon\Carbon; use App\utils\helpers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Http; use GuzzleHttp\Client as guzzle_client; class SubscriptionController extends BaseController { //-------------- Get All Subscription ---------------\\ public function index(Request $request) { $this->authorizeForUser($request->user('api'), 'view', Subscription::class); // How many items do you want to display. $perPage = $request->limit; $pageStart = \Request::get('page', 1); // Start displaying items from this number; $offSet = ($pageStart * $perPage) - $perPage; $order = $request->SortField; $dir = $request->SortType; $subscription_data = Subscription::where(function ($query) use ($request) { return $query->when($request->filled('search'), function ($query) use ($request) { return $query->where('name', 'LIKE', "%{$request->search}%"); }); }); $totalRows = $subscription_data->count(); if($perPage == "-1"){ $perPage = $totalRows; } $subscriptions = $subscription_data->offset($offSet) ->limit($perPage) ->orderBy($order, $dir) ->get(); $data = []; foreach ($subscriptions as $subscription) { $item['id'] = $subscription->id; $item['client_name'] = $subscription['client']?$subscription['client']->name:'---'; $item['product_name'] = $subscription['product']?$subscription['product']->name:'---'; $item['warehouse_name'] = $subscription['warehouse']?$subscription['warehouse']->name:'---'; $item['billing_cycle'] = $subscription->billing_cycle; $item['total_cycles'] = $subscription->total_cycles .' '.$subscription->cycle_type; $item['price'] = $subscription->price; $item['remaining_cycles'] = $subscription->remaining_cycles; $item['next_billing_date'] = $subscription->next_billing_date; $item['status'] = $subscription->status; $data[] = $item; } return response()->json([ 'subscriptions' => $data, 'totalRows' => $totalRows, ]); } //------------ function create -----------\\ public function create(Request $request) { $this->authorizeForUser($request->user('api'), 'create', Subscription::class); $clients = Client::where('deleted_at', '=', null)->get(['id', 'name']); $products = Product::where('deleted_at', '=', null)->get(['id', 'name']); $warehouses = Warehouse::where('deleted_at', '=', null)->get(['id', 'name']); return response()->json([ 'clients' => $clients, 'products' => $products, 'warehouses' => $warehouses, ]); } //-------------- Store New ---------------\\ public function store(Request $request) { $this->authorizeForUser($request->user('api'), 'create', Subscription::class); $validatedData = $request->validate([ 'subscription.client_id' => 'required|exists:clients,id', 'subscription.product_id' => 'required|exists:products,id', 'subscription.warehouse_id' => 'required|exists:warehouses,id', 'subscription.total_cycles' => 'required|integer|min:1', 'subscription.cycle_type' => 'required|in:weekly,monthly,yearly', 'subscription.billing_cycle' => 'required|in:weekly,monthly,yearly', 'subscription.price_per_cycle' => 'required|numeric|min:0', 'subscription.price_per_unit' => 'required|numeric|min:0', 'subscription.quantity' => 'required|integer|min:1', 'subscription.next_billing_date' => 'required|date', 'subscription.status' => 'required|in:active,canceled,completed', ]); $data = $validatedData['subscription']; // Calculate remaining cycles $remaining_cycles = $this->calculateRemainingCycles( $data['total_cycles'], $data['cycle_type'], $data['billing_cycle'] ); // Create new subscription $subscription = Subscription::create([ 'date' => now(), 'user_id' => auth()->id(), 'client_id' => $data['client_id'], 'product_id' => $data['product_id'], 'warehouse_id' => $data['warehouse_id'], 'total_cycles' => $data['total_cycles'], 'cycle_type' => $data['cycle_type'], 'billing_cycle' => $data['billing_cycle'], 'remaining_cycles' => $remaining_cycles, 'price_per_cycle' => $data['price_per_cycle'], 'price_per_unit' => $data['price_per_unit'], 'quantity' => $data['quantity'], 'next_billing_date' => $data['next_billing_date'], 'status' => $data['status'], ]); // Check if next billing date is today, generate invoice immediately if (Carbon::parse($subscription->next_billing_date)->isToday()) { $subscription->generateInvoice(); } return response()->json([ 'message' => 'Subscription created successfully!', 'subscription' => $subscription ], 201); } private function calculateRemainingCycles($total_cycles, $cycle_type, $billing_cycle) { // Define durations in days $durations = [ 'yearly' => 365, 'monthly' => 30.4375, // Average month duration 'weekly' => 7, ]; // Get the total duration in days based on the cycle type (how long the subscription lasts) $total_duration = $total_cycles * ($durations[$cycle_type] ?? 1); // Get the billing cycle duration in days (how often the customer pays) $billing_duration = $durations[$billing_cycle] ?? 1; // Calculate how many payments the user needs to make $remaining_cycles = intval($total_duration / $billing_duration); return max($remaining_cycles, 1); // Ensure at least 1 cycle } //------------ function show -----------\\ public function show(Request $request , $id) { $this->authorizeForUser($request->user('api'), 'view', Subscription::class); $subscription = Subscription::with(['client', 'product', 'warehouse', 'invoices'])->findOrFail($id); return response()->json([ 'subscription' => [ 'id' => $subscription->id, 'client' => $subscription->client->name, 'product' => $subscription->product->name, 'warehouse' => $subscription->warehouse->name, 'billing_cycle' => $subscription->billing_cycle, 'price_per_cycle' => number_format($subscription->price_per_cycle, 2, '.', ','), 'next_billing_date' => $subscription->next_billing_date, 'status' => $subscription->status, ], 'invoices' => $subscription->invoices->map(function ($invoice) { return [ 'sale_id' => $invoice->id, 'ref' => $invoice->Ref, 'date' => $invoice->date, 'total' => number_format($invoice->GrandTotal, 2, '.', ','), 'status' => $invoice->payment_statut, ]; }), 'invoiceFields' => [ ['key' => 'ref', 'label' => 'Invoice Ref'], ['key' => 'date', 'label' => 'Date'], ['key' => 'total', 'label' => 'Total Amount'], ['key' => 'status', 'label' => 'Status'], ], ]); } //-------------- Update ---------------\\ public function update(Request $request, $id) { // } //-------------- Delete Subscription ---------------\\ public function destroy(Request $request, $id) { $this->authorizeForUser($request->user('api'), 'delete', Subscription::class); Subscription::whereId($id)->update([ 'deleted_at' => Carbon::now(), ]); return response()->json(['success' => true], 200); } public function updateStatus(Request $request, $id) { $request->validate([ 'status' => 'required|in:active,canceled,completed', ]); $subscription = Subscription::findOrFail($id); $subscription->update([ 'status' => $request->status, ]); return response()->json(['message' => 'Subscription status updated successfully!']); } }