@hed-hog/finance 0.0.231 → 0.0.232
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/dist/dto/create-financial-title.dto.d.ts +1 -0
- package/dist/dto/create-financial-title.dto.d.ts.map +1 -1
- package/dist/dto/create-financial-title.dto.js +11 -0
- package/dist/dto/create-financial-title.dto.js.map +1 -1
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +139 -4
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +78 -61
- package/package.json +4 -4
- package/src/dto/create-financial-title.dto.ts +12 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-financial-title.dto.d.ts","sourceRoot":"","sources":["../../src/dto/create-financial-title.dto.ts"],"names":[],"mappings":"AAcA,qBAAa,6BAA6B;IAUxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAS5B,QAAQ,EAAE,MAAM,CAAC;IAajB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,uBAAuB;IAOlC,eAAe,EAAE,MAAM,CAAC;IAKxB,SAAS,EAAE,MAAM,CAAC;IAUlB,eAAe,CAAC,EAAE,MAAM,CAAC;IAUzB,UAAU,CAAC,EAAE,MAAM,CAAC;IASpB,QAAQ,EAAE,MAAM,CAAC;IAajB,YAAY,EAAE,MAAM,CAAC;IAOrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAO7B,cAAc,CAAC,EAAE,MAAM,CAAC;IAOxB,eAAe,CAAC,EAAE,MAAM,CAAC;IAOzB,WAAW,CAAC,EAAE,MAAM,CAAC;IASrB,YAAY,CAAC,EAAE,6BAA6B,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"create-financial-title.dto.d.ts","sourceRoot":"","sources":["../../src/dto/create-financial-title.dto.ts"],"names":[],"mappings":"AAcA,qBAAa,6BAA6B;IAUxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAS5B,QAAQ,EAAE,MAAM,CAAC;IAajB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,uBAAuB;IAOlC,eAAe,EAAE,MAAM,CAAC;IAKxB,SAAS,EAAE,MAAM,CAAC;IAUlB,eAAe,CAAC,EAAE,MAAM,CAAC;IAUzB,UAAU,CAAC,EAAE,MAAM,CAAC;IASpB,QAAQ,EAAE,MAAM,CAAC;IAajB,YAAY,EAAE,MAAM,CAAC;IAOrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAO7B,cAAc,CAAC,EAAE,MAAM,CAAC;IAOxB,eAAe,CAAC,EAAE,MAAM,CAAC;IAOzB,WAAW,CAAC,EAAE,MAAM,CAAC;IASrB,YAAY,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAY/C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC"}
|
|
@@ -125,4 +125,15 @@ __decorate([
|
|
|
125
125
|
(0, class_transformer_1.Type)(() => CreateFinancialInstallmentDto),
|
|
126
126
|
__metadata("design:type", Array)
|
|
127
127
|
], CreateFinancialTitleDto.prototype, "installments", void 0);
|
|
128
|
+
__decorate([
|
|
129
|
+
(0, class_validator_1.IsOptional)(),
|
|
130
|
+
(0, class_validator_1.IsArray)({
|
|
131
|
+
message: (args) => (0, api_locale_1.getLocaleText)('validation.attachmentFileIdsMustBeArray', args.value),
|
|
132
|
+
}),
|
|
133
|
+
(0, class_validator_1.IsInt)({
|
|
134
|
+
each: true,
|
|
135
|
+
message: (args) => (0, api_locale_1.getLocaleText)('validation.attachmentFileIdMustBeNumber', args.value),
|
|
136
|
+
}),
|
|
137
|
+
__metadata("design:type", Array)
|
|
138
|
+
], CreateFinancialTitleDto.prototype, "attachment_file_ids", void 0);
|
|
128
139
|
//# sourceMappingURL=create-financial-title.dto.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-financial-title.dto.js","sourceRoot":"","sources":["../../src/dto/create-financial-title.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAoD;AACpD,yDAAyC;AACzC,qDAUyB;AAEzB,MAAa,6BAA6B;CAiCzC;AAjCD,sEAiCC;AAvBC;IATC,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAK,EAAC;QACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,0CAA0C,EAAE,IAAI,CAAC,KAAK,CAAC;KACxE,CAAC;IACD,IAAA,qBAAG,EAAC,CAAC,EAAE;QACN,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC;KAC/D,CAAC;;yEAC0B;AAS5B;IAPC,IAAA,8BAAY,EACX,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,8BAA8B,EAAE,IAAI,CAAC,KAAK,CAAC;KAC5D,CACF;;+DACgB;AAajB;IAXC,IAAA,0BAAQ,EACP,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,0CAA0C,EAAE,IAAI,CAAC,KAAK,CAAC;KACxE,CACF;IACA,IAAA,qBAAG,EAAC,IAAI,EAAE;QACT,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC;KAC/D,CAAC;;6DACa;AAGjB,MAAa,uBAAuB;
|
|
1
|
+
{"version":3,"file":"create-financial-title.dto.js","sourceRoot":"","sources":["../../src/dto/create-financial-title.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAoD;AACpD,yDAAyC;AACzC,qDAUyB;AAEzB,MAAa,6BAA6B;CAiCzC;AAjCD,sEAiCC;AAvBC;IATC,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAK,EAAC;QACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,0CAA0C,EAAE,IAAI,CAAC,KAAK,CAAC;KACxE,CAAC;IACD,IAAA,qBAAG,EAAC,CAAC,EAAE;QACN,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC;KAC/D,CAAC;;yEAC0B;AAS5B;IAPC,IAAA,8BAAY,EACX,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,8BAA8B,EAAE,IAAI,CAAC,KAAK,CAAC;KAC5D,CACF;;+DACgB;AAajB;IAXC,IAAA,0BAAQ,EACP,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,0CAA0C,EAAE,IAAI,CAAC,KAAK,CAAC;KACxE,CACF;IACA,IAAA,qBAAG,EAAC,IAAI,EAAE;QACT,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC;KAC/D,CAAC;;6DACa;AAGjB,MAAa,uBAAuB;CAwGnC;AAxGD,0DAwGC;AAjGC;IANC,IAAA,0BAAQ,EAAC;QACR,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,0BAAa,EAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC;KAChF,CAAC;IACD,IAAA,4BAAU,EAAC;QACV,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,0BAAa,EAAC,6BAA6B,EAAE,IAAI,CAAC,KAAK,CAAC;KAC5E,CAAC;;gEACsB;AAKxB;IAHC,IAAA,uBAAK,EAAC;QACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,0BAAa,EAAC,iCAAiC,EAAE,IAAI,CAAC,KAAK,CAAC;KAChF,CAAC;;0DACgB;AAUlB;IARC,IAAA,4BAAU,GAAE;IACZ,IAAA,8BAAY,EACX,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,qCAAqC,EAAE,IAAI,CAAC,KAAK,CAAC;KACnE,CACF;;gEACwB;AAUzB;IARC,IAAA,4BAAU,GAAE;IACZ,IAAA,8BAAY,EACX,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,gCAAgC,EAAE,IAAI,CAAC,KAAK,CAAC;KAC9D,CACF;;2DACmB;AASpB;IAPC,IAAA,8BAAY,EACX,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,8BAA8B,EAAE,IAAI,CAAC,KAAK,CAAC;KAC5D,CACF;;yDACgB;AAajB;IAXC,IAAA,0BAAQ,EACP,EAAE,EACF;QACE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,oCAAoC,EAAE,IAAI,CAAC,KAAK,CAAC;KAClE,CACF;IACA,IAAA,qBAAG,EAAC,IAAI,EAAE;QACT,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,2BAA2B,EAAE,IAAI,CAAC,KAAK,CAAC;KACzD,CAAC;;6DACmB;AAOrB;IALC,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAK,EAAC;QACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,0CAA0C,EAAE,IAAI,CAAC,KAAK,CAAC;KACxE,CAAC;;oEAC2B;AAO7B;IALC,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAK,EAAC;QACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,qCAAqC,EAAE,IAAI,CAAC,KAAK,CAAC;KACnE,CAAC;;+DACsB;AAOxB;IALC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,EAAC;QACR,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,uCAAuC,EAAE,IAAI,CAAC,KAAK,CAAC;KACrE,CAAC;;gEACuB;AAOzB;IALC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,EAAC;QACR,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,oCAAoC,EAAE,IAAI,CAAC,KAAK,CAAC;KAClE,CAAC;;4DACmB;AASrB;IAPC,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,EAAC;QACP,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,oCAAoC,EAAE,IAAI,CAAC,KAAK,CAAC;KAClE,CAAC;IACD,IAAA,gCAAc,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,6BAA6B,CAAC;;6DACK;AAY/C;IAVC,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,EAAC;QACP,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,yCAAyC,EAAE,IAAI,CAAC,KAAK,CAAC;KACvE,CAAC;IACD,IAAA,uBAAK,EAAC;QACL,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAChB,IAAA,0BAAa,EAAC,yCAAyC,EAAE,IAAI,CAAC,KAAK,CAAC;KACvE,CAAC;;oEAC6B"}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import { Input } from '@/components/ui/input';
|
|
22
22
|
import { InputMoney } from '@/components/ui/input-money';
|
|
23
23
|
import { Money } from '@/components/ui/money';
|
|
24
|
+
import { Progress } from '@/components/ui/progress';
|
|
24
25
|
import {
|
|
25
26
|
Select,
|
|
26
27
|
SelectContent,
|
|
@@ -96,6 +97,28 @@ function NovoTituloSheet({
|
|
|
96
97
|
}) {
|
|
97
98
|
const { request, showToastHandler } = useApp();
|
|
98
99
|
const [open, setOpen] = useState(false);
|
|
100
|
+
const [uploadedFileId, setUploadedFileId] = useState<number | null>(null);
|
|
101
|
+
const [uploadedFileName, setUploadedFileName] = useState('');
|
|
102
|
+
const [isUploadingFile, setIsUploadingFile] = useState(false);
|
|
103
|
+
const [uploadProgress, setUploadProgress] = useState(0);
|
|
104
|
+
|
|
105
|
+
const normalizeFilenameForDisplay = (filename: string) => {
|
|
106
|
+
if (!filename) {
|
|
107
|
+
return filename;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!/Ã.|Â.|â[\u0080-\u00BF]/.test(filename)) {
|
|
111
|
+
return filename;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const bytes = Uint8Array.from(filename, (char) => char.charCodeAt(0));
|
|
116
|
+
const decoded = new TextDecoder('utf-8').decode(bytes);
|
|
117
|
+
return /Ã.|Â.|â[\u0080-\u00BF]/.test(decoded) ? filename : decoded;
|
|
118
|
+
} catch {
|
|
119
|
+
return filename;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
99
122
|
|
|
100
123
|
const form = useForm<NewTitleFormValues>({
|
|
101
124
|
resolver: zodResolver(newTitleFormSchema),
|
|
@@ -133,11 +156,14 @@ function NovoTituloSheet({
|
|
|
133
156
|
: undefined,
|
|
134
157
|
payment_channel: values.metodo || undefined,
|
|
135
158
|
description: values.descricao?.trim() || undefined,
|
|
159
|
+
attachment_file_ids: uploadedFileId ? [uploadedFileId] : undefined,
|
|
136
160
|
},
|
|
137
161
|
});
|
|
138
162
|
|
|
139
163
|
await onCreated();
|
|
140
164
|
form.reset();
|
|
165
|
+
setUploadedFileId(null);
|
|
166
|
+
setUploadedFileName('');
|
|
141
167
|
setOpen(false);
|
|
142
168
|
showToastHandler?.('success', 'Título criado com sucesso');
|
|
143
169
|
} catch {
|
|
@@ -147,9 +173,83 @@ function NovoTituloSheet({
|
|
|
147
173
|
|
|
148
174
|
const handleCancel = () => {
|
|
149
175
|
form.reset();
|
|
176
|
+
setUploadedFileId(null);
|
|
177
|
+
setUploadedFileName('');
|
|
178
|
+
setUploadProgress(0);
|
|
150
179
|
setOpen(false);
|
|
151
180
|
};
|
|
152
181
|
|
|
182
|
+
const uploadRelatedFile = async (file: File) => {
|
|
183
|
+
setIsUploadingFile(true);
|
|
184
|
+
setUploadProgress(0);
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
const formData = new FormData();
|
|
188
|
+
formData.append('file', file);
|
|
189
|
+
formData.append('destination', 'finance/titles');
|
|
190
|
+
|
|
191
|
+
const { data } = await request<{ id: number; filename: string }>({
|
|
192
|
+
url: '/file',
|
|
193
|
+
method: 'POST',
|
|
194
|
+
data: formData,
|
|
195
|
+
headers: {
|
|
196
|
+
'Content-Type': 'multipart/form-data',
|
|
197
|
+
},
|
|
198
|
+
onUploadProgress: (event) => {
|
|
199
|
+
if (!event.total) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const progress = Math.round((event.loaded * 100) / event.total);
|
|
204
|
+
setUploadProgress(progress);
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
if (!data?.id) {
|
|
209
|
+
throw new Error('Arquivo inválido');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
setUploadedFileId(data.id);
|
|
213
|
+
setUploadedFileName(
|
|
214
|
+
normalizeFilenameForDisplay(data.filename || file.name)
|
|
215
|
+
);
|
|
216
|
+
setUploadProgress(100);
|
|
217
|
+
showToastHandler?.('success', 'Arquivo relacionado com sucesso');
|
|
218
|
+
} catch {
|
|
219
|
+
setUploadedFileId(null);
|
|
220
|
+
setUploadedFileName('');
|
|
221
|
+
setUploadProgress(0);
|
|
222
|
+
showToastHandler?.('error', 'Não foi possível enviar o arquivo');
|
|
223
|
+
} finally {
|
|
224
|
+
setIsUploadingFile(false);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const parseDateToIso = (value: string) => {
|
|
229
|
+
const sanitized = value.trim();
|
|
230
|
+
|
|
231
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(sanitized)) {
|
|
232
|
+
return sanitized;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const br = sanitized.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
236
|
+
if (br) {
|
|
237
|
+
return `${br[3]}-${br[2]}-${br[1]}`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return '';
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const parseMoneyToNumber = (value: string) => {
|
|
244
|
+
const normalized = value
|
|
245
|
+
.replace(/\s/g, '')
|
|
246
|
+
.replace(/\./g, '')
|
|
247
|
+
.replace(',', '.');
|
|
248
|
+
|
|
249
|
+
const parsed = Number(normalized);
|
|
250
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
251
|
+
};
|
|
252
|
+
|
|
153
253
|
return (
|
|
154
254
|
<Sheet open={open} onOpenChange={setOpen}>
|
|
155
255
|
<SheetTrigger asChild>
|
|
@@ -166,6 +266,41 @@ function NovoTituloSheet({
|
|
|
166
266
|
<Form {...form}>
|
|
167
267
|
<form className="px-4" onSubmit={form.handleSubmit(handleSubmit)}>
|
|
168
268
|
<div className="grid gap-4">
|
|
269
|
+
<div className="grid gap-2">
|
|
270
|
+
<FormLabel>Arquivo da fatura (opcional)</FormLabel>
|
|
271
|
+
<div className="flex flex-col gap-2 sm:flex-row sm:items-center">
|
|
272
|
+
<Input
|
|
273
|
+
type="file"
|
|
274
|
+
accept=".pdf,.png,.jpg,.jpeg,.xml,.txt"
|
|
275
|
+
onChange={(event) => {
|
|
276
|
+
const file = event.target.files?.[0];
|
|
277
|
+
if (!file) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
setUploadedFileId(null);
|
|
282
|
+
setUploadedFileName('');
|
|
283
|
+
setUploadProgress(0);
|
|
284
|
+
void uploadRelatedFile(file);
|
|
285
|
+
}}
|
|
286
|
+
disabled={isUploadingFile || form.formState.isSubmitting}
|
|
287
|
+
/>
|
|
288
|
+
</div>
|
|
289
|
+
{isUploadingFile && (
|
|
290
|
+
<div className="space-y-1">
|
|
291
|
+
<Progress value={uploadProgress} className="h-2" />
|
|
292
|
+
<p className="text-xs text-muted-foreground">
|
|
293
|
+
Upload em andamento: {uploadProgress}%
|
|
294
|
+
</p>
|
|
295
|
+
</div>
|
|
296
|
+
)}
|
|
297
|
+
{uploadedFileId && (
|
|
298
|
+
<p className="text-xs text-muted-foreground">
|
|
299
|
+
Arquivo relacionado: {uploadedFileName}
|
|
300
|
+
</p>
|
|
301
|
+
)}
|
|
302
|
+
</div>
|
|
303
|
+
|
|
169
304
|
<FormField
|
|
170
305
|
control={form.control}
|
|
171
306
|
name="documento"
|
|
@@ -188,7 +323,7 @@ function NovoTituloSheet({
|
|
|
188
323
|
<FormLabel>{t('fields.supplier')}</FormLabel>
|
|
189
324
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
190
325
|
<FormControl>
|
|
191
|
-
<SelectTrigger>
|
|
326
|
+
<SelectTrigger className="w-full">
|
|
192
327
|
<SelectValue placeholder={t('common.select')} />
|
|
193
328
|
</SelectTrigger>
|
|
194
329
|
</FormControl>
|
|
@@ -276,7 +411,7 @@ function NovoTituloSheet({
|
|
|
276
411
|
<FormLabel>{t('fields.category')}</FormLabel>
|
|
277
412
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
278
413
|
<FormControl>
|
|
279
|
-
<SelectTrigger>
|
|
414
|
+
<SelectTrigger className="w-full">
|
|
280
415
|
<SelectValue placeholder={t('common.select')} />
|
|
281
416
|
</SelectTrigger>
|
|
282
417
|
</FormControl>
|
|
@@ -303,7 +438,7 @@ function NovoTituloSheet({
|
|
|
303
438
|
<FormLabel>{t('fields.costCenter')}</FormLabel>
|
|
304
439
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
305
440
|
<FormControl>
|
|
306
|
-
<SelectTrigger>
|
|
441
|
+
<SelectTrigger className="w-full">
|
|
307
442
|
<SelectValue placeholder={t('common.select')} />
|
|
308
443
|
</SelectTrigger>
|
|
309
444
|
</FormControl>
|
|
@@ -328,7 +463,7 @@ function NovoTituloSheet({
|
|
|
328
463
|
<FormLabel>{t('fields.paymentMethod')}</FormLabel>
|
|
329
464
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
330
465
|
<FormControl>
|
|
331
|
-
<SelectTrigger>
|
|
466
|
+
<SelectTrigger className="w-full">
|
|
332
467
|
<SelectValue placeholder={t('common.select')} />
|
|
333
468
|
</SelectTrigger>
|
|
334
469
|
</FormControl>
|
|
@@ -285,37 +285,64 @@ function NovaContaSheet({
|
|
|
285
285
|
/>
|
|
286
286
|
</div>
|
|
287
287
|
|
|
288
|
-
<
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
<
|
|
294
|
-
|
|
288
|
+
<div className="grid grid-cols-2 gap-4">
|
|
289
|
+
<FormField
|
|
290
|
+
control={form.control}
|
|
291
|
+
name="tipo"
|
|
292
|
+
render={({ field }) => (
|
|
293
|
+
<FormItem>
|
|
294
|
+
<FormLabel>{t('fields.type')}</FormLabel>
|
|
295
|
+
<Select
|
|
296
|
+
value={field.value}
|
|
297
|
+
onValueChange={field.onChange}
|
|
298
|
+
>
|
|
299
|
+
<FormControl>
|
|
300
|
+
<SelectTrigger className="w-full">
|
|
301
|
+
<SelectValue placeholder={t('common.select')} />
|
|
302
|
+
</SelectTrigger>
|
|
303
|
+
</FormControl>
|
|
304
|
+
<SelectContent>
|
|
305
|
+
<SelectItem value="corrente">
|
|
306
|
+
{t('types.corrente')}
|
|
307
|
+
</SelectItem>
|
|
308
|
+
<SelectItem value="poupanca">
|
|
309
|
+
{t('types.poupanca')}
|
|
310
|
+
</SelectItem>
|
|
311
|
+
<SelectItem value="investimento">
|
|
312
|
+
{t('types.investimento')}
|
|
313
|
+
</SelectItem>
|
|
314
|
+
<SelectItem value="caixa">
|
|
315
|
+
{t('types.caixa')}
|
|
316
|
+
</SelectItem>
|
|
317
|
+
</SelectContent>
|
|
318
|
+
</Select>
|
|
319
|
+
<FormMessage />
|
|
320
|
+
</FormItem>
|
|
321
|
+
)}
|
|
322
|
+
/>
|
|
323
|
+
|
|
324
|
+
<FormField
|
|
325
|
+
control={form.control}
|
|
326
|
+
name="saldoInicial"
|
|
327
|
+
render={({ field }) => (
|
|
328
|
+
<FormItem>
|
|
329
|
+
<FormLabel>{t('fields.initialBalance')}</FormLabel>
|
|
295
330
|
<FormControl>
|
|
296
|
-
<
|
|
297
|
-
|
|
298
|
-
|
|
331
|
+
<InputMoney
|
|
332
|
+
ref={field.ref}
|
|
333
|
+
name={field.name}
|
|
334
|
+
value={field.value}
|
|
335
|
+
onBlur={field.onBlur}
|
|
336
|
+
onValueChange={(value) => field.onChange(value ?? 0)}
|
|
337
|
+
placeholder="0,00"
|
|
338
|
+
disabled={!!editingAccount}
|
|
339
|
+
/>
|
|
299
340
|
</FormControl>
|
|
300
|
-
<
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
{t('types.poupanca')}
|
|
306
|
-
</SelectItem>
|
|
307
|
-
<SelectItem value="investimento">
|
|
308
|
-
{t('types.investimento')}
|
|
309
|
-
</SelectItem>
|
|
310
|
-
<SelectItem value="caixa">
|
|
311
|
-
{t('types.caixa')}
|
|
312
|
-
</SelectItem>
|
|
313
|
-
</SelectContent>
|
|
314
|
-
</Select>
|
|
315
|
-
<FormMessage />
|
|
316
|
-
</FormItem>
|
|
317
|
-
)}
|
|
318
|
-
/>
|
|
341
|
+
<FormMessage />
|
|
342
|
+
</FormItem>
|
|
343
|
+
)}
|
|
344
|
+
/>
|
|
345
|
+
</div>
|
|
319
346
|
|
|
320
347
|
<FormField
|
|
321
348
|
control={form.control}
|
|
@@ -334,28 +361,6 @@ function NovaContaSheet({
|
|
|
334
361
|
</FormItem>
|
|
335
362
|
)}
|
|
336
363
|
/>
|
|
337
|
-
|
|
338
|
-
<FormField
|
|
339
|
-
control={form.control}
|
|
340
|
-
name="saldoInicial"
|
|
341
|
-
render={({ field }) => (
|
|
342
|
-
<FormItem>
|
|
343
|
-
<FormLabel>{t('fields.initialBalance')}</FormLabel>
|
|
344
|
-
<FormControl>
|
|
345
|
-
<InputMoney
|
|
346
|
-
ref={field.ref}
|
|
347
|
-
name={field.name}
|
|
348
|
-
value={field.value}
|
|
349
|
-
onBlur={field.onBlur}
|
|
350
|
-
onValueChange={(value) => field.onChange(value ?? 0)}
|
|
351
|
-
placeholder="0,00"
|
|
352
|
-
disabled={!!editingAccount}
|
|
353
|
-
/>
|
|
354
|
-
</FormControl>
|
|
355
|
-
<FormMessage />
|
|
356
|
-
</FormItem>
|
|
357
|
-
)}
|
|
358
|
-
/>
|
|
359
364
|
</div>
|
|
360
365
|
|
|
361
366
|
<div className="flex justify-end gap-2 pt-4">
|
|
@@ -412,6 +417,7 @@ export default function ContasBancariasPage() {
|
|
|
412
417
|
},
|
|
413
418
|
placeholderData: [],
|
|
414
419
|
});
|
|
420
|
+
const accounts = contasBancarias ?? [];
|
|
415
421
|
|
|
416
422
|
const tipoConfig = {
|
|
417
423
|
corrente: { label: t('types.corrente'), icon: Building2 },
|
|
@@ -420,11 +426,11 @@ export default function ContasBancariasPage() {
|
|
|
420
426
|
caixa: { label: t('types.caixa'), icon: Wallet },
|
|
421
427
|
};
|
|
422
428
|
|
|
423
|
-
const saldoTotal =
|
|
429
|
+
const saldoTotal = accounts
|
|
424
430
|
.filter((c) => c.ativo)
|
|
425
431
|
.reduce((acc, c) => acc + c.saldoAtual, 0);
|
|
426
432
|
|
|
427
|
-
const saldoConciliadoTotal =
|
|
433
|
+
const saldoConciliadoTotal = accounts
|
|
428
434
|
.filter((c) => c.ativo)
|
|
429
435
|
.reduce((acc, c) => acc + c.saldoConciliado, 0);
|
|
430
436
|
|
|
@@ -522,7 +528,7 @@ export default function ContasBancariasPage() {
|
|
|
522
528
|
</div>
|
|
523
529
|
<p className="text-xs text-muted-foreground">
|
|
524
530
|
{t('cards.activeAccounts', {
|
|
525
|
-
count:
|
|
531
|
+
count: accounts.filter((c) => c.ativo).length,
|
|
526
532
|
})}
|
|
527
533
|
</p>
|
|
528
534
|
</CardContent>
|
|
@@ -547,7 +553,7 @@ export default function ContasBancariasPage() {
|
|
|
547
553
|
</div>
|
|
548
554
|
|
|
549
555
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
550
|
-
{
|
|
556
|
+
{accounts.map((conta) => {
|
|
551
557
|
const tipo =
|
|
552
558
|
tipoConfig[conta.tipo as keyof typeof tipoConfig] ||
|
|
553
559
|
tipoConfig.corrente;
|
|
@@ -563,14 +569,25 @@ export default function ContasBancariasPage() {
|
|
|
563
569
|
<TipoIcon className="h-5 w-5" />
|
|
564
570
|
</div>
|
|
565
571
|
<div>
|
|
566
|
-
<
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
572
|
+
<div className="flex gap-4 items-center">
|
|
573
|
+
<CardTitle className="text-base">
|
|
574
|
+
{conta.banco}
|
|
575
|
+
</CardTitle>
|
|
576
|
+
{conta.descricao && (
|
|
577
|
+
<span className="block text-muted-foreground text-xs">
|
|
578
|
+
{conta.descricao}
|
|
579
|
+
</span>
|
|
580
|
+
)}
|
|
581
|
+
</div>
|
|
582
|
+
<CardDescription className="space-y-0.5">
|
|
583
|
+
{conta.agencia !== '-' && (
|
|
584
|
+
<span className="block">
|
|
585
|
+
{t('accountCard.bankAccount', {
|
|
570
586
|
agency: conta.agencia,
|
|
571
587
|
account: conta.conta,
|
|
572
|
-
})
|
|
573
|
-
|
|
588
|
+
})}
|
|
589
|
+
</span>
|
|
590
|
+
)}
|
|
574
591
|
</CardDescription>
|
|
575
592
|
</div>
|
|
576
593
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/finance",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.232",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"@hed-hog/api-locale": "0.0.11",
|
|
13
13
|
"@hed-hog/api-prisma": "0.0.4",
|
|
14
14
|
"@hed-hog/api-pagination": "0.0.5",
|
|
15
|
-
"@hed-hog/tag": "0.0.223",
|
|
16
|
-
"@hed-hog/api": "0.0.3",
|
|
17
15
|
"@hed-hog/api-types": "0.0.1",
|
|
18
|
-
"@hed-hog/
|
|
16
|
+
"@hed-hog/api": "0.0.3",
|
|
17
|
+
"@hed-hog/tag": "0.0.232",
|
|
18
|
+
"@hed-hog/contact": "0.0.232"
|
|
19
19
|
},
|
|
20
20
|
"exports": {
|
|
21
21
|
".": {
|
|
@@ -139,4 +139,16 @@ export class CreateFinancialTitleDto {
|
|
|
139
139
|
@ValidateNested({ each: true })
|
|
140
140
|
@Type(() => CreateFinancialInstallmentDto)
|
|
141
141
|
installments?: CreateFinancialInstallmentDto[];
|
|
142
|
+
|
|
143
|
+
@IsOptional()
|
|
144
|
+
@IsArray({
|
|
145
|
+
message: (args) =>
|
|
146
|
+
getLocaleText('validation.attachmentFileIdsMustBeArray', args.value),
|
|
147
|
+
})
|
|
148
|
+
@IsInt({
|
|
149
|
+
each: true,
|
|
150
|
+
message: (args) =>
|
|
151
|
+
getLocaleText('validation.attachmentFileIdMustBeNumber', args.value),
|
|
152
|
+
})
|
|
153
|
+
attachment_file_ids?: number[];
|
|
142
154
|
}
|