2025-11-21 16:07:43 +05:30
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
|
|
|
|
|
|
use App\Http\Controllers\Controller;
|
|
|
|
|
use App\Models\Entry;
|
|
|
|
|
use App\Models\Order;
|
|
|
|
|
use App\Models\Installment;
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
|
|
|
|
|
|
class AdminAccountController extends Controller
|
|
|
|
|
{
|
2025-12-02 18:11:58 +05:30
|
|
|
public function updateEntry(Request $request)
|
2025-12-01 10:34:27 +05:30
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$data = $request->validate([
|
2025-12-02 18:11:58 +05:30
|
|
|
'entry_no' => 'required|exists:entries,entry_no',
|
|
|
|
|
'description' => 'required|string|max:255',
|
|
|
|
|
'order_quantity' => 'required|numeric|min:0',
|
|
|
|
|
'region' => 'required|string|max:50',
|
|
|
|
|
'amount' => 'required|numeric|min:0',
|
2025-12-04 12:08:45 +05:30
|
|
|
//'payment_status' => 'required|string|max:50',
|
2025-12-01 10:34:27 +05:30
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$entry = Entry::where('entry_no', $data['entry_no'])->first();
|
|
|
|
|
|
|
|
|
|
if (!$entry) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Entry not found.',
|
|
|
|
|
], 404);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$entry->description = $data['description'];
|
|
|
|
|
$entry->order_quantity = $data['order_quantity'];
|
2025-12-02 18:11:58 +05:30
|
|
|
$entry->region = $data['region'];
|
|
|
|
|
$entry->amount = $data['amount'];
|
2025-12-04 12:08:45 +05:30
|
|
|
//$entry->payment_status = $data['payment_status'];
|
2025-12-02 18:11:58 +05:30
|
|
|
|
2025-12-01 10:34:27 +05:30
|
|
|
$entry->save();
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Entry updated successfully.',
|
|
|
|
|
'entry' => $entry,
|
|
|
|
|
]);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Server error: '.$e->getMessage(),
|
|
|
|
|
], 500);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-21 16:07:43 +05:30
|
|
|
/**
|
|
|
|
|
* 🚀 1. Get dashboard entries
|
|
|
|
|
*/
|
|
|
|
|
public function getDashboardData()
|
|
|
|
|
{
|
|
|
|
|
$entries = Entry::withCount('installments')
|
|
|
|
|
->orderBy('id', 'desc')
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'entries' => $entries
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 🚀 2. Get available consolidated orders
|
|
|
|
|
*/
|
|
|
|
|
public function getAvailableOrders()
|
|
|
|
|
{
|
2025-12-03 16:17:14 +05:30
|
|
|
|
|
|
|
|
$orders = Order::whereDoesntHave('entries')
|
|
|
|
|
->orderBy('id', 'desc')
|
|
|
|
|
->get();
|
2025-12-02 18:11:58 +05:30
|
|
|
|
2025-11-21 16:07:43 +05:30
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
2025-12-02 18:11:58 +05:30
|
|
|
'orders' => $orders,
|
2025-11-21 16:07:43 +05:30
|
|
|
]);
|
|
|
|
|
}
|
2025-12-02 18:11:58 +05:30
|
|
|
|
2025-11-21 16:07:43 +05:30
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 🚀 3. Create new entry
|
|
|
|
|
*/
|
|
|
|
|
public function accountCreateOrder(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'description' => 'required|string|max:255',
|
|
|
|
|
'region' => 'required|string|max:50',
|
|
|
|
|
'amount' => 'required|numeric|min:1',
|
|
|
|
|
'entry_date' => 'nullable|date',
|
|
|
|
|
'selected_orders' => 'nullable|array',
|
|
|
|
|
'selected_orders.*'=> 'integer|exists:orders,id',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return DB::transaction(function () use ($data) {
|
|
|
|
|
|
|
|
|
|
$entryDate = $data['entry_date'] ?? now()->toDateString();
|
|
|
|
|
|
|
|
|
|
// Count selected consolidated orders
|
|
|
|
|
$orderQuantity = !empty($data['selected_orders'])
|
|
|
|
|
? count($data['selected_orders'])
|
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
|
|
// Generate entry No: PAY-2025-001
|
|
|
|
|
$prefix = 'PAY-' . date('Y') . '-';
|
|
|
|
|
$last = Entry::where('entry_no', 'like', $prefix . '%')
|
|
|
|
|
->orderBy('id', 'desc')
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
$next = $last
|
|
|
|
|
? intval(substr($last->entry_no, strrpos($last->entry_no, '-') + 1)) + 1
|
|
|
|
|
: 1;
|
|
|
|
|
|
|
|
|
|
$entryNo = $prefix . str_pad($next, 7, '0', STR_PAD_LEFT);
|
|
|
|
|
|
|
|
|
|
// Create entry
|
|
|
|
|
$entry = Entry::create([
|
|
|
|
|
'entry_no' => $entryNo,
|
|
|
|
|
'description' => $data['description'],
|
|
|
|
|
'region' => $data['region'],
|
|
|
|
|
'order_quantity' => $orderQuantity,
|
|
|
|
|
'amount' => $data['amount'],
|
|
|
|
|
'pending_amount' => $data['amount'],
|
|
|
|
|
'entry_date' => $entryDate,
|
|
|
|
|
'payment_status' => 'unpaid',
|
|
|
|
|
'toggle_pos' => 0,
|
|
|
|
|
'dispatch_status' => 'pending',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Attach consolidated orders
|
|
|
|
|
if (!empty($data['selected_orders'])) {
|
|
|
|
|
$entry->orders()->attach($data['selected_orders']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$entry->load('orders');
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Entry Created Successfully',
|
|
|
|
|
'entry' => $entry
|
|
|
|
|
], 201);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 🚀 4. Toggle payment switch
|
|
|
|
|
*/
|
|
|
|
|
public function togglePayment(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$request->validate([
|
|
|
|
|
'entry_no' => 'required|string|exists:entries,entry_no',
|
|
|
|
|
'toggle_pos' => 'required|integer|in:0,1,2',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$entry = Entry::where('entry_no', $request->entry_no)->firstOrFail();
|
|
|
|
|
|
|
|
|
|
$map = [
|
|
|
|
|
0 => 'unpaid',
|
|
|
|
|
1 => 'pending',
|
|
|
|
|
2 => 'paid'
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$entry->update([
|
|
|
|
|
'toggle_pos' => $request->toggle_pos,
|
|
|
|
|
'payment_status' => $map[$request->toggle_pos],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'entry' => $entry
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 🚀 5. Add Installment
|
|
|
|
|
*/
|
|
|
|
|
public function addInstallment(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'entry_no' => 'required|exists:entries,entry_no',
|
|
|
|
|
'proc_date' => 'nullable|date',
|
|
|
|
|
'amount' => 'required|numeric|min:1',
|
|
|
|
|
'status' => 'required|string'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return DB::transaction(function () use ($data) {
|
|
|
|
|
|
|
|
|
|
$entry = Entry::where('entry_no', $data['entry_no'])
|
|
|
|
|
->lockForUpdate()
|
|
|
|
|
->firstOrFail();
|
|
|
|
|
|
|
|
|
|
$amount = floatval($data['amount']);
|
|
|
|
|
|
|
|
|
|
if ($amount > $entry->pending_amount) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Installment cannot exceed pending amount.'
|
|
|
|
|
], 422);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$installment = Installment::create([
|
|
|
|
|
'entry_id' => $entry->id,
|
|
|
|
|
'proc_date' => $data['proc_date'] ?? now()->toDateString(),
|
|
|
|
|
'amount' => $amount,
|
|
|
|
|
'description'=> $entry->description,
|
|
|
|
|
'region' => $entry->region,
|
|
|
|
|
'status' => $data['status']
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$entry->pending_amount -= $amount;
|
|
|
|
|
|
|
|
|
|
if ($entry->pending_amount <= 0.001) {
|
|
|
|
|
$entry->pending_amount = 0;
|
|
|
|
|
$entry->dispatch_status = 'dispatched';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$entry->save();
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'entry' => $entry,
|
|
|
|
|
'installment' => $installment
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 🚀 6. Update Installment Status
|
|
|
|
|
*/
|
|
|
|
|
public function updateInstallmentStatus(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'installment_id' => 'required|exists:installments,id',
|
|
|
|
|
'status' => 'required|string|max:50'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return DB::transaction(function () use ($data) {
|
|
|
|
|
|
|
|
|
|
$installment = Installment::lockForUpdate()->findOrFail($data['installment_id']);
|
|
|
|
|
|
|
|
|
|
$installment->status = $data['status'];
|
|
|
|
|
$installment->save();
|
|
|
|
|
|
|
|
|
|
$entry = Entry::lockForUpdate()->find($installment->entry_id);
|
|
|
|
|
|
|
|
|
|
// If ANY installment is not delivered — entry is NOT delivered
|
|
|
|
|
if ($entry->installments()->where('status', '!=', 'Delivered')->exists()) {
|
|
|
|
|
// entry still in progress
|
|
|
|
|
$entry->dispatch_status = 'pending';
|
|
|
|
|
} else {
|
|
|
|
|
// all installments delivered
|
|
|
|
|
$entry->dispatch_status = 'delivered';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$entry->save();
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Installment updated successfully',
|
|
|
|
|
'installment' => $installment,
|
|
|
|
|
'entry' => $entry
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 🚀 6. Entry Details (installment history)
|
|
|
|
|
*/
|
|
|
|
|
public function getEntryDetails($entry_no)
|
|
|
|
|
{
|
|
|
|
|
$entry = Entry::with('installments')
|
|
|
|
|
->where('entry_no', $entry_no)
|
|
|
|
|
->firstOrFail();
|
|
|
|
|
|
|
|
|
|
$totalProcessed = $entry->amount - $entry->pending_amount;
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'entry' => $entry,
|
|
|
|
|
'total_processed' => $totalProcessed,
|
|
|
|
|
'pending' => $entry->pending_amount,
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-12-01 10:34:27 +05:30
|
|
|
|
|
|
|
|
//--------------------------
|
|
|
|
|
//add order Entry
|
|
|
|
|
//--------------------------
|
|
|
|
|
public function addOrdersToEntry(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'entry_no' => 'required|exists:entries,entry_no',
|
|
|
|
|
'order_ids' => 'required|array',
|
|
|
|
|
'order_ids.*' => 'integer|exists:orders,id',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return DB::transaction(function () use ($data) {
|
|
|
|
|
$entry = Entry::where('entry_no', $data['entry_no'])->firstOrFail();
|
|
|
|
|
|
2025-12-02 18:11:58 +05:30
|
|
|
|
2025-12-01 10:34:27 +05:30
|
|
|
$entry->orders()->syncWithoutDetaching($data['order_ids']);
|
|
|
|
|
|
|
|
|
|
$entry->order_quantity = $entry->orders()->count();
|
|
|
|
|
$entry->save();
|
|
|
|
|
|
|
|
|
|
$entry->load('orders');
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Orders added successfully.',
|
|
|
|
|
'entry' => $entry,
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getEntryOrders($entry_no)
|
|
|
|
|
{
|
|
|
|
|
$entry = Entry::where('entry_no', $entry_no)
|
|
|
|
|
->with('orders')
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
if (!$entry) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Entry not found.',
|
|
|
|
|
], 404);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'orders' => $entry->orders,
|
|
|
|
|
]);
|
2025-11-21 16:07:43 +05:30
|
|
|
}
|
2025-12-01 10:34:27 +05:30
|
|
|
|
|
|
|
|
public function removeOrderFromEntry(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'entry_no' => 'required|exists:entries,entry_no',
|
|
|
|
|
'order_id' => 'required|integer|exists:orders,id',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return DB::transaction(function () use ($data) {
|
|
|
|
|
$entry = Entry::where('entry_no', $data['entry_no'])->firstOrFail();
|
|
|
|
|
|
|
|
|
|
// order detach करा
|
|
|
|
|
$entry->orders()->detach($data['order_id']);
|
|
|
|
|
|
|
|
|
|
// इथे quantity auto update
|
|
|
|
|
$entry->order_quantity = $entry->orders()->count();
|
|
|
|
|
$entry->save();
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Order removed successfully.',
|
|
|
|
|
'entry' => $entry,
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-12-02 18:11:58 +05:30
|
|
|
public function deleteEntry(Request $request)
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'entry_no' => 'required|exists:entries,entry_no',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$entry = Entry::where('entry_no', $data['entry_no'])->first();
|
|
|
|
|
|
|
|
|
|
if (!$entry) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Entry not found.',
|
|
|
|
|
], 404);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$entry->delete();
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => 'Entry deleted successfully.',
|
|
|
|
|
]);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Server error: '.$e->getMessage(),
|
|
|
|
|
], 500);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-01 10:34:27 +05:30
|
|
|
|
|
|
|
|
}
|