checkpoint: goals feature, wallet balance, and goals/wallet detail UI
- Add goals feature (models, migrations, API, web pages) - Add reserved/centralized wallet balance service - Add wallet detail page and overview components - Add new UI components (progress, multi-select, FAB) - Remove stray empty -H/-d files from working tree
This commit is contained in:
5
apps/api/dist/goals/dto/create-allocation.dto.d.ts
vendored
Executable file
5
apps/api/dist/goals/dto/create-allocation.dto.d.ts
vendored
Executable file
@@ -0,0 +1,5 @@
|
||||
export declare class CreateAllocationDto {
|
||||
walletId: string;
|
||||
amount: number;
|
||||
notes?: string;
|
||||
}
|
||||
35
apps/api/dist/goals/dto/create-allocation.dto.js
vendored
Executable file
35
apps/api/dist/goals/dto/create-allocation.dto.js
vendored
Executable file
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CreateAllocationDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class CreateAllocationDto {
|
||||
walletId;
|
||||
amount;
|
||||
notes;
|
||||
}
|
||||
exports.CreateAllocationDto = CreateAllocationDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsNotEmpty)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateAllocationDto.prototype, "walletId", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsNumber)(),
|
||||
(0, class_validator_1.Min)(0.01),
|
||||
__metadata("design:type", Number)
|
||||
], CreateAllocationDto.prototype, "amount", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateAllocationDto.prototype, "notes", void 0);
|
||||
//# sourceMappingURL=create-allocation.dto.js.map
|
||||
1
apps/api/dist/goals/dto/create-allocation.dto.js.map
vendored
Executable file
1
apps/api/dist/goals/dto/create-allocation.dto.js.map
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create-allocation.dto.js","sourceRoot":"","sources":["../../../src/goals/dto/create-allocation.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAkF;AAElF,MAAa,mBAAmB;IAG9B,QAAQ,CAAS;IAIjB,MAAM,CAAS;IAIf,KAAK,CAAU;CAChB;AAZD,kDAYC;AATC;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;qDACI;AAIjB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,IAAI,CAAC;;mDACK;AAIf;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;kDACE"}
|
||||
9
apps/api/dist/goals/dto/create-goal.dto.d.ts
vendored
Executable file
9
apps/api/dist/goals/dto/create-goal.dto.d.ts
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
export declare class CreateGoalDto {
|
||||
name: string;
|
||||
description?: string;
|
||||
targetAmount: number;
|
||||
currency: string;
|
||||
targetDate?: string;
|
||||
imageUrl?: string;
|
||||
category?: string;
|
||||
}
|
||||
59
apps/api/dist/goals/dto/create-goal.dto.js
vendored
Executable file
59
apps/api/dist/goals/dto/create-goal.dto.js
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CreateGoalDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class CreateGoalDto {
|
||||
name;
|
||||
description;
|
||||
targetAmount;
|
||||
currency;
|
||||
targetDate;
|
||||
imageUrl;
|
||||
category;
|
||||
}
|
||||
exports.CreateGoalDto = CreateGoalDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsNotEmpty)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateGoalDto.prototype, "name", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateGoalDto.prototype, "description", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsNumber)(),
|
||||
(0, class_validator_1.Min)(0),
|
||||
__metadata("design:type", Number)
|
||||
], CreateGoalDto.prototype, "targetAmount", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsNotEmpty)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateGoalDto.prototype, "currency", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsDateString)(),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateGoalDto.prototype, "targetDate", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateGoalDto.prototype, "imageUrl", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateGoalDto.prototype, "category", void 0);
|
||||
//# sourceMappingURL=create-goal.dto.js.map
|
||||
1
apps/api/dist/goals/dto/create-goal.dto.js.map
vendored
Executable file
1
apps/api/dist/goals/dto/create-goal.dto.js.map
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create-goal.dto.js","sourceRoot":"","sources":["../../../src/goals/dto/create-goal.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAgG;AAEhG,MAAa,aAAa;IAGxB,IAAI,CAAS;IAIb,WAAW,CAAU;IAIrB,YAAY,CAAS;IAIrB,QAAQ,CAAS;IAIjB,UAAU,CAAU;IAIpB,QAAQ,CAAU;IAIlB,QAAQ,CAAU;CACnB;AA5BD,sCA4BC;AAzBC;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;2CACA;AAIb;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;kDACQ;AAIrB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,CAAC,CAAC;;mDACc;AAIrB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;+CACI;AAIjB;IAFC,IAAA,8BAAY,GAAE;IACd,IAAA,4BAAU,GAAE;;iDACO;AAIpB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;+CACK;AAIlB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;+CACK"}
|
||||
6
apps/api/dist/goals/dto/update-goal.dto.d.ts
vendored
Executable file
6
apps/api/dist/goals/dto/update-goal.dto.d.ts
vendored
Executable file
@@ -0,0 +1,6 @@
|
||||
import { CreateGoalDto } from './create-goal.dto';
|
||||
declare const UpdateGoalDto_base: import("@nestjs/mapped-types").MappedType<Partial<CreateGoalDto>>;
|
||||
export declare class UpdateGoalDto extends UpdateGoalDto_base {
|
||||
status?: string;
|
||||
}
|
||||
export {};
|
||||
25
apps/api/dist/goals/dto/update-goal.dto.js
vendored
Executable file
25
apps/api/dist/goals/dto/update-goal.dto.js
vendored
Executable file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UpdateGoalDto = void 0;
|
||||
const mapped_types_1 = require("@nestjs/mapped-types");
|
||||
const create_goal_dto_1 = require("./create-goal.dto");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class UpdateGoalDto extends (0, mapped_types_1.PartialType)(create_goal_dto_1.CreateGoalDto) {
|
||||
status;
|
||||
}
|
||||
exports.UpdateGoalDto = UpdateGoalDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateGoalDto.prototype, "status", void 0);
|
||||
//# sourceMappingURL=update-goal.dto.js.map
|
||||
1
apps/api/dist/goals/dto/update-goal.dto.js.map
vendored
Executable file
1
apps/api/dist/goals/dto/update-goal.dto.js.map
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"update-goal.dto.js","sourceRoot":"","sources":["../../../src/goals/dto/update-goal.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uDAAmD;AACnD,uDAAkD;AAClD,qDAAuD;AAEvD,MAAa,aAAc,SAAQ,IAAA,0BAAW,EAAC,+BAAa,CAAC;IAG3D,MAAM,CAAU;CACjB;AAJD,sCAIC;AADC;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;6CACG"}
|
||||
261
apps/api/dist/goals/goals.controller.d.ts
vendored
Executable file
261
apps/api/dist/goals/goals.controller.d.ts
vendored
Executable file
@@ -0,0 +1,261 @@
|
||||
import { GoalsService } from './goals.service';
|
||||
import { CreateGoalDto } from './dto/create-goal.dto';
|
||||
import { UpdateGoalDto } from './dto/update-goal.dto';
|
||||
import { CreateAllocationDto } from './dto/create-allocation.dto';
|
||||
export declare class GoalsController {
|
||||
private readonly goalsService;
|
||||
constructor(goalsService: GoalsService);
|
||||
create(req: any, createGoalDto: CreateGoalDto): Promise<{
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: import("@prisma/client/runtime/library").Decimal | null;
|
||||
pricePerUnit: import("@prisma/client/runtime/library").Decimal | null;
|
||||
reservedBalance: import("@prisma/client/runtime/library").Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: import("@prisma/client/runtime/library").Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: import("@prisma/client/runtime/library").Decimal | null;
|
||||
amountInGoalCurrency: import("@prisma/client/runtime/library").Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
completedAt: Date | null;
|
||||
}>;
|
||||
findAll(req: any, status?: string): Promise<({
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: import("@prisma/client/runtime/library").Decimal | null;
|
||||
pricePerUnit: import("@prisma/client/runtime/library").Decimal | null;
|
||||
reservedBalance: import("@prisma/client/runtime/library").Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: import("@prisma/client/runtime/library").Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: import("@prisma/client/runtime/library").Decimal | null;
|
||||
amountInGoalCurrency: import("@prisma/client/runtime/library").Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
completedAt: Date | null;
|
||||
})[]>;
|
||||
getStats(req: any): Promise<{
|
||||
totalGoals: number;
|
||||
activeGoals: number;
|
||||
completedGoals: number;
|
||||
totalTargetAmount: number;
|
||||
totalCurrentAmount: number;
|
||||
overallProgress: number;
|
||||
}>;
|
||||
findOne(req: any, id: string): Promise<{
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: import("@prisma/client/runtime/library").Decimal | null;
|
||||
pricePerUnit: import("@prisma/client/runtime/library").Decimal | null;
|
||||
reservedBalance: import("@prisma/client/runtime/library").Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: import("@prisma/client/runtime/library").Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: import("@prisma/client/runtime/library").Decimal | null;
|
||||
amountInGoalCurrency: import("@prisma/client/runtime/library").Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
completedAt: Date | null;
|
||||
}>;
|
||||
update(req: any, id: string, updateGoalDto: UpdateGoalDto): Promise<{
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: import("@prisma/client/runtime/library").Decimal | null;
|
||||
pricePerUnit: import("@prisma/client/runtime/library").Decimal | null;
|
||||
reservedBalance: import("@prisma/client/runtime/library").Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: import("@prisma/client/runtime/library").Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: import("@prisma/client/runtime/library").Decimal | null;
|
||||
amountInGoalCurrency: import("@prisma/client/runtime/library").Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: import("@prisma/client/runtime/library").Decimal;
|
||||
completedAt: Date | null;
|
||||
}>;
|
||||
remove(req: any, id: string): Promise<{
|
||||
message: string;
|
||||
}>;
|
||||
addAllocation(req: any, id: string, createAllocationDto: CreateAllocationDto): Promise<{
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: import("@prisma/client/runtime/library").Decimal | null;
|
||||
pricePerUnit: import("@prisma/client/runtime/library").Decimal | null;
|
||||
reservedBalance: import("@prisma/client/runtime/library").Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: import("@prisma/client/runtime/library").Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: import("@prisma/client/runtime/library").Decimal | null;
|
||||
amountInGoalCurrency: import("@prisma/client/runtime/library").Decimal;
|
||||
createdBy: string;
|
||||
}>;
|
||||
removeAllocation(req: any, id: string, allocationId: string): Promise<{
|
||||
message: string;
|
||||
}>;
|
||||
}
|
||||
124
apps/api/dist/goals/goals.controller.js
vendored
Executable file
124
apps/api/dist/goals/goals.controller.js
vendored
Executable file
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GoalsController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const goals_service_1 = require("./goals.service");
|
||||
const create_goal_dto_1 = require("./dto/create-goal.dto");
|
||||
const update_goal_dto_1 = require("./dto/update-goal.dto");
|
||||
const create_allocation_dto_1 = require("./dto/create-allocation.dto");
|
||||
const auth_guard_1 = require("../auth/auth.guard");
|
||||
let GoalsController = class GoalsController {
|
||||
goalsService;
|
||||
constructor(goalsService) {
|
||||
this.goalsService = goalsService;
|
||||
}
|
||||
create(req, createGoalDto) {
|
||||
return this.goalsService.create(req.user.userId, createGoalDto);
|
||||
}
|
||||
findAll(req, status) {
|
||||
return this.goalsService.findAll(req.user.userId, status);
|
||||
}
|
||||
getStats(req) {
|
||||
return this.goalsService.getStats(req.user.userId);
|
||||
}
|
||||
findOne(req, id) {
|
||||
return this.goalsService.findOne(req.user.userId, id);
|
||||
}
|
||||
update(req, id, updateGoalDto) {
|
||||
return this.goalsService.update(req.user.userId, id, updateGoalDto);
|
||||
}
|
||||
remove(req, id) {
|
||||
return this.goalsService.remove(req.user.userId, id);
|
||||
}
|
||||
addAllocation(req, id, createAllocationDto) {
|
||||
return this.goalsService.addAllocation(req.user.userId, id, createAllocationDto);
|
||||
}
|
||||
removeAllocation(req, id, allocationId) {
|
||||
return this.goalsService.removeAllocation(req.user.userId, id, allocationId);
|
||||
}
|
||||
};
|
||||
exports.GoalsController = GoalsController;
|
||||
__decorate([
|
||||
(0, common_1.Post)(),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, create_goal_dto_1.CreateGoalDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "create", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)(),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Query)('status')),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "findAll", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('stats'),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "getStats", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)(':id'),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Param)('id')),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "findOne", null);
|
||||
__decorate([
|
||||
(0, common_1.Patch)(':id'),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Param)('id')),
|
||||
__param(2, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String, update_goal_dto_1.UpdateGoalDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "update", null);
|
||||
__decorate([
|
||||
(0, common_1.Delete)(':id'),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Param)('id')),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "remove", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)(':id/allocations'),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Param)('id')),
|
||||
__param(2, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String, create_allocation_dto_1.CreateAllocationDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "addAllocation", null);
|
||||
__decorate([
|
||||
(0, common_1.Delete)(':id/allocations/:allocationId'),
|
||||
__param(0, (0, common_1.Request)()),
|
||||
__param(1, (0, common_1.Param)('id')),
|
||||
__param(2, (0, common_1.Param)('allocationId')),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], GoalsController.prototype, "removeAllocation", null);
|
||||
exports.GoalsController = GoalsController = __decorate([
|
||||
(0, common_1.Controller)('goals'),
|
||||
(0, common_1.UseGuards)(auth_guard_1.AuthGuard),
|
||||
__metadata("design:paramtypes", [goals_service_1.GoalsService])
|
||||
], GoalsController);
|
||||
//# sourceMappingURL=goals.controller.js.map
|
||||
1
apps/api/dist/goals/goals.controller.js.map
vendored
Executable file
1
apps/api/dist/goals/goals.controller.js.map
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"goals.controller.js","sourceRoot":"","sources":["../../src/goals/goals.controller.ts"],"names":[],"mappings":"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"}
|
||||
2
apps/api/dist/goals/goals.module.d.ts
vendored
Executable file
2
apps/api/dist/goals/goals.module.d.ts
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
export declare class GoalsModule {
|
||||
}
|
||||
26
apps/api/dist/goals/goals.module.js
vendored
Executable file
26
apps/api/dist/goals/goals.module.js
vendored
Executable file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GoalsModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const goals_service_1 = require("./goals.service");
|
||||
const goals_controller_1 = require("./goals.controller");
|
||||
const prisma_module_1 = require("../prisma/prisma.module");
|
||||
const wallets_module_1 = require("../wallets/wallets.module");
|
||||
let GoalsModule = class GoalsModule {
|
||||
};
|
||||
exports.GoalsModule = GoalsModule;
|
||||
exports.GoalsModule = GoalsModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [prisma_module_1.PrismaModule, wallets_module_1.WalletsModule],
|
||||
controllers: [goals_controller_1.GoalsController],
|
||||
providers: [goals_service_1.GoalsService],
|
||||
exports: [goals_service_1.GoalsService],
|
||||
})
|
||||
], GoalsModule);
|
||||
//# sourceMappingURL=goals.module.js.map
|
||||
1
apps/api/dist/goals/goals.module.js.map
vendored
Executable file
1
apps/api/dist/goals/goals.module.js.map
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"goals.module.js","sourceRoot":"","sources":["../../src/goals/goals.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,mDAA+C;AAC/C,yDAAqD;AACrD,2DAAuD;AACvD,8DAA0D;AAQnD,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,kCAAW;sBAAX,WAAW;IANvB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,4BAAY,EAAE,8BAAa,CAAC;QACtC,WAAW,EAAE,CAAC,kCAAe,CAAC;QAC9B,SAAS,EAAE,CAAC,4BAAY,CAAC;QACzB,OAAO,EAAE,CAAC,4BAAY,CAAC;KACxB,CAAC;GACW,WAAW,CAAG"}
|
||||
267
apps/api/dist/goals/goals.service.d.ts
vendored
Executable file
267
apps/api/dist/goals/goals.service.d.ts
vendored
Executable file
@@ -0,0 +1,267 @@
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { WalletBalanceService } from '../wallets/wallet-balance.service';
|
||||
import { CreateGoalDto } from './dto/create-goal.dto';
|
||||
import { UpdateGoalDto } from './dto/update-goal.dto';
|
||||
import { CreateAllocationDto } from './dto/create-allocation.dto';
|
||||
import { Decimal } from '@prisma/client/runtime/library';
|
||||
export declare class GoalsService {
|
||||
private prisma;
|
||||
private walletBalanceService;
|
||||
constructor(prisma: PrismaService, walletBalanceService: WalletBalanceService);
|
||||
create(userId: string, createGoalDto: CreateGoalDto): Promise<{
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: Decimal | null;
|
||||
pricePerUnit: Decimal | null;
|
||||
reservedBalance: Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: Decimal | null;
|
||||
amountInGoalCurrency: Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: Decimal;
|
||||
completedAt: Date | null;
|
||||
}>;
|
||||
findAll(userId: string, status?: string): Promise<({
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: Decimal | null;
|
||||
pricePerUnit: Decimal | null;
|
||||
reservedBalance: Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: Decimal | null;
|
||||
amountInGoalCurrency: Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: Decimal;
|
||||
completedAt: Date | null;
|
||||
})[]>;
|
||||
findOne(userId: string, id: string): Promise<{
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: Decimal | null;
|
||||
pricePerUnit: Decimal | null;
|
||||
reservedBalance: Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: Decimal | null;
|
||||
amountInGoalCurrency: Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: Decimal;
|
||||
completedAt: Date | null;
|
||||
}>;
|
||||
update(userId: string, id: string, updateGoalDto: UpdateGoalDto): Promise<{
|
||||
allocations: ({
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: Decimal | null;
|
||||
pricePerUnit: Decimal | null;
|
||||
reservedBalance: Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: Decimal | null;
|
||||
amountInGoalCurrency: Decimal;
|
||||
createdBy: string;
|
||||
})[];
|
||||
milestones: {
|
||||
id: string;
|
||||
targetAmount: Decimal;
|
||||
percentage: number;
|
||||
goalId: string;
|
||||
achievedAt: Date | null;
|
||||
notifiedAt: Date | null;
|
||||
}[];
|
||||
} & {
|
||||
category: string | null;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
status: string;
|
||||
name: string;
|
||||
userId: string;
|
||||
currency: string;
|
||||
description: string | null;
|
||||
targetAmount: Decimal;
|
||||
targetDate: Date | null;
|
||||
imageUrl: string | null;
|
||||
teamId: string | null;
|
||||
currentAmount: Decimal;
|
||||
completedAt: Date | null;
|
||||
}>;
|
||||
remove(userId: string, id: string): Promise<{
|
||||
message: string;
|
||||
}>;
|
||||
addAllocation(userId: string, goalId: string, createAllocationDto: CreateAllocationDto): Promise<{
|
||||
wallet: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
name: string;
|
||||
userId: string;
|
||||
kind: string;
|
||||
currency: string | null;
|
||||
unit: string | null;
|
||||
deletedAt: Date | null;
|
||||
initialAmount: Decimal | null;
|
||||
pricePerUnit: Decimal | null;
|
||||
reservedBalance: Decimal;
|
||||
};
|
||||
} & {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
currency: string;
|
||||
amount: Decimal;
|
||||
walletId: string;
|
||||
notes: string | null;
|
||||
goalId: string;
|
||||
exchangeRate: Decimal | null;
|
||||
amountInGoalCurrency: Decimal;
|
||||
createdBy: string;
|
||||
}>;
|
||||
removeAllocation(userId: string, goalId: string, allocationId: string): Promise<{
|
||||
message: string;
|
||||
}>;
|
||||
getStats(userId: string): Promise<{
|
||||
totalGoals: number;
|
||||
activeGoals: number;
|
||||
completedGoals: number;
|
||||
totalTargetAmount: number;
|
||||
totalCurrentAmount: number;
|
||||
overallProgress: number;
|
||||
}>;
|
||||
private createMilestones;
|
||||
private updateMilestones;
|
||||
private getExchangeRate;
|
||||
}
|
||||
303
apps/api/dist/goals/goals.service.js
vendored
Executable file
303
apps/api/dist/goals/goals.service.js
vendored
Executable file
@@ -0,0 +1,303 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GoalsService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const prisma_service_1 = require("../prisma/prisma.service");
|
||||
const wallet_balance_service_1 = require("../wallets/wallet-balance.service");
|
||||
const library_1 = require("@prisma/client/runtime/library");
|
||||
let GoalsService = class GoalsService {
|
||||
prisma;
|
||||
walletBalanceService;
|
||||
constructor(prisma, walletBalanceService) {
|
||||
this.prisma = prisma;
|
||||
this.walletBalanceService = walletBalanceService;
|
||||
}
|
||||
async create(userId, createGoalDto) {
|
||||
const goal = await this.prisma.goal.create({
|
||||
data: {
|
||||
userId,
|
||||
name: createGoalDto.name,
|
||||
description: createGoalDto.description,
|
||||
targetAmount: new library_1.Decimal(createGoalDto.targetAmount),
|
||||
currency: createGoalDto.currency,
|
||||
targetDate: createGoalDto.targetDate ? new Date(createGoalDto.targetDate) : null,
|
||||
imageUrl: createGoalDto.imageUrl,
|
||||
category: createGoalDto.category,
|
||||
},
|
||||
include: {
|
||||
allocations: true,
|
||||
milestones: true,
|
||||
},
|
||||
});
|
||||
await this.createMilestones(goal.id, new library_1.Decimal(createGoalDto.targetAmount));
|
||||
return this.findOne(userId, goal.id);
|
||||
}
|
||||
async findAll(userId, status) {
|
||||
const where = { userId };
|
||||
if (status) {
|
||||
where.status = status;
|
||||
}
|
||||
return this.prisma.goal.findMany({
|
||||
where,
|
||||
include: {
|
||||
allocations: {
|
||||
include: {
|
||||
wallet: true,
|
||||
},
|
||||
},
|
||||
milestones: {
|
||||
orderBy: { percentage: 'asc' },
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
}
|
||||
async findOne(userId, id) {
|
||||
const goal = await this.prisma.goal.findFirst({
|
||||
where: { id, userId },
|
||||
include: {
|
||||
allocations: {
|
||||
include: {
|
||||
wallet: true,
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
},
|
||||
milestones: {
|
||||
orderBy: { percentage: 'asc' },
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!goal) {
|
||||
throw new common_1.NotFoundException('Goal not found');
|
||||
}
|
||||
return goal;
|
||||
}
|
||||
async update(userId, id, updateGoalDto) {
|
||||
await this.findOne(userId, id);
|
||||
const updateData = {};
|
||||
if (updateGoalDto.name !== undefined)
|
||||
updateData.name = updateGoalDto.name;
|
||||
if (updateGoalDto.description !== undefined)
|
||||
updateData.description = updateGoalDto.description;
|
||||
if (updateGoalDto.targetAmount !== undefined) {
|
||||
updateData.targetAmount = new library_1.Decimal(updateGoalDto.targetAmount);
|
||||
await this.prisma.goalMilestone.deleteMany({ where: { goalId: id } });
|
||||
await this.createMilestones(id, new library_1.Decimal(updateGoalDto.targetAmount));
|
||||
}
|
||||
if (updateGoalDto.currency !== undefined)
|
||||
updateData.currency = updateGoalDto.currency;
|
||||
if (updateGoalDto.targetDate !== undefined) {
|
||||
updateData.targetDate = updateGoalDto.targetDate ? new Date(updateGoalDto.targetDate) : null;
|
||||
}
|
||||
if (updateGoalDto.imageUrl !== undefined)
|
||||
updateData.imageUrl = updateGoalDto.imageUrl;
|
||||
if (updateGoalDto.category !== undefined)
|
||||
updateData.category = updateGoalDto.category;
|
||||
if (updateGoalDto.status !== undefined) {
|
||||
updateData.status = updateGoalDto.status;
|
||||
if (updateGoalDto.status === 'completed') {
|
||||
updateData.completedAt = new Date();
|
||||
}
|
||||
}
|
||||
const goal = await this.prisma.goal.update({
|
||||
where: { id },
|
||||
data: updateData,
|
||||
include: {
|
||||
allocations: {
|
||||
include: {
|
||||
wallet: true,
|
||||
},
|
||||
},
|
||||
milestones: true,
|
||||
},
|
||||
});
|
||||
return goal;
|
||||
}
|
||||
async remove(userId, id) {
|
||||
await this.findOne(userId, id);
|
||||
await this.prisma.goal.delete({
|
||||
where: { id },
|
||||
});
|
||||
return { message: 'Goal deleted successfully' };
|
||||
}
|
||||
async addAllocation(userId, goalId, createAllocationDto) {
|
||||
const goal = await this.findOne(userId, goalId);
|
||||
const wallet = await this.prisma.wallet.findFirst({
|
||||
where: {
|
||||
id: createAllocationDto.walletId,
|
||||
userId,
|
||||
deletedAt: null,
|
||||
},
|
||||
});
|
||||
if (!wallet) {
|
||||
throw new common_1.NotFoundException('Wallet not found');
|
||||
}
|
||||
const walletBalance = await this.walletBalanceService.calculateBalance(wallet.id);
|
||||
const allocationAmountInIDR = new library_1.Decimal(createAllocationDto.amount);
|
||||
let amountInWalletCurrency = allocationAmountInIDR;
|
||||
let exchangeRate = new library_1.Decimal(1);
|
||||
if (wallet.currency && wallet.currency !== 'IDR') {
|
||||
exchangeRate = await this.getExchangeRate('IDR', wallet.currency);
|
||||
amountInWalletCurrency = allocationAmountInIDR.times(exchangeRate);
|
||||
}
|
||||
else if (wallet.kind === 'asset' && wallet.pricePerUnit) {
|
||||
amountInWalletCurrency = allocationAmountInIDR.dividedBy(wallet.pricePerUnit);
|
||||
}
|
||||
if (walletBalance.availableBalance.lessThan(amountInWalletCurrency)) {
|
||||
const currency = wallet.kind === 'money' ? wallet.currency : wallet.unit;
|
||||
throw new common_1.BadRequestException(`Insufficient available balance. Available: ${walletBalance.availableBalance.toString()} ${currency}, Reserved: ${walletBalance.reservedBalance.toString()} ${currency}`);
|
||||
}
|
||||
const allocation = await this.prisma.goalAllocation.create({
|
||||
data: {
|
||||
goalId,
|
||||
walletId: wallet.id,
|
||||
amount: allocationAmountInIDR,
|
||||
currency: 'IDR',
|
||||
exchangeRate: wallet.currency !== 'IDR' ? exchangeRate : null,
|
||||
amountInGoalCurrency: allocationAmountInIDR,
|
||||
notes: createAllocationDto.notes,
|
||||
createdBy: userId,
|
||||
},
|
||||
include: {
|
||||
wallet: true,
|
||||
},
|
||||
});
|
||||
const newCurrentAmount = new library_1.Decimal(goal.currentAmount).plus(allocationAmountInIDR);
|
||||
await this.prisma.goal.update({
|
||||
where: { id: goalId },
|
||||
data: { currentAmount: newCurrentAmount },
|
||||
});
|
||||
await this.prisma.wallet.update({
|
||||
where: { id: wallet.id },
|
||||
data: {
|
||||
reservedBalance: {
|
||||
increment: amountInWalletCurrency,
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.updateMilestones(goalId, newCurrentAmount);
|
||||
return allocation;
|
||||
}
|
||||
async removeAllocation(userId, goalId, allocationId) {
|
||||
const goal = await this.findOne(userId, goalId);
|
||||
const allocation = await this.prisma.goalAllocation.findFirst({
|
||||
where: {
|
||||
id: allocationId,
|
||||
goalId,
|
||||
},
|
||||
});
|
||||
if (!allocation) {
|
||||
throw new common_1.NotFoundException('Allocation not found');
|
||||
}
|
||||
const newCurrentAmount = new library_1.Decimal(goal.currentAmount).minus(allocation.amountInGoalCurrency);
|
||||
await this.prisma.goal.update({
|
||||
where: { id: goalId },
|
||||
data: { currentAmount: newCurrentAmount.greaterThanOrEqualTo(0) ? newCurrentAmount : new library_1.Decimal(0) },
|
||||
});
|
||||
await this.prisma.wallet.update({
|
||||
where: { id: allocation.walletId },
|
||||
data: {
|
||||
reservedBalance: {
|
||||
decrement: allocation.amount,
|
||||
},
|
||||
},
|
||||
});
|
||||
await this.prisma.goalAllocation.delete({
|
||||
where: { id: allocationId },
|
||||
});
|
||||
await this.updateMilestones(goalId, newCurrentAmount);
|
||||
return { message: 'Allocation removed successfully' };
|
||||
}
|
||||
async getStats(userId) {
|
||||
const goals = await this.prisma.goal.findMany({
|
||||
where: { userId },
|
||||
include: {
|
||||
allocations: true,
|
||||
},
|
||||
});
|
||||
const totalGoals = goals.length;
|
||||
const activeGoals = goals.filter(g => g.status === 'active').length;
|
||||
const completedGoals = goals.filter(g => g.status === 'completed').length;
|
||||
let totalTargetAmount = new library_1.Decimal(0);
|
||||
let totalCurrentAmount = new library_1.Decimal(0);
|
||||
for (const goal of goals) {
|
||||
if (goal.status === 'active') {
|
||||
totalTargetAmount = totalTargetAmount.plus(goal.targetAmount);
|
||||
totalCurrentAmount = totalCurrentAmount.plus(goal.currentAmount);
|
||||
}
|
||||
}
|
||||
const overallProgress = totalTargetAmount.greaterThan(0)
|
||||
? totalCurrentAmount.dividedBy(totalTargetAmount).times(100).toNumber()
|
||||
: 0;
|
||||
return {
|
||||
totalGoals,
|
||||
activeGoals,
|
||||
completedGoals,
|
||||
totalTargetAmount: totalTargetAmount.toNumber(),
|
||||
totalCurrentAmount: totalCurrentAmount.toNumber(),
|
||||
overallProgress: Math.round(overallProgress * 100) / 100,
|
||||
};
|
||||
}
|
||||
async createMilestones(goalId, targetAmount) {
|
||||
const percentages = [25, 50, 75, 100];
|
||||
for (const percentage of percentages) {
|
||||
await this.prisma.goalMilestone.create({
|
||||
data: {
|
||||
goalId,
|
||||
percentage,
|
||||
targetAmount: targetAmount.times(percentage).dividedBy(100),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
async updateMilestones(goalId, currentAmount) {
|
||||
const milestones = await this.prisma.goalMilestone.findMany({
|
||||
where: { goalId },
|
||||
orderBy: { percentage: 'asc' },
|
||||
});
|
||||
for (const milestone of milestones) {
|
||||
if (currentAmount.greaterThanOrEqualTo(milestone.targetAmount) && !milestone.achievedAt) {
|
||||
await this.prisma.goalMilestone.update({
|
||||
where: { id: milestone.id },
|
||||
data: { achievedAt: new Date() },
|
||||
});
|
||||
}
|
||||
else if (currentAmount.lessThan(milestone.targetAmount) && milestone.achievedAt) {
|
||||
await this.prisma.goalMilestone.update({
|
||||
where: { id: milestone.id },
|
||||
data: { achievedAt: null },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
async getExchangeRate(fromCurrency, toCurrency) {
|
||||
const rates = {
|
||||
'USD': 15000,
|
||||
'EUR': 16500,
|
||||
'GBP': 19000,
|
||||
'JPY': 100,
|
||||
'SGD': 11000,
|
||||
'MYR': 3500,
|
||||
'IDR': 1,
|
||||
};
|
||||
const fromRate = rates[fromCurrency] || 1;
|
||||
const toRate = rates[toCurrency] || 1;
|
||||
return new library_1.Decimal(fromRate).dividedBy(toRate);
|
||||
}
|
||||
};
|
||||
exports.GoalsService = GoalsService;
|
||||
exports.GoalsService = GoalsService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [prisma_service_1.PrismaService,
|
||||
wallet_balance_service_1.WalletBalanceService])
|
||||
], GoalsService);
|
||||
//# sourceMappingURL=goals.service.js.map
|
||||
1
apps/api/dist/goals/goals.service.js.map
vendored
Executable file
1
apps/api/dist/goals/goals.service.js.map
vendored
Executable file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user