fix(inventory): 修復倉庫低庫存警告計算與全站租戶名稱動態化
This commit is contained in:
@@ -37,6 +37,12 @@ class WarehouseController extends Controller
|
|||||||
->orWhere('expiry_date', '>=', now());
|
->orWhere('expiry_date', '>=', now());
|
||||||
});
|
});
|
||||||
}], 'quantity')
|
}], 'quantity')
|
||||||
|
->addSelect(['low_stock_count' => function ($query) {
|
||||||
|
$query->selectRaw('count(*)')
|
||||||
|
->from('warehouse_product_safety_stocks as ss')
|
||||||
|
->whereColumn('ss.warehouse_id', 'warehouses.id')
|
||||||
|
->whereRaw('(SELECT COALESCE(SUM(quantity), 0) FROM inventories WHERE warehouse_id = ss.warehouse_id AND product_id = ss.product_id) < ss.safety_stock');
|
||||||
|
}])
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
->paginate(10)
|
->paginate(10)
|
||||||
->withQueryString();
|
->withQueryString();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default function ApplicationLogo(props: ImgHTMLAttributes<HTMLImageElemen
|
|||||||
<img
|
<img
|
||||||
{...props}
|
{...props}
|
||||||
src="/logo.png"
|
src="/logo.png"
|
||||||
alt="小小冰室 Logo"
|
alt={`${branding?.short_name || 'Star'} Logo`}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ export default function AuthenticatedLayout({
|
|||||||
</button>
|
</button>
|
||||||
<Link href="/" className="flex items-center gap-2">
|
<Link href="/" className="flex items-center gap-2">
|
||||||
<ApplicationLogo className="w-8 h-8 rounded-lg object-contain" />
|
<ApplicationLogo className="w-8 h-8 rounded-lg object-contain" />
|
||||||
<span className="font-bold text-slate-900">{branding?.short_name || '小小冰室'} ERP</span>
|
<span className="font-bold text-slate-900">{branding?.short_name || 'Star'} ERP</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -510,7 +510,7 @@ export default function AuthenticatedLayout({
|
|||||||
{!isCollapsed && (
|
{!isCollapsed && (
|
||||||
<Link href="/" className="flex items-center gap-2 group">
|
<Link href="/" className="flex items-center gap-2 group">
|
||||||
<ApplicationLogo className="w-8 h-8 rounded-lg object-contain group-hover:scale-110 transition-transform" />
|
<ApplicationLogo className="w-8 h-8 rounded-lg object-contain group-hover:scale-110 transition-transform" />
|
||||||
<span className="font-extrabold text-primary-main text-lg tracking-tight">{branding?.short_name || '小小冰室'} ERP</span>
|
<span className="font-extrabold text-primary-main text-lg tracking-tight">{branding?.short_name || 'Star'} ERP</span>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{isCollapsed && (
|
{isCollapsed && (
|
||||||
@@ -559,7 +559,7 @@ export default function AuthenticatedLayout({
|
|||||||
<div className="h-16 flex items-center justify-between px-6 border-b border-slate-100">
|
<div className="h-16 flex items-center justify-between px-6 border-b border-slate-100">
|
||||||
<Link href="/" className="flex items-center gap-2">
|
<Link href="/" className="flex items-center gap-2">
|
||||||
<ApplicationLogo className="w-8 h-8 rounded-lg object-contain" />
|
<ApplicationLogo className="w-8 h-8 rounded-lg object-contain" />
|
||||||
<span className="font-extrabold text-primary-main text-lg">{branding?.short_name || '小小冰室'} ERP</span>
|
<span className="font-extrabold text-primary-main text-lg">{branding?.short_name || 'Star'} ERP</span>
|
||||||
</Link>
|
</Link>
|
||||||
<button onClick={() => setIsMobileOpen(false)} className="p-2 text-slate-400">
|
<button onClick={() => setIsMobileOpen(false)} className="p-2 text-slate-400">
|
||||||
<X className="h-5 w-5" />
|
<X className="h-5 w-5" />
|
||||||
@@ -588,7 +588,7 @@ export default function AuthenticatedLayout({
|
|||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
<footer className="mt-auto py-6 text-center text-sm text-slate-400">
|
<footer className="mt-auto py-6 text-center text-sm text-slate-400">
|
||||||
Copyright © {new Date().getFullYear()} {branding?.name || '小小冰室'}. All rights reserved. Design by 星科技
|
Copyright © {new Date().getFullYear()} {branding?.name || branding?.short_name || 'Star ERP'}. All rights reserved. Design by 星科技
|
||||||
</footer>
|
</footer>
|
||||||
<Toaster richColors closeButton position="top-center" />
|
<Toaster richColors closeButton position="top-center" />
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export default function Login() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 relative overflow-hidden">
|
<div className="min-h-screen flex items-center justify-center bg-gray-50 relative overflow-hidden">
|
||||||
<Head title="登入">
|
<Head title={`登入 - ${props.branding?.short_name || 'Star ERP'}`}>
|
||||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ export default function Login() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-center text-gray-400 text-sm mt-8">
|
<p className="text-center text-gray-400 text-sm mt-8">
|
||||||
© {new Date().getFullYear()} {props.branding?.name || '小小冰室'}. All rights reserved.
|
© {new Date().getFullYear()} {props.branding?.name || props.branding?.short_name || 'Star ERP'}. All rights reserved.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
|
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
|
||||||
import { Link, Head } from '@inertiajs/react';
|
import { Link, Head, usePage } from '@inertiajs/react';
|
||||||
|
import { PageProps } from '@/types/global';
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import {
|
import {
|
||||||
Package,
|
Package,
|
||||||
@@ -27,6 +28,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Dashboard({ stats }: Props) {
|
export default function Dashboard({ stats }: Props) {
|
||||||
|
const { branding } = usePage<PageProps>().props;
|
||||||
const cardData = [
|
const cardData = [
|
||||||
{
|
{
|
||||||
label: '商品總數',
|
label: '商品總數',
|
||||||
@@ -75,7 +77,7 @@ export default function Dashboard({ stats }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthenticatedLayout>
|
<AuthenticatedLayout>
|
||||||
<Head title="控制台 - 小小冰室 ERP" />
|
<Head title={`控制台 - ${branding?.short_name || 'Star'} ERP`} />
|
||||||
|
|
||||||
<div className="p-8 max-w-7xl mx-auto">
|
<div className="p-8 max-w-7xl mx-auto">
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
@@ -83,7 +85,7 @@ export default function Dashboard({ stats }: Props) {
|
|||||||
<TrendingUp className="h-6 w-6 text-primary-main" />
|
<TrendingUp className="h-6 w-6 text-primary-main" />
|
||||||
系統總覽
|
系統總覽
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-gray-500 mt-1">歡迎回來,這是您的小小冰室 ERP 營運數據概況。</p>
|
<p className="text-gray-500 mt-1">歡迎回來,這是您的 {branding?.short_name || 'Star'} ERP 營運數據概況。</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 主要數據卡片 */}
|
{/* 主要數據卡片 */}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import ProductDialog from "@/Components/Product/ProductDialog";
|
|||||||
import CategoryManagerDialog from "@/Components/Category/CategoryManagerDialog";
|
import CategoryManagerDialog from "@/Components/Category/CategoryManagerDialog";
|
||||||
import UnitManagerDialog, { Unit } from "@/Components/Unit/UnitManagerDialog";
|
import UnitManagerDialog, { Unit } from "@/Components/Unit/UnitManagerDialog";
|
||||||
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
|
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
|
||||||
import { Head, router } from "@inertiajs/react";
|
import { Head, router, usePage } from "@inertiajs/react";
|
||||||
|
import { PageProps as GlobalPageProps } from "@/types/global";
|
||||||
import { debounce } from "lodash";
|
import { debounce } from "lodash";
|
||||||
import Pagination from "@/Components/shared/Pagination";
|
import Pagination from "@/Components/shared/Pagination";
|
||||||
import { getBreadcrumbs } from "@/utils/breadcrumb";
|
import { getBreadcrumbs } from "@/utils/breadcrumb";
|
||||||
@@ -57,6 +58,7 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ProductManagement({ products, categories, units, filters }: PageProps) {
|
export default function ProductManagement({ products, categories, units, filters }: PageProps) {
|
||||||
|
const { branding } = usePage<GlobalPageProps>().props;
|
||||||
const [searchTerm, setSearchTerm] = useState(filters.search || "");
|
const [searchTerm, setSearchTerm] = useState(filters.search || "");
|
||||||
const [typeFilter, setTypeFilter] = useState<string>(filters.category_id || "all");
|
const [typeFilter, setTypeFilter] = useState<string>(filters.category_id || "all");
|
||||||
const [perPage, setPerPage] = useState<string>(filters.per_page || "10");
|
const [perPage, setPerPage] = useState<string>(filters.per_page || "10");
|
||||||
@@ -182,7 +184,7 @@ export default function ProductManagement({ products, categories, units, filters
|
|||||||
<Package className="h-6 w-6 text-primary-main" />
|
<Package className="h-6 w-6 text-primary-main" />
|
||||||
商品資料管理
|
商品資料管理
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-gray-500 mt-1">管理小小冰室原物料與成品資料</p>
|
<p className="text-gray-500 mt-1">管理 {branding?.short_name || 'Star'} 原物料與成品資料</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Toolbar */}
|
{/* Toolbar */}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export default function WarehouseIndex({ warehouses, totals, filters }: PageProp
|
|||||||
key={warehouse.id}
|
key={warehouse.id}
|
||||||
warehouse={warehouse}
|
warehouse={warehouse}
|
||||||
stats={{
|
stats={{
|
||||||
totalQuantity: warehouse.total_quantity || 0,
|
totalQuantity: warehouse.book_stock || 0,
|
||||||
lowStockCount: warehouse.low_stock_count || 0,
|
lowStockCount: warehouse.low_stock_count || 0,
|
||||||
replenishmentNeeded: warehouse.low_stock_count || 0
|
replenishmentNeeded: warehouse.low_stock_count || 0
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title inertia>{{ config('app.name', 'Laravel') }}</title>
|
<title inertia>{{ $appName ?? config('app.name', 'Star ERP') }}</title>
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link rel="icon" type="image/png" href="{{ $branding['logo_url'] ?? '/favicon.png' }}">
|
<link rel="icon" type="image/png" href="{{ $branding['logo_url'] ?? '/favicon.png' }}">
|
||||||
|
|||||||
Reference in New Issue
Block a user