import { PrismaRepository } from '@gitroom/nestjs-libraries/database/prisma/prisma.service'; import { Injectable } from '@nestjs/common'; import { Post as PostBody } from '@gitroom/nestjs-libraries/dtos/posts/create.post.dto'; import { APPROVED_SUBMIT_FOR_ORDER, Post } from '@prisma/client'; import { GetPostsDto } from '@gitroom/nestjs-libraries/dtos/posts/get.posts.dto'; import dayjs from 'dayjs'; import isoWeek from 'dayjs/plugin/isoWeek'; import { v4 as uuidv4 } from 'uuid'; dayjs.extend(isoWeek); @Injectable() export class PostsRepository { constructor(private _post: PrismaRepository<'post'>) {} getOldPosts(orgId: string, date: string) { return this._post.model.post.findMany({ where: { organizationId: orgId, publishDate: { lte: dayjs(date).toDate(), }, deletedAt: null, parentPostId: null, }, orderBy: { publishDate: 'desc', }, select: { id: true, content: true, publishDate: true, releaseURL: true, state: true, integration: { select: { id: true, name: true, providerIdentifier: true, picture: true, type: true, }, }, }, }); } getPostUrls(orgId: string, ids: string[]) { return this._post.model.post.findMany({ where: { organizationId: orgId, id: { in: ids, }, }, select: { id: true, releaseURL: true, }, }); } getPosts(orgId: string, query: GetPostsDto) { const date = dayjs().year(query.year).isoWeek(query.week); const startDate = date.startOf('week').toDate(); const endDate = date.endOf('week').toDate(); console.log(startDate, endDate); return this._post.model.post.findMany({ where: { OR: [ { organizationId: orgId, }, { submittedForOrganizationId: orgId, } ], publishDate: { gte: startDate, lte: endDate, }, deletedAt: null, parentPostId: null, }, select: { id: true, content: true, publishDate: true, releaseURL: true, submittedForOrganizationId: true, submittedForOrderId: true, state: true, integration: { select: { id: true, providerIdentifier: true, name: true, picture: true, }, }, }, }); } async deletePost(orgId: string, group: string) { await this._post.model.post.updateMany({ where: { organizationId: orgId, group, }, data: { deletedAt: new Date(), }, }); return this._post.model.post.findFirst({ where: { organizationId: orgId, group, parentPostId: null, }, select: { id: true, }, }); } getPost( id: string, includeIntegration = false, orgId?: string, isFirst?: boolean ) { return this._post.model.post.findUnique({ where: { id, ...(orgId ? { organizationId: orgId } : {}), deletedAt: null, }, include: { ...(includeIntegration ? { integration: true, } : {}), childrenPost: true, }, }); } updatePost(id: string, postId: string, releaseURL: string) { return this._post.model.post.update({ where: { id, }, data: { state: 'PUBLISHED', releaseURL, releaseId: postId, }, }); } async changeDate(orgId: string, id: string, date: string) { return this._post.model.post.update({ where: { organizationId: orgId, id, }, data: { publishDate: dayjs(date).toDate(), }, }); } countPostsFromDay(orgId: string, date: Date) { return this._post.model.post.count({ where: { organizationId: orgId, publishDate: { gte: date, }, OR: [ { deletedAt: null, state: { in: ['QUEUE'], }, }, { state: 'PUBLISHED', }, ], }, }); } async createOrUpdatePost( state: 'draft' | 'schedule' | 'now', orgId: string, date: string, body: PostBody ) { const posts: Post[] = []; const uuid = uuidv4(); for (const value of body.value) { const updateData = (type: 'create' | 'update') => ({ publishDate: dayjs(date).toDate(), integration: { connect: { id: body.integration.id, organizationId: orgId, }, }, ...(posts?.[posts.length - 1]?.id ? { parentPost: { connect: { id: posts[posts.length - 1]?.id, }, }, } : type === 'update' ? { parentPost: { disconnect: true, }, } : {}), content: value.content, group: uuid, approvedSubmitForOrder: APPROVED_SUBMIT_FOR_ORDER.NO, state: state === 'draft' ? ('DRAFT' as const) : ('QUEUE' as const), image: JSON.stringify(value.image), settings: JSON.stringify(body.settings), organization: { connect: { id: orgId, }, }, }); posts.push( await this._post.model.post.upsert({ where: { id: value.id || uuidv4(), }, create: { ...updateData('create') }, update: { ...updateData('update'), lastMessage: { disconnect: true, }, submittedForOrder: { disconnect: true, }, }, }) ); } const previousPost = body.group ? ( await this._post.model.post.findFirst({ where: { group: body.group, deletedAt: null, parentPostId: null, }, select: { id: true, }, }) )?.id! : undefined; if (body.group) { await this._post.model.post.updateMany({ where: { group: body.group, deletedAt: null, }, data: { parentPostId: null, deletedAt: new Date(), }, }); } return { previousPost, posts }; } async submit(id: string, order: string, buyerOrganizationId: string) { return this._post.model.post.update({ where: { id, }, data: { submittedForOrderId: order, approvedSubmitForOrder: 'WAITING_CONFIRMATION', submittedForOrganizationId: buyerOrganizationId, }, select: { id: true, description: true, submittedForOrder: { select: { messageGroupId: true, }, }, }, }); } updateMessage(id: string, messageId: string) { return this._post.model.post.update({ where: { id, }, data: { lastMessageId: messageId, }, }); } getPostById(id: string, org?: string) { return this._post.model.post.findUnique({ where: { id, ...(org ? { organizationId: org } : {}), }, include: { integration: true, submittedForOrder: { include: { posts: { where: { state: 'PUBLISHED', }, }, ordersItems: true, seller: { select: { id: true, account: true, }, }, }, }, }, }); } }