[PROMOTE] dev → demo:發票列印限縮統編 + 銷售中心 RWD 調整
1. [FIX] 電子發票列印限縮為僅統編發票,避免載具/捐贈列印失敗(69a1d02) - printInvoice() 守衛與前端列印鈕改用 metadata['business_tax_id'] 判定。 - 非統編發票顯示「此發票無可列印紙本」。 - 新增兩組三語系 key。 2. [STYLE] 銷售中心與 admin header 手機版響應式調整(840052d) - 三個 Tab 容器圓角/內距行動優先、搜尋欄手機滿版。 - admin layout 防水平溢出與行動版 header 間距調整。 備註:本次無 migration 變更。
This commit is contained in:
commit
1ec149a624
@ -1155,9 +1155,10 @@ class SalesController extends Controller
|
||||
if ($invoice->status !== Invoice::STATUS_ISSUED || empty($invoice->invoice_no)) {
|
||||
return back()->with('error', __('Only issued invoices can be printed'));
|
||||
}
|
||||
// 捐贈發票依法無紙本、不可列印(綠界 InvoicePrint 會回查無資料)
|
||||
if (!empty($invoice->love_code)) {
|
||||
return back()->with('error', __('Donation invoices cannot be printed'));
|
||||
// 僅「統編發票」可列印:本系統開立時 Print=1 僅給帶統編者(見 EcpayInvoiceService::issue 的 Print 規則);
|
||||
// 捐贈、載具、一般無統編 B2C 皆以 Print=0 開立,綠界 InvoicePrint 會回查無資料而失敗。
|
||||
if (empty($invoice->metadata['business_tax_id'] ?? '')) {
|
||||
return back()->with('error', __('Only invoices with a tax ID can be printed'));
|
||||
}
|
||||
$machine = $invoice->machine;
|
||||
if (!$machine || !$ecpay->configForMachine($machine)) {
|
||||
|
||||
@ -1392,6 +1392,7 @@
|
||||
"Online Status": "Online Status",
|
||||
"Only .xlsx files are supported (Max 5MB)": "Only .xlsx files are supported (Max 5MB)",
|
||||
"Only .xlsx, .xls, .csv files are supported (Max 5MB)": "Only .xlsx, .xls, .csv files are supported (Max 5MB)",
|
||||
"Only invoices with a tax ID can be printed": "Only invoices with a tax ID can be printed",
|
||||
"Only issued invoices can be printed": "Only issued invoices can be printed",
|
||||
"Only issued invoices can be voided": "Only issued invoices can be voided",
|
||||
"Only machines under the same company can be cloned for security.": "Only machines under the same company can be cloned for security.",
|
||||
@ -2113,6 +2114,7 @@
|
||||
"This Month": "This Month",
|
||||
"This Week": "This Week",
|
||||
"This account does not belong to this company.": "This account does not belong to this company.",
|
||||
"This invoice has no printable copy": "This invoice has no printable copy",
|
||||
"This is a system administrator role. Its name is locked to ensure system stability.": "This is a system administrator role. Its name is locked to ensure system stability.",
|
||||
"This machine has a pending command. Please wait.": "This machine has a pending command. Please wait.",
|
||||
"This machine has no ECPay invoice settings": "This machine has no ECPay invoice settings",
|
||||
|
||||
@ -1392,6 +1392,7 @@
|
||||
"Online Status": "オンラインステータス",
|
||||
"Only .xlsx files are supported (Max 5MB)": "Only .xlsx files are supported (Max 5MB)",
|
||||
"Only .xlsx, .xls, .csv files are supported (Max 5MB)": ".xlsx, .xls, .csv ファイルのみサポートされています (最大 5MB)",
|
||||
"Only invoices with a tax ID can be printed": "統一番号付き請求書のみ印刷できます",
|
||||
"Only issued invoices can be printed": "発行済みの領収書のみ印刷できます",
|
||||
"Only issued invoices can be voided": "Only issued invoices can be voided",
|
||||
"Only machines under the same company can be cloned for security.": "セキュリティのため、同じ会社の機器設定のみコピーできます。",
|
||||
@ -2113,6 +2114,7 @@
|
||||
"This Month": "今月",
|
||||
"This Week": "今週",
|
||||
"This account does not belong to this company.": "このアカウントは該当企業に所属していません。",
|
||||
"This invoice has no printable copy": "この請求書は印刷可能な紙面がありません",
|
||||
"This is a system administrator role. Its name is locked to ensure system stability.": "これはシステム管理者ロールです。システムの安定性を確保するため、名前はロックされています。",
|
||||
"This machine has a pending command. Please wait.": "この機器には実行中のコマンドがあります。しばらくお待ちください。",
|
||||
"This machine has no ECPay invoice settings": "This machine has no ECPay invoice settings",
|
||||
|
||||
@ -1392,6 +1392,7 @@
|
||||
"Online Status": "在線狀態",
|
||||
"Only .xlsx files are supported (Max 5MB)": "僅支援 .xlsx 檔案 (最大 5MB)",
|
||||
"Only .xlsx, .xls, .csv files are supported (Max 5MB)": "僅支援 .xlsx, .xls, .csv 檔案 (最大 5MB)",
|
||||
"Only invoices with a tax ID can be printed": "僅統編發票可列印",
|
||||
"Only issued invoices can be printed": "僅已開立的發票可列印",
|
||||
"Only issued invoices can be voided": "僅已開立的發票可作廢",
|
||||
"Only machines under the same company can be cloned for security.": "基於安全性,僅限複製同公司旗下的機台設定。",
|
||||
@ -2113,6 +2114,7 @@
|
||||
"This Month": "本月",
|
||||
"This Week": "本週",
|
||||
"This account does not belong to this company.": "此帳號不屬於該公司。",
|
||||
"This invoice has no printable copy": "此發票無可列印紙本",
|
||||
"This is a system administrator role. Its name is locked to ensure system stability.": "這是系統管理員角色,名稱已鎖定以確保系統穩定性。",
|
||||
"This machine has a pending command. Please wait.": "此機台已有指令正在執行,請稍後。",
|
||||
"This machine has no ECPay invoice settings": "此機台未設定綠界電子發票",
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<div x-show="activeTab === 'orders'" class="relative"
|
||||
x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0">
|
||||
<div class="luxury-card rounded-3xl p-8 relative overflow-hidden">
|
||||
<div class="luxury-card rounded-2xl sm:rounded-3xl p-4 sm:p-6 lg:p-8 relative overflow-hidden">
|
||||
<x-luxury-spinner show="tabLoading === 'orders'" />
|
||||
<div id="tab-orders-container" :class="{ 'opacity-30 pointer-events-none transition-opacity duration-300': tabLoading === 'orders' }">
|
||||
@include('admin.sales.partials.tab-orders')
|
||||
@ -33,7 +33,7 @@
|
||||
<div x-show="activeTab === 'invoices'" class="relative"
|
||||
x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0" x-cloak>
|
||||
<div class="luxury-card rounded-3xl p-8 relative overflow-hidden">
|
||||
<div class="luxury-card rounded-2xl sm:rounded-3xl p-4 sm:p-6 lg:p-8 relative overflow-hidden">
|
||||
<x-luxury-spinner show="tabLoading === 'invoices'" />
|
||||
<div id="tab-invoices-container" :class="{ 'opacity-30 pointer-events-none transition-opacity duration-300': tabLoading === 'invoices' }">
|
||||
@include('admin.sales.partials.tab-invoices')
|
||||
@ -45,7 +45,7 @@
|
||||
<div x-show="activeTab === 'dispense'" class="relative"
|
||||
x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4"
|
||||
x-transition:enter-end="opacity-100 translate-y-0" x-cloak>
|
||||
<div class="luxury-card rounded-3xl p-8 relative overflow-hidden">
|
||||
<div class="luxury-card rounded-2xl sm:rounded-3xl p-4 sm:p-6 lg:p-8 relative overflow-hidden">
|
||||
<x-luxury-spinner show="tabLoading === 'dispense'" />
|
||||
<div id="tab-dispense-container" :class="{ 'opacity-30 pointer-events-none transition-opacity duration-300': tabLoading === 'dispense' }">
|
||||
@include('admin.sales.partials.tab-dispense')
|
||||
|
||||
@ -342,8 +342,9 @@
|
||||
'void' => ['label' => __('Void'), 'color' => 'slate'],
|
||||
];
|
||||
$invBadge = $invStatusMap[$invStatus] ?? ['label' => $invStatus, 'color' => 'slate'];
|
||||
// 捐贈發票依法無紙本、不可列印(綠界 InvoicePrint 會回查無資料)
|
||||
$invPrintable = empty($order->invoice->love_code);
|
||||
// 僅「統編發票」可列印:本系統開立時 Print=1 僅給帶統編者;
|
||||
// 捐贈、載具、一般無統編 B2C 皆為 Print=0,綠界 InvoicePrint 會回查無資料而失敗。
|
||||
$invPrintable = !empty($order->invoice->metadata['business_tax_id'] ?? '');
|
||||
@endphp
|
||||
<div class="relative flex flex-col sm:flex-row sm:items-center justify-between gap-6">
|
||||
<div class="space-y-3">
|
||||
@ -361,7 +362,7 @@
|
||||
|
||||
@if($invStatus === 'issued')
|
||||
<div class="flex items-center gap-3">
|
||||
{{-- 列印(捐贈發票無紙本,僅非捐贈可列印) --}}
|
||||
{{-- 列印:僅統編發票可列印(載具/捐贈/一般無統編 B2C 為 Print=0,綠界查無資料) --}}
|
||||
@if($invPrintable)
|
||||
<form method="POST" action="{{ route('admin.sales.invoices.print', $order->invoice) }}" target="_blank">
|
||||
@csrf
|
||||
@ -370,7 +371,7 @@
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<span class="text-[11px] font-bold text-slate-400 dark:text-slate-500 px-2">{{ __('Donation invoices cannot be printed') }}</span>
|
||||
<span class="text-[11px] font-bold text-slate-400 dark:text-slate-500 px-2">{{ __('This invoice has no printable copy') }}</span>
|
||||
@endif
|
||||
{{-- 作廢:僅平台系統管理員可見可用(後端亦有 403 守衛)。使用自製確認框 UI --}}
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<input type="hidden" name="tab" value="dispense">
|
||||
|
||||
<div class="relative group flex-1 min-w-[280px]">
|
||||
<div class="relative group flex-1 w-full min-w-0 lg:min-w-[280px]">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10">
|
||||
<svg class="w-4 h-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors stroke-[2.5]"
|
||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<input type="hidden" name="tab" value="invoices">
|
||||
|
||||
<div class="relative group flex-1 min-w-[280px]">
|
||||
<div class="relative group flex-1 w-full min-w-0 lg:min-w-[280px]">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10">
|
||||
<svg class="w-4 h-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors stroke-[2.5]"
|
||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<input type="hidden" name="tab" value="orders">
|
||||
|
||||
<div class="relative group flex-1 min-w-[280px]">
|
||||
<div class="relative group flex-1 w-full min-w-0 lg:min-w-[280px]">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10">
|
||||
<svg class="w-4 h-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors stroke-[2.5]"
|
||||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
</head>
|
||||
|
||||
<body
|
||||
class="bg-gray-50 dark:bg-[#0f172a] antialiased font-sans h-full selection:bg-indigo-100 dark:selection:bg-indigo-900/40"
|
||||
class="bg-gray-50 dark:bg-[#0f172a] antialiased font-sans h-full overflow-x-clip selection:bg-indigo-100 dark:selection:bg-indigo-900/40"
|
||||
x-data="{
|
||||
sidebarOpen: false,
|
||||
sidebarCollapsed: localStorage.getItem('sidebarCollapsed') === 'true',
|
||||
@ -128,18 +128,18 @@
|
||||
<header
|
||||
class="sticky top-0 inset-x-0 flex flex-wrap sm:justify-start sm:flex-nowrap z-[48] w-full bg-white/80 backdrop-blur-md border-b border-slate-200/50 text-sm py-2.5 sm:py-4 lg:pl-[var(--admin-sidebar-offset)] dark:bg-[#0f172a]/80 dark:border-slate-800/50 shadow-sm transition-all duration-300">
|
||||
<nav class="flex basis-full items-center w-full mx-auto pl-4 lg:pl-0 pr-4 sm:pr-6 md:pr-8" aria-label="Global">
|
||||
<div class="mr-5 lg:mr-0 lg:hidden text-center">
|
||||
<div class="mr-2 lg:mr-0 lg:hidden text-center shrink-0">
|
||||
<a class="flex items-center gap-x-2 flex-none text-xl font-bold dark:text-white font-display tracking-tight"
|
||||
href="{{ route('admin.dashboard') }}" aria-label="Brand">
|
||||
<img src="{{ auth()->user()->company && auth()->user()->company->hasCustomBrandingEnabled() && auth()->user()->company->logo_url ? auth()->user()->company->logo_url : asset('starcloud_icon.png') }}"
|
||||
alt="{{ auth()->user()->company ? auth()->user()->company->name : config('app.name') }} Logo"
|
||||
class="w-7 h-7 max-h-7 max-w-[28px] object-contain shrink-0">
|
||||
<span>Star<span class="text-cyan-500">Cloud</span></span>
|
||||
<span class="hidden min-[400px]:inline">Star<span class="text-cyan-500">Cloud</span></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Auto Refresh -->
|
||||
<div class="relative inline-flex ml-4 sm:ml-10 lg:ml-0" x-data="{
|
||||
<div class="relative inline-flex shrink-0 ml-2 sm:ml-10 lg:ml-0" x-data="{
|
||||
refreshOpen: false,
|
||||
interval: localStorage.getItem('autoRefreshInterval') || 'Off',
|
||||
timeLeft: 0,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user