import { Injectable } from '@nestjs/common' ; import { Map } from 'immutable' ; import { Bundle } from '.' ; import { BundleService } from './bundle.service' ; import { AccountAssetDTO , AccountBalanceAssetService , AccountBalanceService } from '../account-balance' ; @ Injectable ( ) export class BundleAccountingService extends AccountBalanceAssetService { constructor ( private readonly bundleService , accountBalanceService ) { super ( ) ; accountBalanceService . registerAssetSource ( this ) ; } public async lockedAssets ( ownerId ) { const bundles = await this . getUserBundles ( ownerId ) ; return this . getAssetsLockedInBundles ( bundles , false ) ; } public async availableAssets ( ownerId ) { const bundles = await this . getUserBundles ( ownerId ) ; const inBundlesAvailable = await this . getAssetsLockedInBundles ( bundles , true ) ; const fromBundles = await this . getAssetsFromBundles ( ownerId ) ; const sum = ( oldVal , newVal ) => ( { ... oldVal , amount : oldVal . amount . add ( newVal . amount ) } ) ; return inBundlesAvailable . mergeWith ( sum , fromBundles ) ; } private async getUserBundles ( ownerId ) { return this . bundleService . getByUser ( ownerId , { isCancelled : false } ) ; } private async getAssetsLockedInBundles ( bundles , initialVolume ) { const items = bundles . flatMap ( ( bundle ) => bundle . items ) ; const sign = initialVolume ? - 1 : 1 ; return this . sumByAsset ( items , ( bundle ) => bundle . asset , ( order ) => ( initialVolume ? order . startVolume : order . currentVolume ) . muln ( sign ) ) ; } private async getAssetsFromBundles ( userId ) { const trades = await this . bundleService . getTrades ( userId ) ; const items = trades . flatMap ( ( trade ) => trade . items ) ; return this . sumByAsset ( items , ( bundle ) => bundle . asset , ( order ) => order . volume ) ; } }