pos-be/src/modules/configuration/couch/data/services/couch.service.ts

171 lines
4.1 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { DatabaseListen } from '../../constants';
import { EventBus } from '@nestjs/cqrs';
import { ChangeDocEvent } from '../../domain/events/change-doc.event';
import { ConfigService } from '@nestjs/config';
import { apm } from 'src/core/apm';
import * as Nano from 'nano';
@Injectable()
export class CouchService {
constructor(
private eventBus: EventBus,
private configService: ConfigService,
) {}
get nanoInstance() {
const couchConfiguration = this.configService.get<string>('COUCHDB_CONFIG');
return Nano(couchConfiguration);
}
async onModuleInit() {
// return;
const nano = this.nanoInstance;
for (const database of DatabaseListen) {
const db = nano.db.use(database);
db.changesReader.start({ includeDocs: true }).on('change', (change) => {
Logger.verbose(
`Receive Data from ${database}: ${change?.id}`,
'CouchService',
);
this.changeDoc(change, database);
});
// transaction
Logger.log(`start listen database ${database}`, 'CouchService');
}
}
private changeDoc(data, database) {
this.eventBus.publish(
new ChangeDocEvent({
id: data.id,
database: database,
data: data.doc,
}),
);
}
public async createDoc(data, database) {
try {
const nano = this.nanoInstance;
const db = nano.use(database);
return await db.insert(data);
} catch (error) {
console.log(error);
apm.captureError(error);
}
}
public async deleteDoc(data, database) {
try {
const nano = this.nanoInstance;
const db = nano.use(database);
const result = await db.get(data.id);
await db.destroy(data.id, result._rev);
} catch (error) {
console.log(error);
apm.captureError(error);
}
}
public async updateDoc(data, database) {
try {
const nano = this.nanoInstance;
const db = nano.use(database);
const result = await db.get(data.id);
await db.insert({
...data,
_rev: result._rev,
});
} catch (error) {
console.log(error);
apm.captureError(error);
}
}
public async getDoc(id: string, database: string) {
try {
const nano = this.nanoInstance;
const db = nano.use(database);
const result = await db.get(id);
return result;
} catch (error) {
console.log(error);
apm.captureError(error);
return null;
}
}
public async totalTodayTransactions(database = 'transaction') {
try {
const nano = this.nanoInstance;
const db = nano.use<any>(database);
// Get today's start timestamp (midnight)
const today = new Date();
today.setHours(0, 0, 0, 0);
const todayTimestamp = today.getTime();
// Query for documents created today
const selector = {
created_at: {
$gte: todayTimestamp,
},
};
const result = await db.find({
selector: selector,
fields: ['_id', 'payment_total_pay'],
limit: 10000,
});
return result.docs.reduce(
(sum, doc) => sum + (doc.payment_total_pay || 0),
0,
);
} catch (error) {
console.log(error);
apm.captureError(error);
return 0;
}
}
getUnixTimestampLast7Days() {
const date = new Date();
date.setDate(date.getDate() - 4);
date.setHours(0, 0, 0, 0);
return date.getTime();
}
public async clearTransactions() {
const nano = this.nanoInstance;
const transaction = nano.use('transaction');
const expiredDate = this.getUnixTimestampLast7Days();
const selectorPayment = {
created_at: {
$lt: expiredDate,
},
};
const transactions = await transaction.find({
selector: selectorPayment,
fields: ['_id', '_rev'],
limit: 100000,
});
const { docs } = transactions;
console.log(docs.length);
const deletedDocs = {
docs: docs.map((doc) => ({
_id: doc._id,
_rev: doc._rev,
_deleted: true,
})),
};
await transaction.bulk(deletedDocs);
}
}