update marketing
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 5m14s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 17s
Build, Push and Deploy / deploy-staging (push) Successful in 41s
Build, Push and Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-05-14 11:55:22 +07:00
parent f80fcc4c1b
commit 05fd3230b8
448 changed files with 17545 additions and 5128 deletions

View File

@@ -3,11 +3,18 @@
namespace Modules\Business\App\Http\Controllers;
use App\Models\Party;
use App\Models\PaymentType;
use App\Helpers\HasUploader;
use App\Imports\PartyImport;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Maatwebsite\Excel\Facades\Excel;
use App\Events\MultiPaymentProcessed;
// use App\Models\Country;
// use App\Models\State;
use Illuminate\Support\Facades\Storage;
class AcnooPartyController extends Controller
{
@@ -30,16 +37,16 @@ public function index(Request $request)
$party_type = $request->input('type');
$query = Party::where('business_id', $business_id)
->when($search, function ($q) use ($search) {
$q->where(function ($q) use ($search) {
$q->where('name', 'like', '%' . $search . '%')
->orWhere('credit_limit', 'like', '%' . $search . '%')
->orWhere('phone', 'like', '%' . $search . '%')
->orWhere('type', 'like', '%' . $search . '%')
->orWhere('address', 'like', '%' . $search . '%')
->orWhere('due', 'like', '%' . $search . '%');
});
->when($search, function ($q) use ($search) {
$q->where(function ($q) use ($search) {
$q->where('name', 'like', '%'.$search.'%')
->orWhere('credit_limit', 'like', '%'.$search.'%')
->orWhere('phone', 'like', '%'.$search.'%')
->orWhere('type', 'like', '%'.$search.'%')
->orWhere('address', 'like', '%'.$search.'%')
->orWhere('due', 'like', '%'.$search.'%');
});
});
// Filter by party type
if ($party_type === 'Customer') {
@@ -54,11 +61,19 @@ public function index(Request $request)
$parties->setCollection(
$parties->getCollection()
->transform(function ($party) use ($activeBranch) {
$party_due = $party->type === 'Supplier'
? $party->purchases_dues->sum('dueAmount')
: $party->sales_dues->sum('dueAmount');
$originalDue = $party->getRawOriginal('due') ?? 0;
$originalOpeningBalance = $party->opening_balance ?? 0;
$party->due = $party->branch_id === $activeBranch->id ? $party_due + $party->due : $party_due;
$party_due = $party->type === 'Supplier'
? $party->purchases_dues->where('branch_id', $activeBranch->id)->sum('dueAmount')
: $party->sales_dues->where('branch_id', $activeBranch->id)->sum('dueAmount');
if ($party->branch_id === $activeBranch->id) {
$openingBalanceDue = $party->opening_balance_type === 'due' ? $originalOpeningBalance : 0;
$party->due = $openingBalanceDue + $party_due;
} else {
$party->due = $party_due;
}
return $party;
})
@@ -67,16 +82,20 @@ public function index(Request $request)
if ($request->ajax()) {
return response()->json([
'data' => view('business::parties.datas', compact('parties'))->render()
'data' => view('business::parties.datas', compact('parties'))->render(),
]);
}
return view('business::parties.index', compact('parties', 'party_type'));
}
public function create()
{
return view('business::parties.create');
$countries = [];
$states = [];
return view('business::parties.create', compact('countries', 'states'));
}
public function store(Request $request)
@@ -88,13 +107,12 @@ public function store(Request $request)
'email' => 'nullable|email',
'image' => 'nullable|image|mimes:jpeg,png,jpg,svg',
'address' => 'nullable|string|max:255',
'tax_no' => 'nullable|string|max:255',
'due' => 'nullable|numeric|min:0',
'billing_address' => 'nullable|array',
'billing_address.address' => 'nullable|string|max:255',
'billing_address.city' => 'nullable|string|max:255',
'billing_address.state' => 'nullable|string|max:255',
'billing_address.zip_code' => 'nullable|string|max:20',
'billing_address.country' => 'nullable|string|max:255',
'shipping_address' => 'nullable|array',
'shipping_address.address' => 'nullable|string|max:255',
'shipping_address.city' => 'nullable|string|max:255',
@@ -127,7 +145,10 @@ public function store(Request $request)
public function edit($id)
{
$party = Party::where('business_id', auth()->user()->business_id)->findOrFail($id);
return view('business::parties.edit', compact('party'));
$countries = [];
$states = [];
return view('business::parties.edit', compact('party', 'countries', 'states'));
}
public function update(Request $request, $id)
@@ -141,13 +162,12 @@ public function update(Request $request, $id)
'email' => 'nullable|email',
'image' => 'nullable|image|mimes:jpeg,png,jpg,svg',
'address' => 'nullable|string|max:255',
'tax_no' => 'nullable|string|max:255',
'due' => 'nullable|numeric|min:0',
'billing_address' => 'nullable|array',
'billing_address.address' => 'nullable|string|max:255',
'billing_address.city' => 'nullable|string|max:255',
'billing_address.state' => 'nullable|string|max:255',
'billing_address.zip_code' => 'nullable|string|max:20',
'billing_address.country' => 'nullable|string|max:255',
'shipping_address' => 'nullable|array',
'shipping_address.address' => 'nullable|string|max:255',
'shipping_address.city' => 'nullable|string|max:255',
@@ -210,6 +230,79 @@ public function update(Request $request, $id)
]);
}
public function advancePayment(string $id)
{
$party = Party::where('business_id', auth()->user()->business_id)->with(['sales_dues', 'purchases_dues'])->findOrFail($id);
$payment_types = PaymentType::where('business_id', auth()->user()->business_id)->whereStatus(1)->latest()->get();
return view('business::parties.advance-payment', compact('party', 'payment_types'));
}
public function advancePaymentStore(Request $request)
{
$request->validate([
'party_id' => 'required|exists:parties,id',
'amount' => 'required|numeric|min:0.01',
'date' => 'nullable|date',
'note' => 'nullable|string|max:255',
]);
DB::beginTransaction();
try {
$party = Party::findOrFail($request->party_id);
$payments = $request->payments ?? [];
if (isset($payments['main'])) {
$mainPayment = $payments['main'];
$mainPayment['amount'] = $request->amount ?? 0;
$payments = [$mainPayment];
}
// Only count actual received money (exclude cheque)
$payAmount = collect($payments)
->reject(fn($p) => strtolower($p['type'] ?? '') === 'cheque')
->sum(fn($p) => $p['amount'] ?? 0);
if ($payAmount <= 0) {
return response()->json([
'message' => __('No valid payment amount received (cheques are pending).')
], 400);
}
// Determine platform based on party type
$platform = $party->type === 'Supplier' ? 'advance_pay' : 'advance_collect';
$party->increment('wallet', $payAmount);
event(new MultiPaymentProcessed(
$payments,
$party->id,
$platform,
$payAmount,
$party->id,
$request->date ?? now(),
$request->note ?? null
));
DB::commit();
$type = in_array($party->type, ['Retailer', 'Dealer', 'Wholesaler']) ? 'Customer' : ($party->type === 'Supplier' ? 'Supplier' : '');
$message = $type === 'Supplier' ? __('Advance amount paid successfully.') : __('Advance amount collected successfully.');
return response()->json([
'message' => $message,
'redirect' => route('business.parties.index', ['type' => $type])
]);
} catch (\Exception $e) {
DB::rollback();
return response()->json([
'error' => 'Transaction failed: ' . $e->getMessage()
], 500);
}
}
public function destroy($id)
{
$party = Party::findOrFail($id);
@@ -266,4 +359,28 @@ public function deleteAll(Request $request)
]);
}
public function bulkStore(Request $request, $type)
{
$request->validate([
'file' => 'required|file|mimes:xlsx,xls,csv'
]);
$businessId = auth()->user()->business_id;
$import = new PartyImport($businessId);
try {
Excel::import($import, $request->file('file'));
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage(),
], 422);
}
return response()->json([
'success' => true,
'message' => __('Bulk upload successfully.'),
'redirect' => route('business.parties.index', ['type' => $type])
]);
}
}