Andrew Wallo 5 月之前
父節點
當前提交
1956d4a9c3

+ 17
- 9
app/DTO/DocumentDTO.php 查看文件

2
 
2
 
3
 namespace App\DTO;
3
 namespace App\DTO;
4
 
4
 
5
+use App\Enums\Accounting\DocumentType;
5
 use App\Enums\Setting\Font;
6
 use App\Enums\Setting\Font;
6
 use App\Models\Accounting\Document;
7
 use App\Models\Accounting\Document;
7
 use App\Models\Setting\DocumentDefault;
8
 use App\Models\Setting\DocumentDefault;
30
         public ?string $discount,
31
         public ?string $discount,
31
         public ?string $tax,
32
         public ?string $tax,
32
         public string $total,
33
         public string $total,
33
-        public string $amountDue,
34
+        public ?string $amountDue,
34
         public CompanyDTO $company,
35
         public CompanyDTO $company,
35
         public ClientDTO $client,
36
         public ClientDTO $client,
36
         public iterable $lineItems,
37
         public iterable $lineItems,
50
 
51
 
51
         $currencyCode = $document->currency_code ?? CurrencyAccessor::getDefaultCurrency();
52
         $currencyCode = $document->currency_code ?? CurrencyAccessor::getDefaultCurrency();
52
 
53
 
53
-        $discount = $document->discount_total > 0 ? self::formatToMoney($document->discount_total, $currencyCode) : null;
54
-        $tax = $document->tax_total > 0 ? self::formatToMoney($document->tax_total, $currencyCode) : null;
54
+        $discount = $document->discount_total > 0
55
+            ? self::formatToMoney($document->discount_total, $currencyCode)
56
+            : null;
55
 
57
 
56
-        if (! $discount && ! $tax) {
57
-            $subtotal = null;
58
-        } else {
59
-            $subtotal = self::formatToMoney($document->subtotal, $currencyCode);
60
-        }
58
+        $tax = $document->tax_total > 0
59
+            ? self::formatToMoney($document->tax_total, $currencyCode)
60
+            : null;
61
+
62
+        $subtotal = ($discount || $tax)
63
+            ? self::formatToMoney($document->subtotal, $currencyCode)
64
+            : null;
65
+
66
+        $amountDue = $document::documentType() !== DocumentType::Estimate ?
67
+            self::formatToMoney($document->amountDue(), $currencyCode) :
68
+            null;
61
 
69
 
62
         return new self(
70
         return new self(
63
             header: $document->header,
71
             header: $document->header,
74
             discount: $discount,
82
             discount: $discount,
75
             tax: $tax,
83
             tax: $tax,
76
             total: self::formatToMoney($document->total, $currencyCode),
84
             total: self::formatToMoney($document->total, $currencyCode),
77
-            amountDue: self::formatToMoney($document->amountDue(), $currencyCode),
85
+            amountDue: $amountDue,
78
             company: CompanyDTO::fromModel($document->company),
86
             company: CompanyDTO::fromModel($document->company),
79
             client: ClientDTO::fromModel($document->client),
87
             client: ClientDTO::fromModel($document->client),
80
             lineItems: $document->lineItems->map(fn ($item) => LineItemDTO::fromModel($item)),
88
             lineItems: $document->lineItems->map(fn ($item) => LineItemDTO::fromModel($item)),

+ 1
- 1
app/DTO/DocumentLabelDTO.php 查看文件

10
         public string $referenceNumber,
10
         public string $referenceNumber,
11
         public string $date,
11
         public string $date,
12
         public string $dueDate,
12
         public string $dueDate,
13
-        public string $amountDue,
13
+        public ?string $amountDue,
14
     ) {}
14
     ) {}
15
 
15
 
16
     public function toArray(): array
16
     public function toArray(): array

+ 6
- 1
app/DTO/DocumentPreviewDTO.php 查看文件

2
 
2
 
3
 namespace App\DTO;
3
 namespace App\DTO;
4
 
4
 
5
+use App\Enums\Accounting\DocumentType;
5
 use App\Enums\Setting\Font;
6
 use App\Enums\Setting\Font;
6
 use App\Enums\Setting\PaymentTerms;
7
 use App\Enums\Setting\PaymentTerms;
7
 use App\Models\Setting\DocumentDefault;
8
 use App\Models\Setting\DocumentDefault;
15
 
16
 
16
         $paymentTerms = PaymentTerms::parse($data['payment_terms']) ?? $settings->payment_terms;
17
         $paymentTerms = PaymentTerms::parse($data['payment_terms']) ?? $settings->payment_terms;
17
 
18
 
19
+        $amountDue = $settings->type !== DocumentType::Estimate ?
20
+            self::formatToMoney('950', null) :
21
+            null;
22
+
18
         return new self(
23
         return new self(
19
             header: $data['header'] ?? $settings->header ?? 'Invoice',
24
             header: $data['header'] ?? $settings->header ?? 'Invoice',
20
             subheader: $data['subheader'] ?? $settings->subheader,
25
             subheader: $data['subheader'] ?? $settings->subheader,
30
             discount: self::formatToMoney('100', null),
35
             discount: self::formatToMoney('100', null),
31
             tax: self::formatToMoney('50', null),
36
             tax: self::formatToMoney('50', null),
32
             total: self::formatToMoney('950', null),
37
             total: self::formatToMoney('950', null),
33
-            amountDue: self::formatToMoney('950', null),
38
+            amountDue: $amountDue,
34
             company: CompanyDTO::fromModel($company),
39
             company: CompanyDTO::fromModel($company),
35
             client: ClientPreviewDTO::fake(),
40
             client: ClientPreviewDTO::fake(),
36
             lineItems: LineItemPreviewDTO::fakeItems(),
41
             lineItems: LineItemPreviewDTO::fakeItems(),

+ 1
- 1
app/Enums/Accounting/DocumentType.php 查看文件

79
                 referenceNumber: 'Reference Number',
79
                 referenceNumber: 'Reference Number',
80
                 date: 'Estimate Date',
80
                 date: 'Estimate Date',
81
                 dueDate: 'Expiration Date',
81
                 dueDate: 'Expiration Date',
82
-                amountDue: 'Grand Total',
82
+                amountDue: null,
83
             ),
83
             ),
84
             self::Bill => new DocumentLabelDTO(
84
             self::Bill => new DocumentLabelDTO(
85
                 title: self::Bill->getLabel(),
85
                 title: self::Bill->getLabel(),

+ 27
- 5
app/View/Models/DocumentTotalViewModel.php 查看文件

36
 
36
 
37
         $conversionMessage = $this->buildConversionMessage($grandTotalInCents, $currencyCode, $defaultCurrencyCode);
37
         $conversionMessage = $this->buildConversionMessage($grandTotalInCents, $currencyCode, $defaultCurrencyCode);
38
 
38
 
39
+        $discountMethod = DocumentDiscountMethod::parse($this->data['discount_method']);
40
+        $isPerDocumentDiscount = $discountMethod->isPerDocument();
41
+
42
+        $taxTotal = $taxTotalInCents > 0
43
+            ? CurrencyConverter::formatCentsToMoney($taxTotalInCents, $currencyCode)
44
+            : null;
45
+
46
+        $discountTotal = ($isPerDocumentDiscount || $discountTotalInCents > 0)
47
+            ? CurrencyConverter::formatCentsToMoney($discountTotalInCents, $currencyCode)
48
+            : null;
49
+
50
+        $subtotal = ($taxTotal || $discountTotal)
51
+            ? CurrencyConverter::formatCentsToMoney($subtotalInCents, $currencyCode)
52
+            : null;
53
+
54
+        $grandTotal = CurrencyConverter::formatCentsToMoney($grandTotalInCents, $currencyCode);
55
+
56
+        $amountDue = $this->documentType !== DocumentType::Estimate
57
+            ? CurrencyConverter::formatCentsToMoney($amountDueInCents, $currencyCode)
58
+            : null;
59
+
39
         return [
60
         return [
40
-            'subtotal' => CurrencyConverter::formatCentsToMoney($subtotalInCents, $currencyCode),
41
-            'taxTotal' => CurrencyConverter::formatCentsToMoney($taxTotalInCents, $currencyCode),
42
-            'discountTotal' => CurrencyConverter::formatCentsToMoney($discountTotalInCents, $currencyCode),
43
-            'grandTotal' => CurrencyConverter::formatCentsToMoney($grandTotalInCents, $currencyCode),
44
-            'amountDue' => CurrencyConverter::formatCentsToMoney($amountDueInCents, $currencyCode),
61
+            'subtotal' => $subtotal,
62
+            'taxTotal' => $taxTotal,
63
+            'discountTotal' => $discountTotal,
64
+            'grandTotal' => $grandTotal,
65
+            'amountDue' => $amountDue,
45
             'currencyCode' => $currencyCode,
66
             'currencyCode' => $currencyCode,
46
             'conversionMessage' => $conversionMessage,
67
             'conversionMessage' => $conversionMessage,
68
+            'isPerDocumentDiscount' => $isPerDocumentDiscount,
47
         ];
69
         ];
48
     }
70
     }
49
 
71
 

+ 1
- 1
resources/views/filament/company/components/document-templates/classic.blade.php 查看文件

128
                         </tr>
128
                         </tr>
129
                     @endif
129
                     @endif
130
                     <tr>
130
                     <tr>
131
-                        <td class="text-right font-semibold border-t py-2">Total:</td>
131
+                        <td class="text-right font-semibold border-t py-2">{{ $document->amountDue ? 'Total' : 'Grand Total' }}:</td>
132
                         <td class="text-right border-t py-2">{{ $document->total }}</td>
132
                         <td class="text-right border-t py-2">{{ $document->total }}</td>
133
                     </tr>
133
                     </tr>
134
                     @if($document->amountDue)
134
                     @if($document->amountDue)

+ 1
- 1
resources/views/filament/company/components/document-templates/default.blade.php 查看文件

115
             @endif
115
             @endif
116
             <tr>
116
             <tr>
117
                 <td class="pl-6 py-2" colspan="2"></td>
117
                 <td class="pl-6 py-2" colspan="2"></td>
118
-                <td class="text-right font-semibold border-t py-2">Total:</td>
118
+                <td class="text-right font-semibold border-t py-2">{{ $document->amountDue ? 'Total' : 'Grand Total' }}:</td>
119
                 <td class="text-right border-t pr-6 py-2">{{ $document->total }}</td>
119
                 <td class="text-right border-t pr-6 py-2">{{ $document->total }}</td>
120
             </tr>
120
             </tr>
121
             @if($document->amountDue)
121
             @if($document->amountDue)

+ 1
- 1
resources/views/filament/company/components/document-templates/modern.blade.php 查看文件

117
             @endif
117
             @endif
118
             <tr>
118
             <tr>
119
                 <td class="pl-6 py-2" colspan="2"></td>
119
                 <td class="pl-6 py-2" colspan="2"></td>
120
-                <td class="text-right font-semibold border-t py-2">Total:</td>
120
+                <td class="text-right font-semibold border-t py-2">{{ $document->amountDue ? 'Total' : 'Grand Total' }}:</td>
121
                 <td class="text-right border-t pr-6 py-2">{{ $document->total }}</td>
121
                 <td class="text-right border-t pr-6 py-2">{{ $document->total }}</td>
122
             </tr>
122
             </tr>
123
             @if($document->amountDue)
123
             @if($document->amountDue)

+ 58
- 46
resources/views/filament/forms/components/document-totals.blade.php 查看文件

7
     $type = $getType();
7
     $type = $getType();
8
     $viewModel = new DocumentTotalViewModel($data, $type);
8
     $viewModel = new DocumentTotalViewModel($data, $type);
9
     extract($viewModel->buildViewData(), EXTR_SKIP);
9
     extract($viewModel->buildViewData(), EXTR_SKIP);
10
-
11
-    $discountMethod = DocumentDiscountMethod::parse($data['discount_method']);
12
-    $isPerDocumentDiscount = $discountMethod->isPerDocument();
13
 @endphp
10
 @endphp
14
 
11
 
15
 <div class="totals-summary w-full lg:pl-[4rem] lg:pr-[6rem] py-8 lg:py-0">
12
 <div class="totals-summary w-full lg:pl-[4rem] lg:pr-[6rem] py-8 lg:py-0">
23
             <col class="w-[10%]"> {{-- Amount --}}
20
             <col class="w-[10%]"> {{-- Amount --}}
24
         </colgroup>
21
         </colgroup>
25
         <tbody>
22
         <tbody>
23
+        @if($subtotal)
26
             <tr>
24
             <tr>
27
                 <td colspan="4"></td>
25
                 <td colspan="4"></td>
28
                 <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white">Subtotal:</td>
26
                 <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white">Subtotal:</td>
29
                 <td class="text-sm p-2">{{ $subtotal }}</td>
27
                 <td class="text-sm p-2">{{ $subtotal }}</td>
30
             </tr>
28
             </tr>
29
+        @endif
30
+        @if($taxTotal)
31
             <tr>
31
             <tr>
32
                 <td colspan="4"></td>
32
                 <td colspan="4"></td>
33
                 <td class="text-sm p-2">Tax:</td>
33
                 <td class="text-sm p-2">Tax:</td>
34
                 <td class="text-sm p-2">{{ $taxTotal }}</td>
34
                 <td class="text-sm p-2">{{ $taxTotal }}</td>
35
             </tr>
35
             </tr>
36
-            @if($isPerDocumentDiscount)
37
-                <tr>
38
-                    <td colspan="3" class="text-sm p-2">Discount:</td>
39
-                    <td colspan="2" class="text-sm p-2">
40
-                        <div class="flex justify-between space-x-2">
41
-                            @foreach($getChildComponentContainer()->getComponents() as $component)
42
-                                <div class="flex-1 text-left">{{ $component }}</div>
43
-                            @endforeach
44
-                        </div>
45
-                    </td>
46
-                    <td class="text-sm p-2">({{ $discountTotal }})</td>
47
-                </tr>
48
-            @else
49
-                <tr>
50
-                    <td colspan="4"></td>
51
-                    <td class="text-sm p-2">Discount:</td>
52
-                    <td class="text-sm p-2">({{ $discountTotal }})</td>
53
-                </tr>
54
-            @endif
36
+        @endif
37
+        @if($isPerDocumentDiscount)
38
+            <tr>
39
+                <td colspan="3" class="text-sm p-2">Discount:</td>
40
+                <td colspan="2" class="text-sm p-2">
41
+                    <div class="flex justify-between space-x-2">
42
+                        @foreach($getChildComponentContainer()->getComponents() as $component)
43
+                            <div class="flex-1 text-left">{{ $component }}</div>
44
+                        @endforeach
45
+                    </div>
46
+                </td>
47
+                <td class="text-sm p-2">({{ $discountTotal }})</td>
48
+            </tr>
49
+        @elseif($discountTotal)
55
             <tr>
50
             <tr>
56
                 <td colspan="4"></td>
51
                 <td colspan="4"></td>
57
-                <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white">Total:</td>
58
-                <td class="text-sm p-2">{{ $grandTotal }}</td>
52
+                <td class="text-sm p-2">Discount:</td>
53
+                <td class="text-sm p-2">({{ $discountTotal }})</td>
59
             </tr>
54
             </tr>
55
+        @endif
56
+        <tr>
57
+            <td colspan="4"></td>
58
+            <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white">{{ $amountDue ? 'Total' : 'Grand Total' }}:</td>
59
+            <td class="text-sm p-2">{{ $grandTotal }}</td>
60
+        </tr>
61
+        @if($amountDue)
60
             <tr>
62
             <tr>
61
                 <td colspan="4"></td>
63
                 <td colspan="4"></td>
62
-                <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white border-t-4 border-double">Amount Due ({{ $currencyCode }}):</td>
64
+                <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white border-t-4 border-double">Amount Due
65
+                    ({{ $currencyCode }}):
66
+                </td>
63
                 <td class="text-sm p-2 border-t-4 border-double">{{ $amountDue }}</td>
67
                 <td class="text-sm p-2 border-t-4 border-double">{{ $amountDue }}</td>
64
             </tr>
68
             </tr>
65
-            @if($conversionMessage)
66
-                <tr>
67
-                    <td colspan="6" class="text-sm p-2 text-gray-600">
68
-                        {{ $conversionMessage }}
69
-                    </td>
70
-                </tr>
71
-            @endif
69
+        @endif
70
+        @if($conversionMessage)
71
+            <tr>
72
+                <td colspan="6" class="text-sm p-2 text-gray-600">
73
+                    {{ $conversionMessage }}
74
+                </td>
75
+            </tr>
76
+        @endif
72
         </tbody>
77
         </tbody>
73
     </table>
78
     </table>
74
 
79
 
75
     <!-- Mobile View -->
80
     <!-- Mobile View -->
76
     <div class="block lg:hidden">
81
     <div class="block lg:hidden">
77
         <div class="flex flex-col space-y-6">
82
         <div class="flex flex-col space-y-6">
78
-            <div class="flex justify-between items-center">
79
-                <span class="text-sm font-semibold text-gray-950 dark:text-white">Subtotal:</span>
80
-                <span class="text-sm">{{ $subtotal }}</span>
81
-            </div>
82
-            <div class="flex justify-between items-center">
83
-                <span class="text-sm">Tax:</span>
84
-                <span class="text-sm">{{ $taxTotal }}</span>
85
-            </div>
83
+            @if($subtotal)
84
+                <div class="flex justify-between items-center">
85
+                    <span class="text-sm font-semibold text-gray-950 dark:text-white">Subtotal:</span>
86
+                    <span class="text-sm">{{ $subtotal }}</span>
87
+                </div>
88
+            @endif
89
+            @if($taxTotal)
90
+                <div class="flex justify-between items-center">
91
+                    <span class="text-sm">Tax:</span>
92
+                    <span class="text-sm">{{ $taxTotal }}</span>
93
+                </div>
94
+            @endif
86
             @if($isPerDocumentDiscount)
95
             @if($isPerDocumentDiscount)
87
                 <div class="flex flex-col space-y-2">
96
                 <div class="flex flex-col space-y-2">
88
                     <span class="text-sm">Discount:</span>
97
                     <span class="text-sm">Discount:</span>
92
                         @endforeach
101
                         @endforeach
93
                     </div>
102
                     </div>
94
                 </div>
103
                 </div>
95
-            @else
104
+            @elseif($discountTotal)
96
                 <div class="flex justify-between items-center">
105
                 <div class="flex justify-between items-center">
97
                     <span class="text-sm">Discount:</span>
106
                     <span class="text-sm">Discount:</span>
98
                     <span class="text-sm">({{ $discountTotal }})</span>
107
                     <span class="text-sm">({{ $discountTotal }})</span>
99
                 </div>
108
                 </div>
100
             @endif
109
             @endif
101
             <div class="flex justify-between items-center">
110
             <div class="flex justify-between items-center">
102
-                <span class="text-sm font-semibold text-gray-950 dark:text-white">Total:</span>
111
+                <span class="text-sm font-semibold text-gray-950 dark:text-white">{{ $amountDue ? 'Total' : 'Grand Total' }}:</span>
103
                 <span class="text-sm">{{ $grandTotal }}</span>
112
                 <span class="text-sm">{{ $grandTotal }}</span>
104
             </div>
113
             </div>
105
-            <div class="flex justify-between items-center">
106
-                <span class="text-sm font-semibold text-gray-950 dark:text-white">Amount Due ({{ $currencyCode }}):</span>
107
-                <span class="text-sm">{{ $amountDue }}</span>
108
-            </div>
114
+            @if($amountDue)
115
+                <div class="flex justify-between items-center">
116
+                    <span
117
+                        class="text-sm font-semibold text-gray-950 dark:text-white">Amount Due ({{ $currencyCode }}):</span>
118
+                    <span class="text-sm">{{ $amountDue }}</span>
119
+                </div>
120
+            @endif
109
             @if($conversionMessage)
121
             @if($conversionMessage)
110
                 <div class="text-sm text-gray-600">
122
                 <div class="text-sm text-gray-600">
111
                     {{ $conversionMessage }}
123
                     {{ $conversionMessage }}

Loading…
取消
儲存