avicenna/service/data-hub/data-connector/src/modules/app-accounting/accounting-validation.repos...

212 lines
5.0 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from 'src/core/database/prisma.service';
import { TourStateMetaObjectType } from './accounting-arg.types';
import {
AccountingFilter,
createPrismaQueryFromAccountingFilters,
} from './accounting-filter';
import { AccountingState } from './accounting-state';
@Injectable()
export class AccountingValidationRepository {
constructor(private readonly prisma: PrismaService) {}
async findByState(
state: AccountingState,
filter: AccountingFilter,
take?: number,
skip?: number,
) {
const checkValue = this.getCheckValueForAccountingState(state);
const query: Prisma.TourFindManyArgs = {
...{
...(skip ? { skip, take: 10 } : {}),
...(take ? { take } : {}),
...(take && !skip ? { skip: 0 } : {}),
},
where: {
check: checkValue,
...(checkValue === 2 && !filter?.deviation
? { revenueDeviation: { not: 0 } }
: {}),
empty: {
not: null,
},
ticketId: {
not: null,
},
AND: [
...createPrismaQueryFromAccountingFilters(filter),
{
OR: [
{
carName: null,
},
{
AND: [
{
carName: {
not: 'Storno',
},
},
{
carName: {
not: 'Löschen',
},
},
{
carName: {
not: 'Abgabe',
},
},
],
},
],
},
{
deletedAt: null,
},
{
OR: [
{ patientId: null },
{
AND: [
{
patientId: {
// Pause
not: 'b7424477-a4b2-42f7-b7e7-a4bef24f6979',
},
},
{
patientId: {
// Feierabend
not: '3554e1a9-9c07-45e5-b53c-692a77e4fa9a',
},
},
],
},
],
},
],
},
orderBy: { createdAt: 'desc' },
};
const [tours, count] = await this.prisma.$transaction([
this.prisma.tour.findMany({ ...query }),
this.prisma.tour.count({ where: query.where }),
]);
return {
tours,
total: count,
};
}
async calculateTourStateMeta(
state: AccountingState,
): Promise<TourStateMetaObjectType> {
const checkValue = this.getCheckValueForAccountingState(state);
const ticketWithCurrentStateAndTours: Prisma.TourWhereInput = {
check: checkValue,
...(checkValue === 2 ? { revenueDeviation: { not: 0 } } : {}),
empty: {
not: null,
},
ticketId: {
not: null,
},
AND: [
{
OR: [
{
carName: null,
},
{
AND: [
{
carName: {
not: 'Storno',
},
},
{
carName: {
not: 'Löschen',
},
},
{
carName: {
not: 'Abgabe',
},
},
],
},
],
},
{
deletedAt: null,
},
{
OR: [
{ patientId: null },
{
AND: [
{
patientId: {
// Pause
not: 'b7424477-a4b2-42f7-b7e7-a4bef24f6979',
},
},
{
patientId: {
// Feierabend
not: '3554e1a9-9c07-45e5-b53c-692a77e4fa9a',
},
},
],
},
],
},
],
};
const [count, revenueSum] = await this.prisma.$transaction([
this.prisma.tour.count({
where: { ...ticketWithCurrentStateAndTours },
}),
this.prisma.tour.aggregate({
_sum: {
revenue: true,
},
where: {
...ticketWithCurrentStateAndTours,
},
}),
]);
return {
count,
revenueSum: revenueSum._sum.revenue ?? 0,
};
}
findTicketByTicketId(ticketId: string) {
return this.prisma.ticket.findFirst({
where: {
id: ticketId,
},
});
}
private getCheckValueForAccountingState(state: AccountingState): number {
switch (state) {
case AccountingState.Billable:
return 0;
case AccountingState.PreparedForBilling:
return 1;
case AccountingState.Billed:
return 2;
}
}
}