@hed-hog/finance 0.0.235 → 0.0.237
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-cost-center.dto.d.ts +4 -0
- package/dist/dto/create-cost-center.dto.d.ts.map +1 -0
- package/dist/dto/create-cost-center.dto.js +24 -0
- package/dist/dto/create-cost-center.dto.js.map +1 -0
- package/dist/dto/create-finance-category.dto.d.ts +6 -0
- package/dist/dto/create-finance-category.dto.d.ts.map +1 -0
- package/dist/dto/create-finance-category.dto.js +37 -0
- package/dist/dto/create-finance-category.dto.js.map +1 -0
- package/dist/dto/create-period-close.dto.d.ts +7 -0
- package/dist/dto/create-period-close.dto.d.ts.map +1 -0
- package/dist/dto/create-period-close.dto.js +44 -0
- package/dist/dto/create-period-close.dto.js.map +1 -0
- package/dist/dto/move-finance-category.dto.d.ts +5 -0
- package/dist/dto/move-finance-category.dto.d.ts.map +1 -0
- package/dist/dto/move-finance-category.dto.js +32 -0
- package/dist/dto/move-finance-category.dto.js.map +1 -0
- package/dist/dto/update-cost-center.dto.d.ts +5 -0
- package/dist/dto/update-cost-center.dto.d.ts.map +1 -0
- package/dist/dto/update-cost-center.dto.js +32 -0
- package/dist/dto/update-cost-center.dto.js.map +1 -0
- package/dist/dto/update-finance-category.dto.d.ts +7 -0
- package/dist/dto/update-finance-category.dto.d.ts.map +1 -0
- package/dist/dto/update-finance-category.dto.js +46 -0
- package/dist/dto/update-finance-category.dto.js.map +1 -0
- package/dist/finance-audit-logs.controller.d.ts +13 -0
- package/dist/finance-audit-logs.controller.d.ts.map +1 -0
- package/dist/finance-audit-logs.controller.js +54 -0
- package/dist/finance-audit-logs.controller.js.map +1 -0
- package/dist/finance-categories.controller.d.ts +42 -0
- package/dist/finance-categories.controller.d.ts.map +1 -0
- package/dist/finance-categories.controller.js +84 -0
- package/dist/finance-categories.controller.js.map +1 -0
- package/dist/finance-cost-centers.controller.d.ts +32 -0
- package/dist/finance-cost-centers.controller.d.ts.map +1 -0
- package/dist/finance-cost-centers.controller.js +72 -0
- package/dist/finance-cost-centers.controller.js.map +1 -0
- package/dist/finance-period-close.controller.d.ts +27 -0
- package/dist/finance-period-close.controller.d.ts.map +1 -0
- package/dist/finance-period-close.controller.js +64 -0
- package/dist/finance-period-close.controller.js.map +1 -0
- package/dist/finance.module.d.ts.map +1 -1
- package/dist/finance.module.js +8 -0
- package/dist/finance.module.js.map +1 -1
- package/dist/finance.service.d.ts +111 -0
- package/dist/finance.service.d.ts.map +1 -1
- package/dist/finance.service.js +446 -17
- package/dist/finance.service.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/hedhog/data/route.yaml +108 -0
- package/hedhog/frontend/app/_components/person-field-with-create.tsx.ejs +627 -0
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +865 -883
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +838 -861
- package/hedhog/frontend/app/administration/audit-logs/page.tsx.ejs +309 -0
- package/hedhog/frontend/app/administration/categories/page.tsx.ejs +725 -0
- package/hedhog/frontend/app/administration/cost-centers/page.tsx.ejs +378 -0
- package/hedhog/frontend/app/administration/period-close/page.tsx.ejs +502 -0
- package/hedhog/frontend/messages/en.json +225 -0
- package/hedhog/frontend/messages/pt.json +225 -0
- package/package.json +5 -5
- package/src/dto/create-cost-center.dto.ts +9 -0
- package/src/dto/create-finance-category.dto.ts +21 -0
- package/src/dto/create-period-close.dto.ts +34 -0
- package/src/dto/move-finance-category.dto.ts +18 -0
- package/src/dto/update-cost-center.dto.ts +17 -0
- package/src/dto/update-finance-category.dto.ts +30 -0
- package/src/finance-audit-logs.controller.ts +30 -0
- package/src/finance-categories.controller.ts +52 -0
- package/src/finance-cost-centers.controller.ts +43 -0
- package/src/finance-period-close.controller.ts +34 -0
- package/src/finance.module.ts +8 -0
- package/src/finance.service.ts +578 -9
- package/src/index.ts +4 -0
package/dist/finance.service.js
CHANGED
|
@@ -572,6 +572,159 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
572
572
|
});
|
|
573
573
|
return bankAccounts.map((bankAccount) => this.mapBankAccountToFront(bankAccount));
|
|
574
574
|
}
|
|
575
|
+
async listCostCenters() {
|
|
576
|
+
const costCenters = await this.prisma.cost_center.findMany({
|
|
577
|
+
orderBy: [{ code: 'asc' }, { name: 'asc' }],
|
|
578
|
+
});
|
|
579
|
+
return costCenters.map((costCenter) => this.mapCostCenterToFront(costCenter));
|
|
580
|
+
}
|
|
581
|
+
async listAuditLogs(paginationParams, filters) {
|
|
582
|
+
var _a;
|
|
583
|
+
const actorUserId = (filters === null || filters === void 0 ? void 0 : filters.actor_user_id)
|
|
584
|
+
? Number.parseInt(filters.actor_user_id, 10)
|
|
585
|
+
: undefined;
|
|
586
|
+
const fromDate = (filters === null || filters === void 0 ? void 0 : filters.from) ? new Date(filters.from) : undefined;
|
|
587
|
+
const toDate = (filters === null || filters === void 0 ? void 0 : filters.to) ? new Date(filters.to) : undefined;
|
|
588
|
+
const where = Object.assign(Object.assign(Object.assign(Object.assign({}, ((filters === null || filters === void 0 ? void 0 : filters.action) ? { action: filters.action } : {})), ((filters === null || filters === void 0 ? void 0 : filters.entity_table) ? { entity_table: filters.entity_table } : {})), (Number.isNaN(actorUserId) || !actorUserId
|
|
589
|
+
? {}
|
|
590
|
+
: { actor_user_id: actorUserId })), ((fromDate || toDate) &&
|
|
591
|
+
!(fromDate && Number.isNaN(fromDate.getTime())) &&
|
|
592
|
+
!(toDate && Number.isNaN(toDate.getTime()))
|
|
593
|
+
? {
|
|
594
|
+
created_at: Object.assign(Object.assign({}, (fromDate ? { gte: fromDate } : {})), (toDate ? { lte: toDate } : {})),
|
|
595
|
+
}
|
|
596
|
+
: {}));
|
|
597
|
+
const search = (_a = filters === null || filters === void 0 ? void 0 : filters.search) === null || _a === void 0 ? void 0 : _a.trim();
|
|
598
|
+
if (search) {
|
|
599
|
+
where.OR = [
|
|
600
|
+
{ action: { contains: search, mode: 'insensitive' } },
|
|
601
|
+
{ entity_table: { contains: search, mode: 'insensitive' } },
|
|
602
|
+
{ entity_id: { contains: search, mode: 'insensitive' } },
|
|
603
|
+
{ summary: { contains: search, mode: 'insensitive' } },
|
|
604
|
+
{ ip_address: { contains: search, mode: 'insensitive' } },
|
|
605
|
+
];
|
|
606
|
+
}
|
|
607
|
+
const paginated = await this.paginationService.paginatePrismaModel(this.prisma.audit_log, {
|
|
608
|
+
page: paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.page,
|
|
609
|
+
pageSize: paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.pageSize,
|
|
610
|
+
sortField: (paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.sortField) || 'created_at',
|
|
611
|
+
sortOrder: (paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.sortOrder) || 'desc',
|
|
612
|
+
validSortFields: [
|
|
613
|
+
'id',
|
|
614
|
+
'created_at',
|
|
615
|
+
'action',
|
|
616
|
+
'entity_table',
|
|
617
|
+
'entity_id',
|
|
618
|
+
],
|
|
619
|
+
where,
|
|
620
|
+
include: {
|
|
621
|
+
user: {
|
|
622
|
+
select: {
|
|
623
|
+
id: true,
|
|
624
|
+
name: true,
|
|
625
|
+
},
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
});
|
|
629
|
+
return Object.assign(Object.assign({}, paginated), { data: (paginated.data || []).map((log) => {
|
|
630
|
+
var _a, _b, _c;
|
|
631
|
+
return ({
|
|
632
|
+
id: String(log.id),
|
|
633
|
+
actorUserId: log.actor_user_id ? String(log.actor_user_id) : null,
|
|
634
|
+
actorName: ((_a = log.user) === null || _a === void 0 ? void 0 : _a.name) || '-',
|
|
635
|
+
actorEmail: '',
|
|
636
|
+
action: log.action,
|
|
637
|
+
entityTable: log.entity_table,
|
|
638
|
+
entityId: log.entity_id,
|
|
639
|
+
summary: log.summary || '',
|
|
640
|
+
ipAddress: log.ip_address || '',
|
|
641
|
+
beforeData: log.before_data || '',
|
|
642
|
+
afterData: log.after_data || '',
|
|
643
|
+
createdAt: ((_c = (_b = log.created_at) === null || _b === void 0 ? void 0 : _b.toISOString) === null || _c === void 0 ? void 0 : _c.call(_b)) || null,
|
|
644
|
+
});
|
|
645
|
+
}) });
|
|
646
|
+
}
|
|
647
|
+
async listFinanceCategories() {
|
|
648
|
+
const categories = await this.prisma.finance_category.findMany({
|
|
649
|
+
orderBy: [{ parent_id: 'asc' }, { updated_at: 'asc' }, { name: 'asc' }],
|
|
650
|
+
});
|
|
651
|
+
return categories.map((category) => this.mapFinanceCategoryToFront(category));
|
|
652
|
+
}
|
|
653
|
+
async listPeriodClose(paginationParams, filters) {
|
|
654
|
+
var _a, _b;
|
|
655
|
+
const fromDate = (filters === null || filters === void 0 ? void 0 : filters.from) ? new Date(filters.from) : undefined;
|
|
656
|
+
const toDate = (filters === null || filters === void 0 ? void 0 : filters.to) ? new Date(filters.to) : undefined;
|
|
657
|
+
const userNumericId = (filters === null || filters === void 0 ? void 0 : filters.user)
|
|
658
|
+
? Number.parseInt(filters.user, 10)
|
|
659
|
+
: undefined;
|
|
660
|
+
const andConditions = [];
|
|
661
|
+
if ((filters === null || filters === void 0 ? void 0 : filters.status) && filters.status !== 'all') {
|
|
662
|
+
andConditions.push({ status: filters.status });
|
|
663
|
+
}
|
|
664
|
+
if ((fromDate && !Number.isNaN(fromDate.getTime())) ||
|
|
665
|
+
(toDate && !Number.isNaN(toDate.getTime()))) {
|
|
666
|
+
andConditions.push({
|
|
667
|
+
period_start: Object.assign({}, (fromDate && !Number.isNaN(fromDate.getTime())
|
|
668
|
+
? { gte: fromDate }
|
|
669
|
+
: {})),
|
|
670
|
+
});
|
|
671
|
+
andConditions.push({
|
|
672
|
+
period_end: Object.assign({}, (toDate && !Number.isNaN(toDate.getTime()) ? { lte: toDate } : {})),
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
const search = (_a = filters === null || filters === void 0 ? void 0 : filters.search) === null || _a === void 0 ? void 0 : _a.trim();
|
|
676
|
+
if (search) {
|
|
677
|
+
andConditions.push({
|
|
678
|
+
OR: [
|
|
679
|
+
{ notes: { contains: search, mode: 'insensitive' } },
|
|
680
|
+
{ user: { is: { name: { contains: search, mode: 'insensitive' } } } },
|
|
681
|
+
{
|
|
682
|
+
user: { is: { email: { contains: search, mode: 'insensitive' } } },
|
|
683
|
+
},
|
|
684
|
+
],
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
if ((_b = filters === null || filters === void 0 ? void 0 : filters.user) === null || _b === void 0 ? void 0 : _b.trim()) {
|
|
688
|
+
andConditions.push({
|
|
689
|
+
OR: [
|
|
690
|
+
...(Number.isNaN(userNumericId) || !userNumericId
|
|
691
|
+
? []
|
|
692
|
+
: [{ closed_by_user_id: userNumericId }]),
|
|
693
|
+
{ user: { is: { name: { contains: filters.user, mode: 'insensitive' } } } },
|
|
694
|
+
{
|
|
695
|
+
user: {
|
|
696
|
+
is: { email: { contains: filters.user, mode: 'insensitive' } },
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
],
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
const where = andConditions.length > 0 ? { AND: andConditions } : {};
|
|
703
|
+
const paginated = await this.paginationService.paginatePrismaModel(this.prisma.period_close, {
|
|
704
|
+
page: paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.page,
|
|
705
|
+
pageSize: paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.pageSize,
|
|
706
|
+
sortField: (paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.sortField) || 'period_start',
|
|
707
|
+
sortOrder: (paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.sortOrder) || 'desc',
|
|
708
|
+
validSortFields: [
|
|
709
|
+
'id',
|
|
710
|
+
'period_start',
|
|
711
|
+
'period_end',
|
|
712
|
+
'status',
|
|
713
|
+
'closed_at',
|
|
714
|
+
'created_at',
|
|
715
|
+
],
|
|
716
|
+
where,
|
|
717
|
+
include: {
|
|
718
|
+
user: {
|
|
719
|
+
select: {
|
|
720
|
+
id: true,
|
|
721
|
+
name: true,
|
|
722
|
+
},
|
|
723
|
+
},
|
|
724
|
+
},
|
|
725
|
+
});
|
|
726
|
+
return Object.assign(Object.assign({}, paginated), { data: (paginated.data || []).map((period) => this.mapPeriodCloseToFront(period)) });
|
|
727
|
+
}
|
|
575
728
|
async listBankStatements(bankAccountId) {
|
|
576
729
|
const statements = await this.prisma.bank_statement_line.findMany({
|
|
577
730
|
where: Object.assign({}, (bankAccountId ? { bank_account_id: bankAccountId } : {})),
|
|
@@ -644,6 +797,74 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
644
797
|
});
|
|
645
798
|
return this.mapBankAccountToFront(account);
|
|
646
799
|
}
|
|
800
|
+
async createCostCenter(data) {
|
|
801
|
+
const code = await this.generateCostCenterCode(data.name);
|
|
802
|
+
const created = await this.prisma.cost_center.create({
|
|
803
|
+
data: {
|
|
804
|
+
code,
|
|
805
|
+
name: data.name.trim(),
|
|
806
|
+
status: 'active',
|
|
807
|
+
},
|
|
808
|
+
});
|
|
809
|
+
return this.mapCostCenterToFront(created);
|
|
810
|
+
}
|
|
811
|
+
async createFinanceCategory(data) {
|
|
812
|
+
if (data.parent_id) {
|
|
813
|
+
await this.ensureFinanceCategoryExists(data.parent_id);
|
|
814
|
+
}
|
|
815
|
+
const created = await this.prisma.finance_category.create({
|
|
816
|
+
data: {
|
|
817
|
+
code: await this.generateFinanceCategoryCode(),
|
|
818
|
+
name: data.name.trim(),
|
|
819
|
+
kind: this.mapCategoryKindFromPt(data.kind),
|
|
820
|
+
status: 'active',
|
|
821
|
+
parent_id: data.parent_id || null,
|
|
822
|
+
},
|
|
823
|
+
});
|
|
824
|
+
return this.mapFinanceCategoryToFront(created);
|
|
825
|
+
}
|
|
826
|
+
async createPeriodClose(data, userId) {
|
|
827
|
+
var _a;
|
|
828
|
+
const periodStart = new Date(data.period_start);
|
|
829
|
+
const periodEnd = new Date(data.period_end);
|
|
830
|
+
if (Number.isNaN(periodStart.getTime()) ||
|
|
831
|
+
Number.isNaN(periodEnd.getTime())) {
|
|
832
|
+
throw new common_1.BadRequestException('Invalid period dates');
|
|
833
|
+
}
|
|
834
|
+
if (periodStart > periodEnd) {
|
|
835
|
+
throw new common_1.BadRequestException('period_start must be before period_end');
|
|
836
|
+
}
|
|
837
|
+
const overlapped = await this.prisma.period_close.findFirst({
|
|
838
|
+
where: {
|
|
839
|
+
period_start: { lte: periodEnd },
|
|
840
|
+
period_end: { gte: periodStart },
|
|
841
|
+
},
|
|
842
|
+
select: { id: true },
|
|
843
|
+
});
|
|
844
|
+
if (overlapped) {
|
|
845
|
+
throw new common_1.BadRequestException('There is already a period in this range');
|
|
846
|
+
}
|
|
847
|
+
const status = data.status || 'closed';
|
|
848
|
+
const created = await this.prisma.period_close.create({
|
|
849
|
+
data: {
|
|
850
|
+
period_start: periodStart,
|
|
851
|
+
period_end: periodEnd,
|
|
852
|
+
status,
|
|
853
|
+
closed_at: status === 'closed' ? new Date() : null,
|
|
854
|
+
closed_by_user_id: status === 'closed' ? userId || null : null,
|
|
855
|
+
notes: ((_a = data.notes) === null || _a === void 0 ? void 0 : _a.trim()) || null,
|
|
856
|
+
},
|
|
857
|
+
include: {
|
|
858
|
+
user: {
|
|
859
|
+
select: {
|
|
860
|
+
id: true,
|
|
861
|
+
name: true,
|
|
862
|
+
},
|
|
863
|
+
},
|
|
864
|
+
},
|
|
865
|
+
});
|
|
866
|
+
return this.mapPeriodCloseToFront(created);
|
|
867
|
+
}
|
|
647
868
|
async updateBankAccount(id, data) {
|
|
648
869
|
const current = await this.prisma.bank_account.findUnique({
|
|
649
870
|
where: { id },
|
|
@@ -673,6 +894,82 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
673
894
|
});
|
|
674
895
|
return this.mapBankAccountToFront(updated);
|
|
675
896
|
}
|
|
897
|
+
async updateCostCenter(id, data) {
|
|
898
|
+
var _a;
|
|
899
|
+
const current = await this.prisma.cost_center.findUnique({
|
|
900
|
+
where: { id },
|
|
901
|
+
select: { id: true },
|
|
902
|
+
});
|
|
903
|
+
if (!current) {
|
|
904
|
+
throw new common_1.NotFoundException('Cost center not found');
|
|
905
|
+
}
|
|
906
|
+
const updated = await this.prisma.cost_center.update({
|
|
907
|
+
where: { id },
|
|
908
|
+
data: {
|
|
909
|
+
name: (_a = data.name) === null || _a === void 0 ? void 0 : _a.trim(),
|
|
910
|
+
status: data.status,
|
|
911
|
+
},
|
|
912
|
+
});
|
|
913
|
+
return this.mapCostCenterToFront(updated);
|
|
914
|
+
}
|
|
915
|
+
async updateFinanceCategory(id, data) {
|
|
916
|
+
var _a;
|
|
917
|
+
const current = await this.prisma.finance_category.findUnique({
|
|
918
|
+
where: { id },
|
|
919
|
+
select: { id: true },
|
|
920
|
+
});
|
|
921
|
+
if (!current) {
|
|
922
|
+
throw new common_1.NotFoundException('Finance category not found');
|
|
923
|
+
}
|
|
924
|
+
if (data.parent_id) {
|
|
925
|
+
await this.ensureFinanceCategoryExists(data.parent_id);
|
|
926
|
+
await this.ensureNoFinanceCategoryCycle(id, data.parent_id);
|
|
927
|
+
}
|
|
928
|
+
const updated = await this.prisma.finance_category.update({
|
|
929
|
+
where: { id },
|
|
930
|
+
data: {
|
|
931
|
+
name: (_a = data.name) === null || _a === void 0 ? void 0 : _a.trim(),
|
|
932
|
+
kind: data.kind ? this.mapCategoryKindFromPt(data.kind) : undefined,
|
|
933
|
+
parent_id: data.parent_id,
|
|
934
|
+
status: data.status,
|
|
935
|
+
},
|
|
936
|
+
});
|
|
937
|
+
return this.mapFinanceCategoryToFront(updated);
|
|
938
|
+
}
|
|
939
|
+
async moveFinanceCategory(id, data) {
|
|
940
|
+
var _a;
|
|
941
|
+
const current = await this.prisma.finance_category.findUnique({
|
|
942
|
+
where: { id },
|
|
943
|
+
select: { id: true, parent_id: true },
|
|
944
|
+
});
|
|
945
|
+
if (!current) {
|
|
946
|
+
throw new common_1.NotFoundException('Finance category not found');
|
|
947
|
+
}
|
|
948
|
+
const targetParentId = data.parent_id || null;
|
|
949
|
+
if (targetParentId) {
|
|
950
|
+
await this.ensureFinanceCategoryExists(targetParentId);
|
|
951
|
+
await this.ensureNoFinanceCategoryCycle(id, targetParentId);
|
|
952
|
+
}
|
|
953
|
+
await this.prisma.finance_category.update({
|
|
954
|
+
where: { id },
|
|
955
|
+
data: { parent_id: targetParentId },
|
|
956
|
+
});
|
|
957
|
+
const siblings = await this.prisma.finance_category.findMany({
|
|
958
|
+
where: { parent_id: targetParentId },
|
|
959
|
+
select: { id: true },
|
|
960
|
+
orderBy: [{ updated_at: 'asc' }, { name: 'asc' }],
|
|
961
|
+
});
|
|
962
|
+
const siblingIds = siblings.map((item) => item.id).filter((item) => item !== id);
|
|
963
|
+
const targetPosition = Math.max(0, Math.min((_a = data.position) !== null && _a !== void 0 ? _a : siblingIds.length, siblingIds.length));
|
|
964
|
+
siblingIds.splice(targetPosition, 0, id);
|
|
965
|
+
await this.prisma.$transaction(siblingIds.map((categoryId) => this.prisma.finance_category.update({
|
|
966
|
+
where: { id: categoryId },
|
|
967
|
+
data: {
|
|
968
|
+
parent_id: targetParentId,
|
|
969
|
+
},
|
|
970
|
+
})));
|
|
971
|
+
return { success: true };
|
|
972
|
+
}
|
|
676
973
|
async deleteBankAccount(id) {
|
|
677
974
|
const current = await this.prisma.bank_account.findUnique({
|
|
678
975
|
where: { id },
|
|
@@ -689,6 +986,38 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
689
986
|
});
|
|
690
987
|
return { success: true };
|
|
691
988
|
}
|
|
989
|
+
async deleteCostCenter(id) {
|
|
990
|
+
const current = await this.prisma.cost_center.findUnique({
|
|
991
|
+
where: { id },
|
|
992
|
+
select: { id: true },
|
|
993
|
+
});
|
|
994
|
+
if (!current) {
|
|
995
|
+
throw new common_1.NotFoundException('Cost center not found');
|
|
996
|
+
}
|
|
997
|
+
await this.prisma.cost_center.update({
|
|
998
|
+
where: { id },
|
|
999
|
+
data: {
|
|
1000
|
+
status: 'inactive',
|
|
1001
|
+
},
|
|
1002
|
+
});
|
|
1003
|
+
return { success: true };
|
|
1004
|
+
}
|
|
1005
|
+
async deleteFinanceCategory(id) {
|
|
1006
|
+
const current = await this.prisma.finance_category.findUnique({
|
|
1007
|
+
where: { id },
|
|
1008
|
+
select: { id: true },
|
|
1009
|
+
});
|
|
1010
|
+
if (!current) {
|
|
1011
|
+
throw new common_1.NotFoundException('Finance category not found');
|
|
1012
|
+
}
|
|
1013
|
+
await this.prisma.finance_category.update({
|
|
1014
|
+
where: { id },
|
|
1015
|
+
data: {
|
|
1016
|
+
status: 'inactive',
|
|
1017
|
+
},
|
|
1018
|
+
});
|
|
1019
|
+
return { success: true };
|
|
1020
|
+
}
|
|
692
1021
|
async listTitles(titleType, paginationParams, status) {
|
|
693
1022
|
const prismaStatus = this.mapStatusFromPt(status);
|
|
694
1023
|
const where = {
|
|
@@ -807,25 +1136,14 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
807
1136
|
}
|
|
808
1137
|
async loadPeople() {
|
|
809
1138
|
const people = await this.prisma.person.findMany({
|
|
810
|
-
include: {
|
|
811
|
-
document: {
|
|
812
|
-
select: {
|
|
813
|
-
value: true,
|
|
814
|
-
},
|
|
815
|
-
take: 1,
|
|
816
|
-
},
|
|
817
|
-
},
|
|
818
1139
|
orderBy: { name: 'asc' },
|
|
819
1140
|
});
|
|
820
|
-
return people.map((person) => {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
documento: ((_a = person.document[0]) === null || _a === void 0 ? void 0 : _a.value) || '',
|
|
827
|
-
});
|
|
828
|
-
});
|
|
1141
|
+
return people.map((person) => ({
|
|
1142
|
+
id: String(person.id),
|
|
1143
|
+
nome: person.name,
|
|
1144
|
+
tipo: 'ambos',
|
|
1145
|
+
documento: '',
|
|
1146
|
+
}));
|
|
829
1147
|
}
|
|
830
1148
|
async loadCategories() {
|
|
831
1149
|
const categories = await this.prisma.finance_category.findMany({
|
|
@@ -1047,6 +1365,70 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
1047
1365
|
ativo: bankAccount.status === 'active',
|
|
1048
1366
|
};
|
|
1049
1367
|
}
|
|
1368
|
+
mapCostCenterToFront(costCenter) {
|
|
1369
|
+
return {
|
|
1370
|
+
id: String(costCenter.id),
|
|
1371
|
+
codigo: costCenter.code,
|
|
1372
|
+
nome: costCenter.name,
|
|
1373
|
+
status: costCenter.status,
|
|
1374
|
+
ativo: costCenter.status === 'active',
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
mapCategoryKindToPt(kind) {
|
|
1378
|
+
const kindMap = {
|
|
1379
|
+
revenue: 'receita',
|
|
1380
|
+
expense: 'despesa',
|
|
1381
|
+
transfer: 'transferencia',
|
|
1382
|
+
adjustment: 'ajuste',
|
|
1383
|
+
other: 'outro',
|
|
1384
|
+
};
|
|
1385
|
+
return kindMap[kind] || 'outro';
|
|
1386
|
+
}
|
|
1387
|
+
mapCategoryKindFromPt(kind) {
|
|
1388
|
+
const normalized = (kind || '').toLowerCase();
|
|
1389
|
+
const kindMap = {
|
|
1390
|
+
receita: 'revenue',
|
|
1391
|
+
revenue: 'revenue',
|
|
1392
|
+
despesa: 'expense',
|
|
1393
|
+
expense: 'expense',
|
|
1394
|
+
transferencia: 'transfer',
|
|
1395
|
+
transferência: 'transfer',
|
|
1396
|
+
transfer: 'transfer',
|
|
1397
|
+
ajuste: 'adjustment',
|
|
1398
|
+
adjustment: 'adjustment',
|
|
1399
|
+
outro: 'other',
|
|
1400
|
+
other: 'other',
|
|
1401
|
+
};
|
|
1402
|
+
return kindMap[normalized] || 'other';
|
|
1403
|
+
}
|
|
1404
|
+
mapFinanceCategoryToFront(category) {
|
|
1405
|
+
return {
|
|
1406
|
+
id: String(category.id),
|
|
1407
|
+
codigo: category.code,
|
|
1408
|
+
nome: category.name,
|
|
1409
|
+
parentId: category.parent_id ? String(category.parent_id) : null,
|
|
1410
|
+
natureza: this.mapCategoryKindToPt(category.kind),
|
|
1411
|
+
status: category.status,
|
|
1412
|
+
ativo: category.status === 'active',
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
mapPeriodCloseToFront(period) {
|
|
1416
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1417
|
+
return {
|
|
1418
|
+
id: String(period.id),
|
|
1419
|
+
periodStart: ((_b = (_a = period.period_start) === null || _a === void 0 ? void 0 : _a.toISOString) === null || _b === void 0 ? void 0 : _b.call(_a)) || null,
|
|
1420
|
+
periodEnd: ((_d = (_c = period.period_end) === null || _c === void 0 ? void 0 : _c.toISOString) === null || _d === void 0 ? void 0 : _d.call(_c)) || null,
|
|
1421
|
+
status: period.status,
|
|
1422
|
+
closedAt: ((_f = (_e = period.closed_at) === null || _e === void 0 ? void 0 : _e.toISOString) === null || _f === void 0 ? void 0 : _f.call(_e)) || null,
|
|
1423
|
+
closedByUserId: period.closed_by_user_id
|
|
1424
|
+
? String(period.closed_by_user_id)
|
|
1425
|
+
: null,
|
|
1426
|
+
closedByName: ((_g = period.user) === null || _g === void 0 ? void 0 : _g.name) || '-',
|
|
1427
|
+
closedByEmail: '',
|
|
1428
|
+
notes: period.notes || '',
|
|
1429
|
+
createdAt: ((_j = (_h = period.created_at) === null || _h === void 0 ? void 0 : _h.toISOString) === null || _j === void 0 ? void 0 : _j.call(_h)) || null,
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1050
1432
|
mapStatementStatusToPt(status) {
|
|
1051
1433
|
const statusMap = {
|
|
1052
1434
|
pending: 'pendente',
|
|
@@ -1067,6 +1449,53 @@ let FinanceService = FinanceService_1 = class FinanceService {
|
|
|
1067
1449
|
.padStart(4, '0');
|
|
1068
1450
|
return `${bankPrefix || 'ACC'}-${accountSuffix}`;
|
|
1069
1451
|
}
|
|
1452
|
+
async generateCostCenterCode(name) {
|
|
1453
|
+
const sanitizedName = (name || 'CENTRO')
|
|
1454
|
+
.trim()
|
|
1455
|
+
.replace(/\s+/g, '-')
|
|
1456
|
+
.replace(/[^A-Za-z0-9-]/g, '')
|
|
1457
|
+
.toUpperCase();
|
|
1458
|
+
const basePrefix = sanitizedName.slice(0, 8) || 'CENTRO';
|
|
1459
|
+
const lastCostCenter = await this.prisma.cost_center.findFirst({
|
|
1460
|
+
orderBy: { id: 'desc' },
|
|
1461
|
+
select: { id: true },
|
|
1462
|
+
});
|
|
1463
|
+
const suffix = String(((lastCostCenter === null || lastCostCenter === void 0 ? void 0 : lastCostCenter.id) || 0) + 1).padStart(4, '0');
|
|
1464
|
+
return `${basePrefix}-${suffix}`;
|
|
1465
|
+
}
|
|
1466
|
+
async generateFinanceCategoryCode() {
|
|
1467
|
+
const lastCategory = await this.prisma.finance_category.findFirst({
|
|
1468
|
+
orderBy: { id: 'desc' },
|
|
1469
|
+
select: { id: true },
|
|
1470
|
+
});
|
|
1471
|
+
const suffix = String(((lastCategory === null || lastCategory === void 0 ? void 0 : lastCategory.id) || 0) + 1).padStart(4, '0');
|
|
1472
|
+
return `CAT-${suffix}`;
|
|
1473
|
+
}
|
|
1474
|
+
async ensureFinanceCategoryExists(id) {
|
|
1475
|
+
const category = await this.prisma.finance_category.findUnique({
|
|
1476
|
+
where: { id },
|
|
1477
|
+
select: { id: true },
|
|
1478
|
+
});
|
|
1479
|
+
if (!category) {
|
|
1480
|
+
throw new common_1.NotFoundException('Finance category not found');
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
async ensureNoFinanceCategoryCycle(categoryId, targetParentId) {
|
|
1484
|
+
if (categoryId === targetParentId) {
|
|
1485
|
+
throw new common_1.BadRequestException('Category cannot be parent of itself');
|
|
1486
|
+
}
|
|
1487
|
+
let currentParentId = targetParentId;
|
|
1488
|
+
while (currentParentId) {
|
|
1489
|
+
if (currentParentId === categoryId) {
|
|
1490
|
+
throw new common_1.BadRequestException('Invalid parent category hierarchy');
|
|
1491
|
+
}
|
|
1492
|
+
const parent = await this.prisma.finance_category.findUnique({
|
|
1493
|
+
where: { id: currentParentId },
|
|
1494
|
+
select: { parent_id: true },
|
|
1495
|
+
});
|
|
1496
|
+
currentParentId = (parent === null || parent === void 0 ? void 0 : parent.parent_id) || null;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1070
1499
|
toCents(value) {
|
|
1071
1500
|
return Math.round(value * 100);
|
|
1072
1501
|
}
|