import Collections from 'common/database/collections' ; import DBProvider , { serverOnly , querySnapshot , QuerySnapshotCallback , DocumentSnapshotCallback , UnsubscribeSnapshot , getIdentify , documentSnapshot } from './dbProvider' ; import { ClientCardIded , ClientCard , ClientSessionEntryIded , ClientSessionEntry , DocumentEntryIded , DocumentEntry , ClientStatus , } from 'common/models' ; import { createLogger } from 'common/logger' ; import { TimeTrackingEntry , TimeTrackingEntryIded } from 'common/models/TimeTracking' ; const logger = createLogger ( '[ClientCardRepo]' ) ; class ClientCardRepo { constructor ( protected readonly db ) { } private getCollection ( coachId ) { return this . db . collection ( Collections . coachClients ( coachId ) ) ; } private getServerCollection ( coachId ) { return serverOnly ( this . db ) . collection ( Collections . coachClients ( coachId ) ) ; } getClients ( coachId ) ; getClients ( coachId , cb ) ; getClients ( coachId , cb = null ) { return querySnapshot ( this . db , this . getCollection ( coachId ) , cb ) ; } async getClientsByEmail ( email , coachUid ? , ... statuses ) { let query = coachUid ? this . getServerCollection ( coachUid ) : serverOnly ( this . db ) . collectionGroup ( 'clients' ) ; query = query . where ( 'email' , '==' , email ) ; const snapshot = await query . get ( ) ; const result = ( snapshot . docs || [ ] ) . map ( d => { const res = getIdentify < ClientCardIded & { coachId : string ; } > ( d ) ; res . coachId = d . ref . parent . parent . id ; return res ; } ) ; if ( statuses ?. length ) { return result . filter ( cc => statuses . includes ( cc . status ) ) ; } return result ; } async getClient ( coachId , cardId ) { const collection = this . getCollection ( coachId ) ; const docRef = await collection . doc ( cardId ) . get ( ) ; if ( ! docRef . exists ) { return null ; } const res = docRef . data ( ) as ClientCardIded ; res . id = docRef . id ; return res ; } async create ( coachId , data ) { const collection = this . getServerCollection ( coachId ) ; const docRef = collection . doc ( ) ; await docRef . create ( data ) ; const res = await docRef . get ( ) ; const card = res . data ( ) as ClientCardIded ; card . id = docRef . id ; return card ; } async update ( coachId , cardId , diff ) { const collection = this . getServerCollection ( coachId ) ; const docRef = collection . doc ( cardId ) ; const cardDoc = await docRef . get ( ) ; if ( ! cardDoc . exists ) { throw new Error ( `Client Card does not exist: ${ docRef . path }` ) ; } const card = getIdentify < ClientCardIded > ( cardDoc ) ; if ( diff . status && card . status !== diff . status ) { ClientCard . changeStatus ( card , diff . status , diff . date ) ; diff . history = card . history || null ; diff . date = card . date || Date . now ( ) ; } await docRef . update ( diff ) ; Object . assign ( card , diff ) ; return card ; } async delete ( coachId , cardId ) { const collection = this . getServerCollection ( coachId ) ; const docRef = collection . doc ( cardId ) ; const res = await docRef . delete ( ) ; return ! ! res ; } getSessions ( coachId , clientCardId ) ; getSessions ( coachId , clientCardId , cb ) ; getSessions ( coachId , clientCardId , cb = null ) { return querySnapshot ( this . db , this . db . collection ( Collections . sessions ( coachId , clientCardId ) ) , cb ) ; } async getSession ( coachId , clientCardId , sessionId ) { const collection = this . db . collection ( Collections . sessions ( coachId , clientCardId ) ) ; const docRef = collection . doc ( sessionId ) ; const doc = await docRef . get ( ) ; const res = doc . data ( ) as ClientSessionEntryIded ; res . id = doc . id ; return res ; } async createSession ( coachId , clientCardId , session ) { const collection = serverOnly ( this . db ) . collection ( Collections . sessions ( coachId , clientCardId ) ) ; const docRef = collection . doc ( ) ; await docRef . create ( session ) ; const data = ( await docRef . get ( ) ) . data ( ) as ClientSessionEntryIded ; data . id = docRef . id ; return data ; } async deleteSession ( coachId , clientCardId , sessionId ) { const collection = this . db . collection ( Collections . sessions ( coachId , clientCardId ) ) ; const docRef = collection . doc ( sessionId ) ; const doc = await docRef . get ( ) ; if ( doc . exists ) { const res = doc . data ( ) as ClientSessionEntryIded ; res . id = doc . id ; await docRef . delete ( ) ; return res ; } return null ; } async updateSession ( coachId , clientCardId , entryId , entry ) { const collection = serverOnly ( this . db ) . collection ( Collections . sessions ( coachId , clientCardId ) ) ; const docRef = collection . doc ( entryId ) ; logger . log ( 'updating session id =' , entryId , 'with diff:' , entry ) ; await docRef . set ( entry , { merge : true } ) ; const docRes = await docRef . get ( ) ; return getIdentify < ClientSessionEntryIded > ( docRes ) ; } getDocuments ( coachId , clientCardId ) ; getDocuments ( coachId , clientCardId , cb ) ; getDocuments ( coachId , clientCardId , cb = null ) { return querySnapshot ( this . db , this . db . collection ( Collections . documents ( coachId , clientCardId ) ) , cb ) ; } getDocument ( coachId , clientCardId , docId ) ; getDocument ( coachId , clientCardId , docId , cb ) ; getDocument ( coachId , clientCardId , docId , cb = null ) { const docRef = this . db . collection ( Collections . documents ( coachId , clientCardId ) ) . doc ( docId ) ; return documentSnapshot ( this . db , docRef , cb ) ; } async createDocument ( coachId , clientCardId , document ) { const collection = serverOnly ( this . db ) . collection ( Collections . documents ( coachId , clientCardId ) ) ; const docRef = collection . doc ( ) ; await docRef . create ( document ) ; const data = ( await docRef . get ( ) ) . data ( ) as DocumentEntryIded ; data . id = docRef . id ; return data ; } async updateDocument ( coachId , clientCardId , entryId , entry ) { const collection = serverOnly ( this . db ) . collection ( Collections . documents ( coachId , clientCardId ) ) ; const docRef = collection . doc ( entryId ) ; logger . log ( 'updating document id =' , entryId , 'with diff:' , entry ) ; await docRef . set ( entry , { merge : true } ) ; const docRes = await docRef . get ( ) ; return getIdentify < DocumentEntryIded > ( docRes ) ; } async deleteDocument ( coachId , clientCardId , documentId ) { const collection = this . db . collection ( Collections . documents ( coachId , clientCardId ) ) ; const docRef = collection . doc ( documentId ) ; const doc = await docRef . get ( ) ; if ( doc . exists ) { const res = doc . data ( ) as DocumentEntryIded ; res . id = doc . id ; await docRef . delete ( ) ; return res ; } return null ; } getTimeTrackings ( coachId , clientCardId ) ; getTimeTrackings ( coachId , clientCardId , cb ) ; getTimeTrackings ( coachId , clientCardId , cb = null ) { return querySnapshot ( this . db , this . db . collection ( Collections . timeTracking ( coachId , clientCardId ) ) , cb ) ; } async createTimeTracking ( coachId , clientCardId , timeTracking ) { const collection = serverOnly ( this . db ) . collection ( Collections . timeTracking ( coachId , clientCardId ) ) ; const docRef = collection . doc ( ) ; await docRef . create ( timeTracking ) ; const data = ( await docRef . get ( ) ) . data ( ) as TimeTrackingEntryIded ; data . id = docRef . id ; return data ; } async updateTimeTracking ( coachId , clientCardId , entryId , entry ) { const collection = serverOnly ( this . db ) . collection ( Collections . timeTracking ( coachId , clientCardId ) ) ; const docRef = collection . doc ( entryId ) ; logger . log ( 'updating timeTracking id =' , entryId , 'with diff:' , entry ) ; await docRef . set ( entry , { merge : true } ) ; const docRes = await docRef . get ( ) ; return getIdentify < TimeTrackingEntryIded > ( docRes ) ; } async deleteTimeTracking ( coachId , clientCardId , timeTrackingId ) { const collection = this . db . collection ( Collections . timeTracking ( coachId , clientCardId ) ) ; const docRef = collection . doc ( timeTrackingId ) ; const doc = await docRef . get ( ) ; if ( doc . exists ) { const res = doc . data ( ) as TimeTrackingEntryIded ; res . id = doc . id ; await docRef . delete ( ) ; return res ; } return null ; } } export default ClientCardRepo ;