first commit
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
import { ClientAccountsAdapterMongoose } from "./ClientAccounts.Adapter.Mongoose";
|
||||
import {
|
||||
CreateClientAccountParams,
|
||||
IClientAccount,
|
||||
IClientAccountsManager,
|
||||
DeleteClientAccountParams,
|
||||
FindClientAccountsParams,
|
||||
ClientAccountView,
|
||||
DeleteClientsAccountsByCompanyParams,
|
||||
ClientAccountReport,
|
||||
GetClientAccountReportParams,
|
||||
GetPrevoiusBalanceParams,
|
||||
ClientAccountReportItem,
|
||||
} from "./ClientAccounts.Interface";
|
||||
import ClientsList from "../Clients/Clients";
|
||||
import ClientAccountMovements from "../ClientAccountMovements/ClientAccountMovements";
|
||||
import { PlanFeatures } from "../Plans/Plans.interface";
|
||||
import { validatePermissionsByClient, validateSessionUser } from "../../helpers/check";
|
||||
|
||||
class ClientAccountManager implements IClientAccountsManager {
|
||||
clientAccounts: ClientAccountsAdapterMongoose;
|
||||
|
||||
constructor() {
|
||||
this.clientAccounts = new ClientAccountsAdapterMongoose();
|
||||
}
|
||||
|
||||
public async deleteClientsAccountsByCompany(
|
||||
data: DeleteClientsAccountsByCompanyParams
|
||||
): Promise<void> {
|
||||
const clients = await ClientsList.clients.find({
|
||||
companyId: data.companyId,
|
||||
});
|
||||
|
||||
for (const client of clients) {
|
||||
await ClientAccountMovements.movements.movementList.deleteMany({
|
||||
clientId: String(client.id),
|
||||
});
|
||||
await this.clientAccounts.clientAccountList.deleteMany({
|
||||
clientId: String(client.id),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async createClientAccount(data: CreateClientAccountParams): Promise<IClientAccount> {
|
||||
await validateSessionUser({ sessionUser: data.sessionUser });
|
||||
await validatePermissionsByClient({
|
||||
sessionUser: data.sessionUser,
|
||||
feature: PlanFeatures.PAYMENTS,
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
const existingAccount = await this.clientAccounts.findOne({
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
if (existingAccount) {
|
||||
throw new Error("El cliente ya tiene una cuenta registrada");
|
||||
}
|
||||
|
||||
return await this.clientAccounts.create(data);
|
||||
}
|
||||
|
||||
public async findById(data: FindClientAccountsParams): Promise<IClientAccount> {
|
||||
await validateSessionUser({ sessionUser: data.sessionUser });
|
||||
await validatePermissionsByClient({
|
||||
sessionUser: String(data.sessionUser),
|
||||
feature: PlanFeatures.PAYMENTS,
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
let account = (await this.clientAccounts.findOne({
|
||||
clientId: data.clientId,
|
||||
})) as IClientAccount;
|
||||
|
||||
if (!account) {
|
||||
account = await this.createClientAccount({
|
||||
clientId: data.clientId,
|
||||
amount: 0,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
}
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
public async deleteClientAccount(data: DeleteClientAccountParams): Promise<void> {
|
||||
const { checkCashOnAccount = true } = data;
|
||||
await validateSessionUser({ sessionUser: data.sessionUser });
|
||||
|
||||
const account = await this.clientAccounts.findOne({
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
await validatePermissionsByClient({
|
||||
sessionUser: String(data.sessionUser),
|
||||
feature: PlanFeatures.PAYMENTS,
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
if (account.amount && account.amount > 0 && checkCashOnAccount) {
|
||||
throw new Error(
|
||||
"No se puede eliminar la cuenta del cliente ya que tiene saldo positivo."
|
||||
);
|
||||
}
|
||||
|
||||
//eliminar todos los movimientos de la cuenta
|
||||
await ClientAccountMovements.movements.movementList.deleteMany({
|
||||
clientId: account.clientId,
|
||||
});
|
||||
|
||||
await this.clientAccounts.delete(account.id);
|
||||
}
|
||||
|
||||
public async clientAccountView(data: FindClientAccountsParams): Promise<ClientAccountView> {
|
||||
await validateSessionUser({ sessionUser: data.sessionUser });
|
||||
await validatePermissionsByClient({
|
||||
sessionUser: String(data.sessionUser),
|
||||
feature: PlanFeatures.PAYMENTS,
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
const account = await this.findById({
|
||||
clientId: data.clientId,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
if (!account || !account.id) {
|
||||
throw new Error("No se encontró la cuenta del cliente");
|
||||
}
|
||||
|
||||
const movements = await ClientAccountMovements.paginate({
|
||||
clientId: data.clientId,
|
||||
page: 1,
|
||||
limit: 10,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
return {
|
||||
id: account.id,
|
||||
clientId: account.clientId,
|
||||
amount: account.amount,
|
||||
lastMovements: movements.data,
|
||||
};
|
||||
}
|
||||
|
||||
public async getAvailableAmount(data: FindClientAccountsParams): Promise<number> {
|
||||
const account = await this.findById(data);
|
||||
return account.amount;
|
||||
}
|
||||
|
||||
public async getPrevoiusBalance(data: GetPrevoiusBalanceParams): Promise<number> {
|
||||
const balance = await ClientAccountMovements.getBalance({
|
||||
clientId: data.clientId,
|
||||
endDate: data.date,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
return balance;
|
||||
}
|
||||
|
||||
public async getAccountReport(
|
||||
data: GetClientAccountReportParams
|
||||
): Promise<ClientAccountReport> {
|
||||
await validateSessionUser({ sessionUser: data.sessionUser });
|
||||
const { company, client } = await validatePermissionsByClient({
|
||||
sessionUser: String(data.sessionUser),
|
||||
feature: PlanFeatures.PAYMENTS,
|
||||
clientId: data.clientId,
|
||||
});
|
||||
|
||||
const previousBalance = await this.getPrevoiusBalance({
|
||||
clientId: data.clientId,
|
||||
date: data.dateFrom,
|
||||
sessionUser: data.sessionUser,
|
||||
});
|
||||
|
||||
const movements = await ClientAccountMovements.movements.find({
|
||||
clientId: data.clientId,
|
||||
startDate: data.dateFrom,
|
||||
endDate: data.dateTo,
|
||||
}); //falta implementar filtros de fecha
|
||||
|
||||
const dataReport: ClientAccountReportItem[] = movements.map((movement) => {
|
||||
return {
|
||||
date: movement.createdAt,
|
||||
description: movement.description,
|
||||
credit: movement.amount > 0 ? movement.amount : 0,
|
||||
debit: movement.amount < 0 ? Math.abs(movement.amount) : 0,
|
||||
balance: 0, //se calcula luego
|
||||
};
|
||||
});
|
||||
|
||||
//calcular saldos parciales
|
||||
let runningBalance = previousBalance;
|
||||
for (let i = 0; i < dataReport.length; i++) {
|
||||
runningBalance += dataReport[i].credit;
|
||||
runningBalance -= dataReport[i].debit;
|
||||
dataReport[i].balance = runningBalance;
|
||||
}
|
||||
|
||||
//retornamos el reporte
|
||||
|
||||
return {
|
||||
organizationId: String(company.id),
|
||||
organizacionName: String(company.name),
|
||||
clientId: String(data.clientId),
|
||||
clientName: ClientsList.getClientFullName(client),
|
||||
balance: previousBalance,
|
||||
data: dataReport,
|
||||
dateFrom: data.dateFrom,
|
||||
dateTo: data.dateTo,
|
||||
} as ClientAccountReport;
|
||||
}
|
||||
}
|
||||
|
||||
export default new ClientAccountManager();
|
||||
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
FindClientAccountsParams,
|
||||
IClientAccountsAdapter,
|
||||
IClientAccount,
|
||||
CreateClientAccountParams,
|
||||
} from "./ClientAccounts.Interface";
|
||||
import { Document, Model, Schema, model } from "mongoose";
|
||||
|
||||
export interface IClientAccountDocument
|
||||
extends Omit<IClientAccount, "id">,
|
||||
Document {}
|
||||
|
||||
export class ClientAccountsAdapterMongoose implements IClientAccountsAdapter {
|
||||
schema: Schema;
|
||||
clientAccountList: Model<IClientAccountDocument>;
|
||||
|
||||
constructor() {
|
||||
this.schema = new Schema({
|
||||
clientId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: true,
|
||||
ref: "Client",
|
||||
},
|
||||
amount: { type: Number, required: true, default: 0 },
|
||||
creationDate: { type: Date, required: true, default: Date.now },
|
||||
});
|
||||
|
||||
this.clientAccountList = model<IClientAccountDocument>(
|
||||
"ClientAccount",
|
||||
this.schema
|
||||
);
|
||||
}
|
||||
|
||||
public async create(
|
||||
data: CreateClientAccountParams
|
||||
): Promise<IClientAccount> {
|
||||
return await this.clientAccountList.create(data);
|
||||
}
|
||||
|
||||
public async delete(id: string): Promise<void> {
|
||||
await this.clientAccountList.deleteOne({ _id: id });
|
||||
}
|
||||
|
||||
public async find(
|
||||
filters: FindClientAccountsParams
|
||||
): Promise<IClientAccount[]> {
|
||||
return this.clientAccountList.find(filters).exec();
|
||||
}
|
||||
|
||||
public async findOne(
|
||||
filters: Omit<FindClientAccountsParams, "sessionUser">
|
||||
): Promise<IClientAccountDocument | null> {
|
||||
return this.clientAccountList.findOne(filters).exec();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { IClientAccountMovement } from "../ClientAccountMovements/ClientAccountMovements.Interface";
|
||||
import { IClientAccountDocument } from "./ClientAccounts.Adapter.Mongoose";
|
||||
|
||||
export type FindClientAccountsParams = {
|
||||
clientId: string;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type CreateClientAccountParams = {
|
||||
clientId: string;
|
||||
amount: number;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type DeleteClientAccountParams = {
|
||||
clientId: string;
|
||||
checkCashOnAccount?: boolean;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type DeleteClientsAccountsByCompanyParams = {
|
||||
companyId: string;
|
||||
};
|
||||
|
||||
export type ClientAccountReportItem = {
|
||||
date: Date;
|
||||
description: string;
|
||||
credit: number;
|
||||
debit: number;
|
||||
balance: number;
|
||||
};
|
||||
|
||||
export type ClientAccountReport = {
|
||||
organizacionName: string;
|
||||
organizationId: string;
|
||||
clientId: string;
|
||||
clientName: string;
|
||||
balance: number;
|
||||
dateFrom: Date;
|
||||
dateTo: Date;
|
||||
data: ClientAccountReportItem[];
|
||||
};
|
||||
|
||||
export type GetPrevoiusBalanceParams = {
|
||||
clientId: string;
|
||||
date: Date;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export type GetClientAccountReportParams = {
|
||||
clientId: string;
|
||||
dateFrom: Date;
|
||||
dateTo: Date;
|
||||
sessionUser: string;
|
||||
};
|
||||
|
||||
export interface ClientAccountView {
|
||||
id: string;
|
||||
clientId: string;
|
||||
amount: number;
|
||||
lastMovements: IClientAccountMovement[];
|
||||
}
|
||||
|
||||
export interface IClientAccount {
|
||||
id?: string;
|
||||
clientId: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface IClientAccountsAdapter {
|
||||
create(data: CreateClientAccountParams): Promise<IClientAccount>;
|
||||
delete(id: string): Promise<void>;
|
||||
find(filters: FindClientAccountsParams): Promise<IClientAccount[]>;
|
||||
findOne(filters: FindClientAccountsParams): Promise<IClientAccountDocument | null>;
|
||||
}
|
||||
|
||||
export interface IClientAccountsManager {
|
||||
clientAccounts: IClientAccountsAdapter;
|
||||
createClientAccount(data: CreateClientAccountParams): Promise<IClientAccount>;
|
||||
findById(data: FindClientAccountsParams): Promise<IClientAccount>;
|
||||
deleteClientAccount(data: DeleteClientAccountParams): Promise<void>;
|
||||
deleteClientsAccountsByCompany(data: DeleteClientsAccountsByCompanyParams): Promise<void>;
|
||||
clientAccountView(data: FindClientAccountsParams): Promise<ClientAccountView>;
|
||||
getAvailableAmount(data: FindClientAccountsParams): Promise<number>;
|
||||
getPrevoiusBalance(data: GetPrevoiusBalanceParams): Promise<number>;
|
||||
getAccountReport(data: GetClientAccountReportParams): Promise<ClientAccountReport>;
|
||||
}
|
||||
Reference in New Issue
Block a user