cloud-ide-fees 0.0.30 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/cloud-ide-fees-fee-discount-form.component-R_yZNKM-.mjs +383 -0
- package/fesm2022/cloud-ide-fees-fee-discount-form.component-R_yZNKM-.mjs.map +1 -0
- package/fesm2022/cloud-ide-fees-fee-scholarship-form.component-C2eJrtQT.mjs +418 -0
- package/fesm2022/cloud-ide-fees-fee-scholarship-form.component-C2eJrtQT.mjs.map +1 -0
- package/fesm2022/cloud-ide-fees.mjs +1434 -762
- package/fesm2022/cloud-ide-fees.mjs.map +1 -1
- package/index.d.ts +201 -114
- package/package.json +1 -1
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, computed, effect, Component } from '@angular/core';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import * as i1 from '@angular/forms';
|
|
5
|
+
import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
6
|
+
import { CideInputComponent, CideSelectComponent, CideTextareaComponent, CideEleButtonComponent, CurrencyPipe } from 'cloud-ide-element';
|
|
7
|
+
|
|
8
|
+
class FeeDiscountFormComponent {
|
|
9
|
+
// Inputs
|
|
10
|
+
feeId = input.required(...(ngDevMode ? [{ debugName: "feeId" }] : []));
|
|
11
|
+
feeName = input.required(...(ngDevMode ? [{ debugName: "feeName" }] : []));
|
|
12
|
+
feeAmount = input.required(...(ngDevMode ? [{ debugName: "feeAmount" }] : []));
|
|
13
|
+
existingDiscount = input(null, ...(ngDevMode ? [{ debugName: "existingDiscount" }] : []));
|
|
14
|
+
discountReasonOptions = input.required(...(ngDevMode ? [{ debugName: "discountReasonOptions" }] : []));
|
|
15
|
+
// Outputs
|
|
16
|
+
saved = output();
|
|
17
|
+
cancelled = output();
|
|
18
|
+
// Form using signals (modern Angular approach)
|
|
19
|
+
discountForm = new FormGroup({
|
|
20
|
+
discount_type: new FormControl('FIXED_AMOUNT', [Validators.required]),
|
|
21
|
+
discount_value: new FormControl(0, [Validators.required, Validators.min(0)]),
|
|
22
|
+
discount_reason_id: new FormControl(''),
|
|
23
|
+
valid_from: new FormControl(''),
|
|
24
|
+
valid_to: new FormControl(''),
|
|
25
|
+
notes: new FormControl('')
|
|
26
|
+
});
|
|
27
|
+
// Computed values
|
|
28
|
+
maxDiscountValue = computed(() => {
|
|
29
|
+
const type = this.discountForm.get('discount_type')?.value;
|
|
30
|
+
return type === 'PERCENTAGE' ? 100 : this.feeAmount();
|
|
31
|
+
}, ...(ngDevMode ? [{ debugName: "maxDiscountValue" }] : []));
|
|
32
|
+
calculatedDiscountAmount = computed(() => {
|
|
33
|
+
const type = this.discountForm.get('discount_type')?.value;
|
|
34
|
+
const value = this.discountForm.get('discount_value')?.value || 0;
|
|
35
|
+
if (!type || value <= 0)
|
|
36
|
+
return 0;
|
|
37
|
+
if (type === 'PERCENTAGE') {
|
|
38
|
+
return (this.feeAmount() * value) / 100;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return Math.min(value, this.feeAmount());
|
|
42
|
+
}
|
|
43
|
+
}, ...(ngDevMode ? [{ debugName: "calculatedDiscountAmount" }] : []));
|
|
44
|
+
constructor() {
|
|
45
|
+
// Initialize form with existing discount data
|
|
46
|
+
effect(() => {
|
|
47
|
+
const existing = this.existingDiscount();
|
|
48
|
+
if (existing) {
|
|
49
|
+
this.discountForm.patchValue({
|
|
50
|
+
discount_type: existing.discount_type,
|
|
51
|
+
discount_value: existing.discount_value,
|
|
52
|
+
discount_reason_id: existing.discount_reason_id || '',
|
|
53
|
+
valid_from: this.formatDateForInput(existing.valid_from),
|
|
54
|
+
valid_to: this.formatDateForInput(existing.valid_to),
|
|
55
|
+
notes: existing.notes || ''
|
|
56
|
+
}, { emitEvent: false });
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Set default valid_from to today
|
|
60
|
+
this.discountForm.patchValue({
|
|
61
|
+
valid_from: this.getTodayDateString()
|
|
62
|
+
}, { emitEvent: false });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// Update max value when discount type changes
|
|
66
|
+
effect(() => {
|
|
67
|
+
const type = this.discountForm.get('discount_type')?.value;
|
|
68
|
+
const control = this.discountForm.get('discount_value');
|
|
69
|
+
if (control && type) {
|
|
70
|
+
const max = type === 'PERCENTAGE' ? 100 : this.feeAmount();
|
|
71
|
+
control.setValidators([
|
|
72
|
+
Validators.required,
|
|
73
|
+
Validators.min(0),
|
|
74
|
+
Validators.max(max)
|
|
75
|
+
]);
|
|
76
|
+
control.updateValueAndValidity();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
onSave() {
|
|
81
|
+
if (!this.discountForm.valid)
|
|
82
|
+
return;
|
|
83
|
+
const formValue = this.discountForm.value;
|
|
84
|
+
const discountData = {
|
|
85
|
+
discount_type: formValue.discount_type,
|
|
86
|
+
discount_value: formValue.discount_value || 0,
|
|
87
|
+
discount_reason_id: formValue.discount_reason_id || undefined,
|
|
88
|
+
discount_reason_title: this.getDiscountReasonTitle(formValue.discount_reason_id || ''),
|
|
89
|
+
valid_from: formValue.valid_from ? new Date(formValue.valid_from) : undefined,
|
|
90
|
+
valid_to: formValue.valid_to ? new Date(formValue.valid_to) : undefined,
|
|
91
|
+
notes: formValue.notes || undefined
|
|
92
|
+
};
|
|
93
|
+
this.saved.emit(discountData);
|
|
94
|
+
}
|
|
95
|
+
onCancel() {
|
|
96
|
+
this.cancelled.emit();
|
|
97
|
+
}
|
|
98
|
+
formatDateForInput(date) {
|
|
99
|
+
if (!date)
|
|
100
|
+
return '';
|
|
101
|
+
const d = new Date(date);
|
|
102
|
+
return d.toISOString().split('T')[0];
|
|
103
|
+
}
|
|
104
|
+
getTodayDateString() {
|
|
105
|
+
return new Date().toISOString().split('T')[0];
|
|
106
|
+
}
|
|
107
|
+
getDiscountReasonTitle(reasonId) {
|
|
108
|
+
if (!reasonId)
|
|
109
|
+
return undefined;
|
|
110
|
+
const reason = this.discountReasonOptions().find(r => r.value === reasonId);
|
|
111
|
+
return reason?.label;
|
|
112
|
+
}
|
|
113
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeeDiscountFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
114
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: FeeDiscountFormComponent, isStandalone: true, selector: "cide-fee-discount-form", inputs: { feeId: { classPropertyName: "feeId", publicName: "feeId", isSignal: true, isRequired: true, transformFunction: null }, feeName: { classPropertyName: "feeName", publicName: "feeName", isSignal: true, isRequired: true, transformFunction: null }, feeAmount: { classPropertyName: "feeAmount", publicName: "feeAmount", isSignal: true, isRequired: true, transformFunction: null }, existingDiscount: { classPropertyName: "existingDiscount", publicName: "existingDiscount", isSignal: true, isRequired: false, transformFunction: null }, discountReasonOptions: { classPropertyName: "discountReasonOptions", publicName: "discountReasonOptions", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: `
|
|
115
|
+
<div class="tw-p-4 tw-space-y-4">
|
|
116
|
+
<div class="tw-mb-4">
|
|
117
|
+
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900">
|
|
118
|
+
{{ existingDiscount() ? 'Edit Discount' : 'Add Discount' }}
|
|
119
|
+
</h3>
|
|
120
|
+
<p class="tw-text-sm tw-text-gray-600 tw-mt-1">{{ feeName() }}</p>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<form [formGroup]="discountForm" class="tw-space-y-4">
|
|
124
|
+
<!-- Discount Type -->
|
|
125
|
+
<div>
|
|
126
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
127
|
+
Discount Type *
|
|
128
|
+
</label>
|
|
129
|
+
<cide-ele-select
|
|
130
|
+
formControlName="discount_type"
|
|
131
|
+
[options]="[{value: 'PERCENTAGE', label: 'Percentage'}, {value: 'FIXED_AMOUNT', label: 'Fixed Amount'}]"
|
|
132
|
+
size="sm">
|
|
133
|
+
</cide-ele-select>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<!-- Discount Value -->
|
|
137
|
+
<div>
|
|
138
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
139
|
+
Discount Value *
|
|
140
|
+
@if (discountForm.get('discount_type')?.value === 'PERCENTAGE') {
|
|
141
|
+
<span class="tw-text-gray-500">(%)</span>
|
|
142
|
+
} @else {
|
|
143
|
+
<span class="tw-text-gray-500">(Amount)</span>
|
|
144
|
+
}
|
|
145
|
+
</label>
|
|
146
|
+
<cide-ele-input
|
|
147
|
+
type="number"
|
|
148
|
+
formControlName="discount_value"
|
|
149
|
+
[min]="0"
|
|
150
|
+
[max]="maxDiscountValue()"
|
|
151
|
+
size="sm">
|
|
152
|
+
</cide-ele-input>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<!-- Discount Reason -->
|
|
156
|
+
<div>
|
|
157
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
158
|
+
Discount Reason
|
|
159
|
+
</label>
|
|
160
|
+
<cide-ele-select
|
|
161
|
+
formControlName="discount_reason_id"
|
|
162
|
+
[options]="discountReasonOptions()"
|
|
163
|
+
placeholder="Select reason"
|
|
164
|
+
size="sm">
|
|
165
|
+
</cide-ele-select>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<!-- Valid From / Valid To -->
|
|
169
|
+
<div class="tw-grid tw-grid-cols-2 tw-gap-4">
|
|
170
|
+
<div>
|
|
171
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
172
|
+
Valid From
|
|
173
|
+
</label>
|
|
174
|
+
<cide-ele-input
|
|
175
|
+
type="date"
|
|
176
|
+
formControlName="valid_from"
|
|
177
|
+
size="sm">
|
|
178
|
+
</cide-ele-input>
|
|
179
|
+
</div>
|
|
180
|
+
<div>
|
|
181
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
182
|
+
Valid To
|
|
183
|
+
</label>
|
|
184
|
+
<cide-ele-input
|
|
185
|
+
type="date"
|
|
186
|
+
formControlName="valid_to"
|
|
187
|
+
size="sm">
|
|
188
|
+
</cide-ele-input>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<!-- Notes -->
|
|
193
|
+
<div>
|
|
194
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
195
|
+
Notes
|
|
196
|
+
</label>
|
|
197
|
+
<cide-ele-textarea
|
|
198
|
+
formControlName="notes"
|
|
199
|
+
rows="2"
|
|
200
|
+
size="sm">
|
|
201
|
+
</cide-ele-textarea>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<!-- Calculated Discount Preview -->
|
|
205
|
+
@if (calculatedDiscountAmount() > 0) {
|
|
206
|
+
<div class="tw-p-3 tw-bg-blue-50 tw-rounded tw-border tw-border-blue-200">
|
|
207
|
+
<p class="tw-text-sm tw-text-gray-700">
|
|
208
|
+
<span class="tw-font-medium">Calculated Discount:</span>
|
|
209
|
+
<span class="tw-ml-2 tw-font-semibold tw-text-blue-600">
|
|
210
|
+
{{ calculatedDiscountAmount() | currency }}
|
|
211
|
+
</span>
|
|
212
|
+
</p>
|
|
213
|
+
</div>
|
|
214
|
+
}
|
|
215
|
+
</form>
|
|
216
|
+
|
|
217
|
+
<!-- Actions -->
|
|
218
|
+
<div class="tw-flex tw-justify-end tw-gap-2 tw-pt-4 tw-border-t tw-border-gray-200">
|
|
219
|
+
<button
|
|
220
|
+
type="button"
|
|
221
|
+
cideEleButton
|
|
222
|
+
variant="ghost"
|
|
223
|
+
size="sm"
|
|
224
|
+
(click)="onCancel()">
|
|
225
|
+
Cancel
|
|
226
|
+
</button>
|
|
227
|
+
<button
|
|
228
|
+
type="button"
|
|
229
|
+
cideEleButton
|
|
230
|
+
variant="primary"
|
|
231
|
+
size="sm"
|
|
232
|
+
[disabled]="!discountForm.valid"
|
|
233
|
+
(click)="onSave()">
|
|
234
|
+
{{ existingDiscount() ? 'Update Discount' : 'Save Discount' }}
|
|
235
|
+
</button>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "step", "size"], outputs: ["ngModelChange"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading", "valueKey", "labelKey", "treeView"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideTextareaComponent, selector: "cide-ele-textarea", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "minlength", "maxlength", "rows", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput"], outputs: ["ngModelChange"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "pipe", type: CurrencyPipe, name: "currency" }] });
|
|
239
|
+
}
|
|
240
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeeDiscountFormComponent, decorators: [{
|
|
241
|
+
type: Component,
|
|
242
|
+
args: [{
|
|
243
|
+
selector: 'cide-fee-discount-form',
|
|
244
|
+
standalone: true,
|
|
245
|
+
imports: [
|
|
246
|
+
CommonModule,
|
|
247
|
+
ReactiveFormsModule,
|
|
248
|
+
CideInputComponent,
|
|
249
|
+
CideSelectComponent,
|
|
250
|
+
CideTextareaComponent,
|
|
251
|
+
CideEleButtonComponent,
|
|
252
|
+
CurrencyPipe
|
|
253
|
+
],
|
|
254
|
+
template: `
|
|
255
|
+
<div class="tw-p-4 tw-space-y-4">
|
|
256
|
+
<div class="tw-mb-4">
|
|
257
|
+
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900">
|
|
258
|
+
{{ existingDiscount() ? 'Edit Discount' : 'Add Discount' }}
|
|
259
|
+
</h3>
|
|
260
|
+
<p class="tw-text-sm tw-text-gray-600 tw-mt-1">{{ feeName() }}</p>
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
<form [formGroup]="discountForm" class="tw-space-y-4">
|
|
264
|
+
<!-- Discount Type -->
|
|
265
|
+
<div>
|
|
266
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
267
|
+
Discount Type *
|
|
268
|
+
</label>
|
|
269
|
+
<cide-ele-select
|
|
270
|
+
formControlName="discount_type"
|
|
271
|
+
[options]="[{value: 'PERCENTAGE', label: 'Percentage'}, {value: 'FIXED_AMOUNT', label: 'Fixed Amount'}]"
|
|
272
|
+
size="sm">
|
|
273
|
+
</cide-ele-select>
|
|
274
|
+
</div>
|
|
275
|
+
|
|
276
|
+
<!-- Discount Value -->
|
|
277
|
+
<div>
|
|
278
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
279
|
+
Discount Value *
|
|
280
|
+
@if (discountForm.get('discount_type')?.value === 'PERCENTAGE') {
|
|
281
|
+
<span class="tw-text-gray-500">(%)</span>
|
|
282
|
+
} @else {
|
|
283
|
+
<span class="tw-text-gray-500">(Amount)</span>
|
|
284
|
+
}
|
|
285
|
+
</label>
|
|
286
|
+
<cide-ele-input
|
|
287
|
+
type="number"
|
|
288
|
+
formControlName="discount_value"
|
|
289
|
+
[min]="0"
|
|
290
|
+
[max]="maxDiscountValue()"
|
|
291
|
+
size="sm">
|
|
292
|
+
</cide-ele-input>
|
|
293
|
+
</div>
|
|
294
|
+
|
|
295
|
+
<!-- Discount Reason -->
|
|
296
|
+
<div>
|
|
297
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
298
|
+
Discount Reason
|
|
299
|
+
</label>
|
|
300
|
+
<cide-ele-select
|
|
301
|
+
formControlName="discount_reason_id"
|
|
302
|
+
[options]="discountReasonOptions()"
|
|
303
|
+
placeholder="Select reason"
|
|
304
|
+
size="sm">
|
|
305
|
+
</cide-ele-select>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<!-- Valid From / Valid To -->
|
|
309
|
+
<div class="tw-grid tw-grid-cols-2 tw-gap-4">
|
|
310
|
+
<div>
|
|
311
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
312
|
+
Valid From
|
|
313
|
+
</label>
|
|
314
|
+
<cide-ele-input
|
|
315
|
+
type="date"
|
|
316
|
+
formControlName="valid_from"
|
|
317
|
+
size="sm">
|
|
318
|
+
</cide-ele-input>
|
|
319
|
+
</div>
|
|
320
|
+
<div>
|
|
321
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
322
|
+
Valid To
|
|
323
|
+
</label>
|
|
324
|
+
<cide-ele-input
|
|
325
|
+
type="date"
|
|
326
|
+
formControlName="valid_to"
|
|
327
|
+
size="sm">
|
|
328
|
+
</cide-ele-input>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
<!-- Notes -->
|
|
333
|
+
<div>
|
|
334
|
+
<label class="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
|
335
|
+
Notes
|
|
336
|
+
</label>
|
|
337
|
+
<cide-ele-textarea
|
|
338
|
+
formControlName="notes"
|
|
339
|
+
rows="2"
|
|
340
|
+
size="sm">
|
|
341
|
+
</cide-ele-textarea>
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<!-- Calculated Discount Preview -->
|
|
345
|
+
@if (calculatedDiscountAmount() > 0) {
|
|
346
|
+
<div class="tw-p-3 tw-bg-blue-50 tw-rounded tw-border tw-border-blue-200">
|
|
347
|
+
<p class="tw-text-sm tw-text-gray-700">
|
|
348
|
+
<span class="tw-font-medium">Calculated Discount:</span>
|
|
349
|
+
<span class="tw-ml-2 tw-font-semibold tw-text-blue-600">
|
|
350
|
+
{{ calculatedDiscountAmount() | currency }}
|
|
351
|
+
</span>
|
|
352
|
+
</p>
|
|
353
|
+
</div>
|
|
354
|
+
}
|
|
355
|
+
</form>
|
|
356
|
+
|
|
357
|
+
<!-- Actions -->
|
|
358
|
+
<div class="tw-flex tw-justify-end tw-gap-2 tw-pt-4 tw-border-t tw-border-gray-200">
|
|
359
|
+
<button
|
|
360
|
+
type="button"
|
|
361
|
+
cideEleButton
|
|
362
|
+
variant="ghost"
|
|
363
|
+
size="sm"
|
|
364
|
+
(click)="onCancel()">
|
|
365
|
+
Cancel
|
|
366
|
+
</button>
|
|
367
|
+
<button
|
|
368
|
+
type="button"
|
|
369
|
+
cideEleButton
|
|
370
|
+
variant="primary"
|
|
371
|
+
size="sm"
|
|
372
|
+
[disabled]="!discountForm.valid"
|
|
373
|
+
(click)="onSave()">
|
|
374
|
+
{{ existingDiscount() ? 'Update Discount' : 'Save Discount' }}
|
|
375
|
+
</button>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
`
|
|
379
|
+
}]
|
|
380
|
+
}], ctorParameters: () => [], propDecorators: { feeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "feeId", required: true }] }], feeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "feeName", required: true }] }], feeAmount: [{ type: i0.Input, args: [{ isSignal: true, alias: "feeAmount", required: true }] }], existingDiscount: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingDiscount", required: false }] }], discountReasonOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "discountReasonOptions", required: true }] }], saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
|
|
381
|
+
|
|
382
|
+
export { FeeDiscountFormComponent };
|
|
383
|
+
//# sourceMappingURL=cloud-ide-fees-fee-discount-form.component-R_yZNKM-.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-ide-fees-fee-discount-form.component-R_yZNKM-.mjs","sources":["../../../projects/cloud-ide-fees/src/lib/shared/components/fee-discount-form/fee-discount-form.component.ts"],"sourcesContent":["\r\nimport { Component, inject, signal, computed, input, output, effect } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\r\nimport { CideInputComponent, CideSelectComponent, CideTextareaComponent, CideEleButtonComponent, CurrencyPipe } from 'cloud-ide-element';\r\n\r\nexport interface FeeDiscountFormData {\r\n discount_type: 'PERCENTAGE' | 'FIXED_AMOUNT';\r\n discount_value: number;\r\n discount_reason_id?: string;\r\n discount_reason_title?: string;\r\n valid_from?: Date;\r\n valid_to?: Date;\r\n notes?: string;\r\n}\r\n\r\nexport interface FeeDiscountFormInputs {\r\n feeId: string;\r\n feeName: string;\r\n feeAmount: number;\r\n existingDiscount?: FeeDiscountFormData | null;\r\n discountReasonOptions: Array<{ value: string; label: string }>;\r\n}\r\n\r\n@Component({\r\n selector: 'cide-fee-discount-form',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n ReactiveFormsModule,\r\n CideInputComponent,\r\n CideSelectComponent,\r\n CideTextareaComponent,\r\n CideEleButtonComponent,\r\n CurrencyPipe\r\n ],\r\n template: `\r\n <div class=\"tw-p-4 tw-space-y-4\">\r\n <div class=\"tw-mb-4\">\r\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-gray-900\">\r\n {{ existingDiscount() ? 'Edit Discount' : 'Add Discount' }}\r\n </h3>\r\n <p class=\"tw-text-sm tw-text-gray-600 tw-mt-1\">{{ feeName() }}</p>\r\n </div>\r\n\r\n <form [formGroup]=\"discountForm\" class=\"tw-space-y-4\">\r\n <!-- Discount Type -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Discount Type *\r\n </label>\r\n <cide-ele-select\r\n formControlName=\"discount_type\"\r\n [options]=\"[{value: 'PERCENTAGE', label: 'Percentage'}, {value: 'FIXED_AMOUNT', label: 'Fixed Amount'}]\"\r\n size=\"sm\">\r\n </cide-ele-select>\r\n </div>\r\n\r\n <!-- Discount Value -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Discount Value *\r\n @if (discountForm.get('discount_type')?.value === 'PERCENTAGE') {\r\n <span class=\"tw-text-gray-500\">(%)</span>\r\n } @else {\r\n <span class=\"tw-text-gray-500\">(Amount)</span>\r\n }\r\n </label>\r\n <cide-ele-input\r\n type=\"number\"\r\n formControlName=\"discount_value\"\r\n [min]=\"0\"\r\n [max]=\"maxDiscountValue()\"\r\n size=\"sm\">\r\n </cide-ele-input>\r\n </div>\r\n\r\n <!-- Discount Reason -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Discount Reason\r\n </label>\r\n <cide-ele-select\r\n formControlName=\"discount_reason_id\"\r\n [options]=\"discountReasonOptions()\"\r\n placeholder=\"Select reason\"\r\n size=\"sm\">\r\n </cide-ele-select>\r\n </div>\r\n\r\n <!-- Valid From / Valid To -->\r\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-4\">\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Valid From\r\n </label>\r\n <cide-ele-input\r\n type=\"date\"\r\n formControlName=\"valid_from\"\r\n size=\"sm\">\r\n </cide-ele-input>\r\n </div>\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Valid To\r\n </label>\r\n <cide-ele-input\r\n type=\"date\"\r\n formControlName=\"valid_to\"\r\n size=\"sm\">\r\n </cide-ele-input>\r\n </div>\r\n </div>\r\n\r\n <!-- Notes -->\r\n <div>\r\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1\">\r\n Notes\r\n </label>\r\n <cide-ele-textarea\r\n formControlName=\"notes\"\r\n rows=\"2\"\r\n size=\"sm\">\r\n </cide-ele-textarea>\r\n </div>\r\n\r\n <!-- Calculated Discount Preview -->\r\n @if (calculatedDiscountAmount() > 0) {\r\n <div class=\"tw-p-3 tw-bg-blue-50 tw-rounded tw-border tw-border-blue-200\">\r\n <p class=\"tw-text-sm tw-text-gray-700\">\r\n <span class=\"tw-font-medium\">Calculated Discount:</span>\r\n <span class=\"tw-ml-2 tw-font-semibold tw-text-blue-600\">\r\n {{ calculatedDiscountAmount() | currency }}\r\n </span>\r\n </p>\r\n </div>\r\n }\r\n </form>\r\n\r\n <!-- Actions -->\r\n <div class=\"tw-flex tw-justify-end tw-gap-2 tw-pt-4 tw-border-t tw-border-gray-200\">\r\n <button\r\n type=\"button\"\r\n cideEleButton\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n (click)=\"onCancel()\">\r\n Cancel\r\n </button>\r\n <button\r\n type=\"button\"\r\n cideEleButton\r\n variant=\"primary\"\r\n size=\"sm\"\r\n [disabled]=\"!discountForm.valid\"\r\n (click)=\"onSave()\">\r\n {{ existingDiscount() ? 'Update Discount' : 'Save Discount' }}\r\n </button>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class FeeDiscountFormComponent {\r\n // Inputs\r\n readonly feeId = input.required<string>();\r\n readonly feeName = input.required<string>();\r\n readonly feeAmount = input.required<number>();\r\n readonly existingDiscount = input<FeeDiscountFormData | null>(null);\r\n readonly discountReasonOptions = input.required<Array<{ value: string; label: string }>>();\r\n\r\n // Outputs\r\n readonly saved = output<FeeDiscountFormData>();\r\n readonly cancelled = output<void>();\r\n\r\n // Form using signals (modern Angular approach)\r\n discountForm = new FormGroup({\r\n discount_type: new FormControl<'PERCENTAGE' | 'FIXED_AMOUNT'>('FIXED_AMOUNT', [Validators.required]),\r\n discount_value: new FormControl<number>(0, [Validators.required, Validators.min(0)]),\r\n discount_reason_id: new FormControl<string>(''),\r\n valid_from: new FormControl<string>(''),\r\n valid_to: new FormControl<string>(''),\r\n notes: new FormControl<string>('')\r\n });\r\n\r\n // Computed values\r\n readonly maxDiscountValue = computed(() => {\r\n const type = this.discountForm.get('discount_type')?.value;\r\n return type === 'PERCENTAGE' ? 100 : this.feeAmount();\r\n });\r\n\r\n readonly calculatedDiscountAmount = computed(() => {\r\n const type = this.discountForm.get('discount_type')?.value;\r\n const value = this.discountForm.get('discount_value')?.value || 0;\r\n\r\n if (!type || value <= 0) return 0;\r\n\r\n if (type === 'PERCENTAGE') {\r\n return (this.feeAmount() * value) / 100;\r\n } else {\r\n return Math.min(value, this.feeAmount());\r\n }\r\n });\r\n\r\n constructor() {\r\n // Initialize form with existing discount data\r\n effect(() => {\r\n const existing = this.existingDiscount();\r\n if (existing) {\r\n this.discountForm.patchValue({\r\n discount_type: existing.discount_type,\r\n discount_value: existing.discount_value,\r\n discount_reason_id: existing.discount_reason_id || '',\r\n valid_from: this.formatDateForInput(existing.valid_from),\r\n valid_to: this.formatDateForInput(existing.valid_to),\r\n notes: existing.notes || ''\r\n }, { emitEvent: false });\r\n } else {\r\n // Set default valid_from to today\r\n this.discountForm.patchValue({\r\n valid_from: this.getTodayDateString()\r\n }, { emitEvent: false });\r\n }\r\n });\r\n\r\n // Update max value when discount type changes\r\n effect(() => {\r\n const type = this.discountForm.get('discount_type')?.value;\r\n const control = this.discountForm.get('discount_value');\r\n if (control && type) {\r\n const max = type === 'PERCENTAGE' ? 100 : this.feeAmount();\r\n control.setValidators([\r\n Validators.required,\r\n Validators.min(0),\r\n Validators.max(max)\r\n ]);\r\n control.updateValueAndValidity();\r\n }\r\n });\r\n }\r\n\r\n onSave(): void {\r\n if (!this.discountForm.valid) return;\r\n\r\n const formValue = this.discountForm.value;\r\n const discountData: FeeDiscountFormData = {\r\n discount_type: formValue.discount_type!,\r\n discount_value: formValue.discount_value || 0,\r\n discount_reason_id: formValue.discount_reason_id || undefined,\r\n discount_reason_title: this.getDiscountReasonTitle(formValue.discount_reason_id || ''),\r\n valid_from: formValue.valid_from ? new Date(formValue.valid_from) : undefined,\r\n valid_to: formValue.valid_to ? new Date(formValue.valid_to) : undefined,\r\n notes: formValue.notes || undefined\r\n };\r\n\r\n this.saved.emit(discountData);\r\n }\r\n\r\n onCancel(): void {\r\n this.cancelled.emit();\r\n }\r\n\r\n private formatDateForInput(date?: Date): string {\r\n if (!date) return '';\r\n const d = new Date(date);\r\n return d.toISOString().split('T')[0];\r\n }\r\n\r\n private getTodayDateString(): string {\r\n return new Date().toISOString().split('T')[0];\r\n }\r\n\r\n private getDiscountReasonTitle(reasonId: string): string | undefined {\r\n if (!reasonId) return undefined;\r\n const reason = this.discountReasonOptions().find(r => r.value === reasonId);\r\n return reason?.label;\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
|