migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,331 @@
<?php
namespace Modules\MultiBranchAddon\App\Http\Controllers;
use App\Models\Sale;
use App\Models\User;
use App\Models\Branch;
use App\Models\Income;
use App\Models\Expense;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;
class AcnooBranchController extends Controller
{
public function __construct()
{
$this->middleware('check.permission:branches.read')->only(['index']);
$this->middleware('check.permission:branches.create')->only(['store']);
$this->middleware('check.permission:branches.update')->only(['update']);
$this->middleware('check.permission:branches.delete')->only(['destroy', 'deleteAll']);
}
public function index(Request $request)
{
$branches = Branch::where('business_id', auth()->user()->business_id)
->when(request('search'), function ($q) use ($request) {
$q->where(function ($q) use ($request) {
$q->where('name', 'like', '%' . $request->search . '%')
->orWhere('phone', 'like', '%' . $request->search . '%')
->orWhere('email', 'like', '%' . $request->search . '%')
->orWhere('address', 'like', '%' . $request->search . '%');
});
})
->paginate($request->per_page ?? 20)->appends($request->query());
if ($request->ajax()) {
return response()->json([
'data' => view('multibranchaddon::branches.datas', compact('branches'))->render()
]);
}
return view('multibranchaddon::branches.index', compact('branches'));
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'phone' => 'nullable|string|max:20',
'email' => 'nullable|email|max:255',
'address' => 'nullable|string|max:255',
'branchOpeningBalance' => 'nullable|numeric|min:0',
'description' => 'nullable|string|max:1000',
]);
DB::beginTransaction();
try {
$business_id = auth()->user()->business_id;
$opening_balance = $request->branchOpeningBalance ?? 0;
$has_main_branch = Branch::where('business_id', $business_id)->where('is_main', 1)->exists();
if (!branch_count() || !$has_main_branch) {
manipulateBranchData($business_id);
}
Branch::create($request->except('branchOpeningBalance', 'branchRemainingBalance') + [
'branchRemainingBalance' => $opening_balance,
'branchOpeningBalance' => $opening_balance,
]);
Cache::forget('branch-count-' . $business_id);
DB::commit();
return response()->json([
'message' => __('Branch saved successfully.'),
'redirect' => route('multibranch.branches.index')
]);
} catch (\Exception $e) {
DB::rollback();
return response()->json(['message' => $e->getMessage()], 500);
}
}
public function update(Request $request, string $id)
{
$request->validate([
'name' => 'required|string|max:255',
'phone' => 'nullable|string|max:20',
'email' => 'nullable|email|max:255',
'address' => 'nullable|string|max:255',
'branchOpeningBalance' => 'nullable|numeric|min:0',
'description' => 'nullable|string|max:1000',
]);
$branch = Branch::findOrFail($id);
$updateData = $request->except('branchRemainingBalance');
$requestedOpeningBalance = $request->input('branchOpeningBalance');
if ($requestedOpeningBalance != $branch->branchOpeningBalance) {
if ($branch->branchRemainingBalance === $branch->branchOpeningBalance) {
$updateData['branchRemainingBalance'] = $requestedOpeningBalance;
} else {
return response()->json([
'message' => __('You cannot update opening balance because it differs from remaining balance.')
], 422);
}
}
$branch->update($updateData);
return response()->json([
'message' => __('Branch updated successfully.'),
'redirect' => route('multibranch.branches.index')
]);
}
public function destroy($id)
{
$business_id = auth()->user()->business_id;
$user = auth()->user();
$branch = Branch::where('business_id', $business_id)->findOrFail($id);
if ($branch->is_main) {
return response()->json([
'message' => __('You can not delete main branch.')
], 406);
}
// Auto exit if this is the active branch
if ($user->active_branch_id == $branch->id) {
$user->update([
'active_branch_id' => null
]);
}
User::where('branch_id', $branch->id)->delete();
$branch->delete();
Cache::forget('branch-count-' . $business_id);
return response()->json([
'message' => __('Branch deleted successfully'),
'redirect' => route('multibranch.branches.index'),
]);
}
public function deleteAll(Request $request)
{
$business_id = auth()->user()->business_id;
User::whereIn('branch_id', $request->ids)->delete();
Branch::where('business_id', $business_id)->where('is_main', 0)->whereIn('id', $request->ids)->delete();
Cache::forget('branch-count-' . $business_id);
return response()->json([
'message' => __('Selected branch deleted successfully'),
'redirect' => route('multibranch.branches.index'),
]);
}
public function overview()
{
$branches = [];
if (moduleCheck('HrmAddon')){
$branches = Branch::where('business_id', auth()->user()->business_id)->withCount('employees')->latest()->take(5)->get();
}
$branches_expired_products = Branch::where('business_id', auth()->user()->business_id)->whereHas('expiredStocks')->withCount('expiredStocks')->latest()->take(5)->get();
return view('multibranchaddon::branches.overview', compact('branches', 'branches_expired_products'));
}
public function branchWiseSales(Request $request)
{
$year = $request->get('year', date('Y'));
$branches_sales = Branch::where('business_id', auth()->user()->business_id)
->whereHas('sales', function ($q) use ($year) {
$q->whereYear('saleDate', $year);
})
->withSum(['sales as totalAmount' => function ($q) use ($year) {
$q->whereYear('saleDate', $year);
}], 'totalAmount')
->withSum(['sales as paidAmount' => function ($q) use ($year) {
$q->whereYear('saleDate', $year);
}], 'paidAmount')
->withSum(['sales as dueAmount' => function ($q) use ($year) {
$q->whereYear('saleDate', $year);
}], 'dueAmount')
->latest()
->take(5)
->get();
$branches_sales->transform(function ($branch) {
$branch->sales_sum_total_amount_formatted = currency_format($branch->totalAmount, currency: business_currency());
$branch->sales_sum_paid_amount_formatted = currency_format($branch->paidAmount, currency: business_currency());
$branch->sales_sum_due_amount_formatted = currency_format($branch->dueAmount, currency: business_currency());
return $branch;
});
return response()->json($branches_sales);
}
public function branchWisePurchases(Request $request)
{
$year = $request->get('year', date('Y'));
$branches_purchases = Branch::where('business_id', auth()->user()->business_id)
->whereHas('purchases', function ($q) use ($year) {
$q->whereYear('purchaseDate', $year);
})
->withSum(['purchases as totalAmount' => function ($q) use ($year) {
$q->whereYear('purchaseDate', $year);
}], 'totalAmount')
->withSum(['purchases as paidAmount' => function ($q) use ($year) {
$q->whereYear('purchaseDate', $year);
}], 'paidAmount')
->withSum(['purchases as dueAmount' => function ($q) use ($year) {
$q->whereYear('purchaseDate', $year);
}], 'dueAmount')
->latest()
->take(5)
->get();
$branches_purchases->transform(function ($branch) {
$branch->purchases_sum_total_amount_formatted = currency_format($branch->totalAmount, currency: business_currency());
$branch->purchases_sum_paid_amount_formatted = currency_format($branch->paidAmount, currency: business_currency());
$branch->purchases_sum_due_amount_formatted = currency_format($branch->dueAmount, currency: business_currency());
return $branch;
});
return response()->json($branches_purchases);
}
public function incomeExpense(Request $request)
{
$data['expenses'] = Sale::where('business_id', auth()->user()->business_id)
->whereYear('created_at', request('year') ?? date('Y'))
->where('lossProfit', '<', 0)
->selectRaw('MONTH(created_at) as month_number, MONTHNAME(created_at) as month, SUM(ABS(lossProfit)) as total')
->groupBy('month_number', 'month')
->orderBy('month_number')
->get();
$data['incomes'] = Sale::where('business_id', auth()->user()->business_id)
->whereYear('created_at', request('year') ?? date('Y'))
->where('lossProfit', '>=', 0)
->selectRaw('MONTH(created_at) as month_number, MONTHNAME(created_at) as month, SUM(ABS(lossProfit)) as total')
->groupBy('month_number', 'month')
->orderBy('month_number')
->get();
return response()->json($data);
}
public function earningData(Request $request)
{
$year = $request->year ?? date('Y');
$businessId = auth()->user()->business_id;
$profit = Income::where('business_id', $businessId)
->whereYear('incomeDate', $year)
->sum('amount');
$loss = Expense::where('business_id', $businessId)
->whereYear('expenseDate', $year)
->sum('amount');
// Get the total loss/profit for the month
$sale_loss_profit = Sale::where('business_id', $businessId)
->whereYear('saleDate', $year)
->sum('lossProfit');
// Update income and expense based on lossProfit value
$profit += $sale_loss_profit > 0 ? $sale_loss_profit : 0;
$loss += $sale_loss_profit < 0 ? abs($sale_loss_profit) : 0;
$data = [
'profit' => $profit,
'loss' => $loss,
];
return response()->json($data);
}
public function status(Request $request, $id)
{
$branch = Branch::findOrFail($id);
$branch->update(['status' => $request->status]);
return response()->json(['message' => __('Branch')]);
}
public function switchBranch($id)
{
if (!auth()->user()->branch_id) {
$branch = Branch::where('business_id', auth()->user()->business_id)->findOrFail($id);
auth()->user()->update([
'active_branch_id' => $branch->id
]);
auth()->user()->tokens()->delete();
return redirect(route('business.dashboard.index'))->with('message', "You've successfully login to " . $branch->name);
} else {
return redirect(route('business.dashboard.index'))->with('warning', "You're not permitted to login on this branch.");
}
}
public function exitBranch($id)
{
if (auth()->user()->active_branch_id) {
$branch = Branch::where('business_id', auth()->user()->business_id)->findOrFail($id);
auth()->user()->update([
'active_branch_id' => null
]);
auth()->user()->tokens()->delete();
return redirect(route('business.dashboard.index'))->with('message', "You've successfully exit from " . $branch->name);
} else {
return redirect(route('business.dashboard.index'))->with('warning', "You're not permitted to exit from this branch.");
}
}
}

View File

@@ -0,0 +1,173 @@
<?php
namespace Modules\MultiBranchAddon\App\Http\Controllers\Api;
use App\Models\User;
use App\Models\Branch;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;
class AcnooBranchController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$data = Branch::where('business_id', auth()->user()->business_id)->latest()->get();
return response()->json([
'message' => __('Data fetched successfully.'),
'data' => $data,
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'phone' => 'nullable|string|max:20',
'email' => 'nullable|email|max:255',
'address' => 'nullable|string|max:255',
'branchOpeningBalance' => 'nullable|numeric|min:0',
'description' => 'nullable|string|max:1000',
]);
DB::beginTransaction();
try {
$opening_balance = $request->branchOpeningBalance ?? 0;
$business_id = auth()->user()->business_id;
$has_main_branch = Branch::where('business_id', $business_id)->where('is_main', 1)->exists();
if (!branch_count() || !$has_main_branch) {
manipulateBranchData($business_id);
}
Branch::create($request->except('branchOpeningBalance', 'branchRemainingBalance') + [
'branchRemainingBalance' => $opening_balance,
'branchOpeningBalance' => $opening_balance,
]);
Cache::forget('branch-count-' . $business_id);
DB::commit();
return response()->json([
'message' => __('Branch saved successfully.'),
]);
} catch (\Exception $e) {
DB::rollback();
return response()->json(['message' => $e->getMessage()], 500);
}
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$request->validate([
'name' => 'required|string|max:255',
'phone' => 'nullable|string|max:20',
'email' => 'nullable|email|max:255',
'address' => 'nullable|string|max:255',
'branchOpeningBalance' => 'nullable|numeric|min:0',
'description' => 'nullable|string|max:1000',
]);
$branch = Branch::findOrFail($id);
$updateData = $request->except('branchRemainingBalance');
$requestedOpeningBalance = $request->input('branchOpeningBalance');
if ($requestedOpeningBalance != $branch->branchOpeningBalance) {
if ($branch->branchRemainingBalance === $branch->branchOpeningBalance) {
$updateData['branchRemainingBalance'] = $requestedOpeningBalance;
} else {
return response()->json([
'message' => __('You cannot update opening balance because it differs from remaining balance.')
], 422);
}
}
$branch->update($updateData);
return response()->json([
'message' => __('Branch updated successfully.')
]);
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
$business_id = auth()->user()->business_id;
$user = auth()->user();
$branch = Branch::where('business_id', $business_id)->findOrFail($id);
if ($branch->is_main) {
return response()->json([
'message' => __('You can not delete main branch.')
], 406);
}
// Auto exit if this is the active branch
if ($user->active_branch_id == $branch->id) {
$user->update([
'active_branch_id' => null
]);
}
User::where('branch_id', $branch->id)->delete();
$branch->delete();
Cache::forget('branch-count-' . $business_id);
return response()->json([
'message' => __('Branch deleted successfully'),
'redirect' => route('multibranch.branches.index'),
]);
}
public function switchBranch(string $id)
{
if (!auth()->user()->branch_id) {
$branch = Branch::where('business_id', auth()->user()->business_id)->findOrFail($id);
auth()->user()->update([
'active_branch_id' => $branch->id
]);
return response()->json([
'message' => "You've successfully login to " . $branch->name,
]);
} else {
return response()->json([
'message' => "You're not permitted to login on this branch.",
]);
}
}
public function exitBranch(string $id)
{
if (auth()->user()->active_branch_id) {
$branch = Branch::where('business_id', auth()->user()->business_id)->findOrFail($id);
auth()->user()->update([
'active_branch_id' => null
]);
return response()->json([
'message' => "You've successfully exit from " . $branch->name,
]);
} else {
return response()->json([
'message' => "You're not permitted to exit from this branch.",
]);
}
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace Modules\MultiBranchAddon\App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class MultiBranchAddonServiceProvider extends ServiceProvider
{
protected string $moduleName = 'MultiBranchAddon';
protected string $moduleNameLower = 'multibranchaddon';
/**
* Boot the application events.
*/
public function boot(): void
{
$this->registerCommands();
$this->registerCommandSchedules();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/migrations'));
}
/**
* Register the service provider.
*/
public function register(): void
{
$this->app->register(RouteServiceProvider::class);
}
/**
* Register commands in the format of Command::class
*/
protected function registerCommands(): void
{
//
}
/**
* Register command Schedules.
*/
protected function registerCommandSchedules(): void
{
//
}
/**
* Register translations.
*/
public function registerTranslations(): void
{
$langPath = resource_path('lang/modules/' . $this->moduleNameLower);
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
$this->loadJsonTranslationsFrom($langPath);
} else {
$this->loadTranslationsFrom(module_path($this->moduleName, 'lang'), $this->moduleNameLower);
$this->loadJsonTranslationsFrom(module_path($this->moduleName, 'lang'));
}
}
/**
* Register config.
*/
protected function registerConfig(): void
{
$this->publishes([module_path($this->moduleName, 'config/config.php') => config_path($this->moduleNameLower . '.php')], 'config');
$this->mergeConfigFrom(module_path($this->moduleName, 'config/config.php'), $this->moduleNameLower);
}
/**
* Register views.
*/
public function registerViews(): void
{
$viewPath = resource_path('views/modules/' . $this->moduleNameLower);
$sourcePath = module_path($this->moduleName, 'resources/views');
$this->publishes([$sourcePath => $viewPath], ['views', $this->moduleNameLower . '-module-views']);
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
$componentNamespace = str_replace('/', '\\', config('modules.namespace') . '\\' . $this->moduleName . '\\' . config('modules.paths.generator.component-class.path'));
Blade::componentNamespace($componentNamespace, $this->moduleNameLower);
}
/**
* Get the services provided by the provider.
*/
public function provides(): array
{
return [];
}
private function getPublishableViewPaths(): array
{
$paths = [];
foreach (config('view.paths') as $path) {
if (is_dir($path . '/modules/' . $this->moduleNameLower)) {
$paths[] = $path . '/modules/' . $this->moduleNameLower;
}
}
return $paths;
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Modules\MultiBranchAddon\App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* The module namespace to assume when generating URLs to actions.
*/
protected string $moduleNamespace = 'Modules\MultiBranchAddon\App\Http\Controllers';
/**
* Called before routes are registered.
*
* Register any model bindings or pattern based filters.
*/
public function boot(): void
{
parent::boot();
}
/**
* Define the routes for the application.
*/
public function map(): void
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*/
protected function mapWebRoutes(): void
{
Route::middleware('web')
->namespace($this->moduleNamespace)
->group(module_path('MultiBranchAddon', '/routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapApiRoutes(): void
{
Route::prefix('api')
->middleware('api')
->namespace($this->moduleNamespace)
->group(module_path('MultiBranchAddon', '/routes/api.php'));
}
}