Bank Account Management: - BankAccountsController with full CRUD operations - BankAccountService for account management logic - Bank account views (index, create, edit) - GL account linking for cash accounts Bank Transfers: - BankTransfersController with approval workflow - BankTransfer model with status management - Inter-business transfer support - Transfer views (index, create, show) Plaid Integration Infrastructure: - PlaidItem, PlaidAccount, PlaidTransaction models - PlaidIntegrationService with 10+ methods (stubbed API) - BankReconciliationController with match/learn flows - Bank match rules for auto-categorization Journal Entry Automation: - JournalEntryService for automatic JE creation - Bill approval creates expense entries - Payment completion creates cash entries - Inter-company Due To/Due From entries AR Enhancements: - ArService with getArSummary and getTopArAccounts - Finance dashboard AR section with drill-down stats - Credit hold and at-risk tracking - Top AR accounts table with division column UI/Navigation: - Updated SuiteMenuResolver with new menu items - Removed Usage & Billing from sidebar (moved to Owner) - Brand Manager Suite menu items added - Vendors page shows divisions using each vendor Models and Migrations: - BankAccount, BankTransfer, BankMatchRule models - PlaidItem, PlaidAccount, PlaidTransaction models - Credit hold fields on ArCustomer - journal_entry_id on ap_bills and ap_payments
62 lines
2.3 KiB
PHP
62 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Seller\Management;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Business;
|
|
use App\Services\Accounting\InventoryValuationService;
|
|
use App\Support\ManagementDivisionFilter;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
|
|
class InventoryValuationController extends Controller
|
|
{
|
|
use ManagementDivisionFilter;
|
|
|
|
public function __construct(
|
|
protected InventoryValuationService $valuationService
|
|
) {}
|
|
|
|
/**
|
|
* Display the inventory valuation dashboard.
|
|
*/
|
|
public function index(Request $request, Business $business): View
|
|
{
|
|
$this->requireManagementSuite($business);
|
|
|
|
$filterData = $this->getDivisionFilterData($business, $request);
|
|
|
|
// Determine scope
|
|
$targetBusiness = $filterData['selectedDivision'] ?? $business;
|
|
$includeChildren = $filterData['selectedDivision'] === null && $business->hasChildBusinesses();
|
|
$businessIds = $includeChildren
|
|
? $business->childBusinesses()->pluck('id')->push($business->id)->toArray()
|
|
: [$targetBusiness->id];
|
|
|
|
// Get valuation data
|
|
$summary = $this->valuationService->getValuationSummary($businessIds);
|
|
$byType = $this->valuationService->getValuationByType($businessIds);
|
|
$byDivision = $includeChildren ? $this->valuationService->getValuationByDivision($businessIds) : collect();
|
|
$byCategory = $this->valuationService->getValuationByCategory($businessIds);
|
|
$byLocation = $this->valuationService->getValuationByLocation($businessIds);
|
|
$topItems = $this->valuationService->getTopItemsByValue($businessIds, 10);
|
|
$aging = $this->valuationService->getInventoryAging($businessIds);
|
|
$atRisk = $this->valuationService->getInventoryAtRisk($businessIds);
|
|
|
|
return view('seller.management.inventory-valuation.index', $this->withDivisionFilter([
|
|
'business' => $business,
|
|
'summary' => $summary,
|
|
'byType' => $byType,
|
|
'byDivision' => $byDivision,
|
|
'byCategory' => $byCategory,
|
|
'byLocation' => $byLocation,
|
|
'topItems' => $topItems,
|
|
'aging' => $aging,
|
|
'atRisk' => $atRisk,
|
|
'isParent' => $business->hasChildBusinesses(),
|
|
], $filterData));
|
|
}
|
|
}
|