Andrew Wallo 5 месяцев назад
Родитель
Сommit
1956d4a9c3

+ 17
- 9
app/DTO/DocumentDTO.php Просмотреть файл

@@ -2,6 +2,7 @@
2 2
 
3 3
 namespace App\DTO;
4 4
 
5
+use App\Enums\Accounting\DocumentType;
5 6
 use App\Enums\Setting\Font;
6 7
 use App\Models\Accounting\Document;
7 8
 use App\Models\Setting\DocumentDefault;
@@ -30,7 +31,7 @@ readonly class DocumentDTO
30 31
         public ?string $discount,
31 32
         public ?string $tax,
32 33
         public string $total,
33
-        public string $amountDue,
34
+        public ?string $amountDue,
34 35
         public CompanyDTO $company,
35 36
         public ClientDTO $client,
36 37
         public iterable $lineItems,
@@ -50,14 +51,21 @@ readonly class DocumentDTO
50 51
 
51 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 70
         return new self(
63 71
             header: $document->header,
@@ -74,7 +82,7 @@ readonly class DocumentDTO
74 82
             discount: $discount,
75 83
             tax: $tax,
76 84
             total: self::formatToMoney($document->total, $currencyCode),
77
-            amountDue: self::formatToMoney($document->amountDue(), $currencyCode),
85
+            amountDue: $amountDue,
78 86
             company: CompanyDTO::fromModel($document->company),
79 87
             client: ClientDTO::fromModel($document->client),
80 88
             lineItems: $document->lineItems->map(fn ($item) => LineItemDTO::fromModel($item)),

+ 1
- 1
app/DTO/DocumentLabelDTO.php Просмотреть файл

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

+ 6
- 1
app/DTO/DocumentPreviewDTO.php Просмотреть файл

@@ -2,6 +2,7 @@
2 2
 
3 3
 namespace App\DTO;
4 4
 
5
+use App\Enums\Accounting\DocumentType;
5 6
 use App\Enums\Setting\Font;
6 7
 use App\Enums\Setting\PaymentTerms;
7 8
 use App\Models\Setting\DocumentDefault;
@@ -15,6 +16,10 @@ readonly class DocumentPreviewDTO extends DocumentDTO
15 16
 
16 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 23
         return new self(
19 24
             header: $data['header'] ?? $settings->header ?? 'Invoice',
20 25
             subheader: $data['subheader'] ?? $settings->subheader,
@@ -30,7 +35,7 @@ readonly class DocumentPreviewDTO extends DocumentDTO
30 35
             discount: self::formatToMoney('100', null),
31 36
             tax: self::formatToMoney('50', null),
32 37
             total: self::formatToMoney('950', null),
33
-            amountDue: self::formatToMoney('950', null),
38
+            amountDue: $amountDue,
34 39
             company: CompanyDTO::fromModel($company),
35 40
             client: ClientPreviewDTO::fake(),
36 41
             lineItems: LineItemPreviewDTO::fakeItems(),

+ 1
- 1
app/Enums/Accounting/DocumentType.php Просмотреть файл

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

+ 27
- 5
app/View/Models/DocumentTotalViewModel.php Просмотреть файл

@@ -36,14 +36,36 @@ class DocumentTotalViewModel
36 36
 
37 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 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 66
             'currencyCode' => $currencyCode,
46 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,7 +128,7 @@
128 128
                         </tr>
129 129
                     @endif
130 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 132
                         <td class="text-right border-t py-2">{{ $document->total }}</td>
133 133
                     </tr>
134 134
                     @if($document->amountDue)

+ 1
- 1
resources/views/filament/company/components/document-templates/default.blade.php Просмотреть файл

@@ -115,7 +115,7 @@
115 115
             @endif
116 116
             <tr>
117 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 119
                 <td class="text-right border-t pr-6 py-2">{{ $document->total }}</td>
120 120
             </tr>
121 121
             @if($document->amountDue)

+ 1
- 1
resources/views/filament/company/components/document-templates/modern.blade.php Просмотреть файл

@@ -117,7 +117,7 @@
117 117
             @endif
118 118
             <tr>
119 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 121
                 <td class="text-right border-t pr-6 py-2">{{ $document->total }}</td>
122 122
             </tr>
123 123
             @if($document->amountDue)

+ 58
- 46
resources/views/filament/forms/components/document-totals.blade.php Просмотреть файл

@@ -7,9 +7,6 @@
7 7
     $type = $getType();
8 8
     $viewModel = new DocumentTotalViewModel($data, $type);
9 9
     extract($viewModel->buildViewData(), EXTR_SKIP);
10
-
11
-    $discountMethod = DocumentDiscountMethod::parse($data['discount_method']);
12
-    $isPerDocumentDiscount = $discountMethod->isPerDocument();
13 10
 @endphp
14 11
 
15 12
 <div class="totals-summary w-full lg:pl-[4rem] lg:pr-[6rem] py-8 lg:py-0">
@@ -23,66 +20,78 @@
23 20
             <col class="w-[10%]"> {{-- Amount --}}
24 21
         </colgroup>
25 22
         <tbody>
23
+        @if($subtotal)
26 24
             <tr>
27 25
                 <td colspan="4"></td>
28 26
                 <td class="text-sm p-2 font-semibold text-gray-950 dark:text-white">Subtotal:</td>
29 27
                 <td class="text-sm p-2">{{ $subtotal }}</td>
30 28
             </tr>
29
+        @endif
30
+        @if($taxTotal)
31 31
             <tr>
32 32
                 <td colspan="4"></td>
33 33
                 <td class="text-sm p-2">Tax:</td>
34 34
                 <td class="text-sm p-2">{{ $taxTotal }}</td>
35 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 50
             <tr>
56 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 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 62
             <tr>
61 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 67
                 <td class="text-sm p-2 border-t-4 border-double">{{ $amountDue }}</td>
64 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 77
         </tbody>
73 78
     </table>
74 79
 
75 80
     <!-- Mobile View -->
76 81
     <div class="block lg:hidden">
77 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 95
             @if($isPerDocumentDiscount)
87 96
                 <div class="flex flex-col space-y-2">
88 97
                     <span class="text-sm">Discount:</span>
@@ -92,20 +101,23 @@
92 101
                         @endforeach
93 102
                     </div>
94 103
                 </div>
95
-            @else
104
+            @elseif($discountTotal)
96 105
                 <div class="flex justify-between items-center">
97 106
                     <span class="text-sm">Discount:</span>
98 107
                     <span class="text-sm">({{ $discountTotal }})</span>
99 108
                 </div>
100 109
             @endif
101 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 112
                 <span class="text-sm">{{ $grandTotal }}</span>
104 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 121
             @if($conversionMessage)
110 122
                 <div class="text-sm text-gray-600">
111 123
                     {{ $conversionMessage }}

Загрузка…
Отмена
Сохранить