futoin-xferengine
Version:
Neutral clustered multi-currency transaction engine with limits
188 lines (160 loc) • 6.03 kB
JavaScript
;
/**
* @file
*
* Copyright 2017 FutoIn Project (https://futoin.org)
* Copyright 2017 Andrey Galkin <andrey@futoin.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const BaseService = require( './BaseService' );
const BonusFace = require( './BonusFace' );
const GamingTools = require( './GamingTools' );
const AmountTools = require( './AmountTools' );
/**
* Bonus Service
*/
class BonusService extends BaseService {
static get IFACE_IMPL() {
return BonusFace;
}
_xferTools( reqinfo ) {
const ccm = reqinfo.executor().ccm();
return new GamingTools( ccm );
}
claimBonus( as, reqinfo ) {
const ccm = reqinfo.executor().ccm();
const acctface = ccm.iface( 'xfer.accounts' );
const p = reqinfo.params();
const xt = this._xferTools( reqinfo );
const ext_id = xt.makeExtId( p.rel_account, p.bonus_id );
acctface.getAccountHolderExt( as, p.user );
// Prepare bonus account
as.add( ( as, holder ) => {
as.add(
( as ) => {
acctface.addAccount( as,
holder.id,
xt.ACCT_BONUS,
p.currency,
p.alias,
true,
ext_id,
p.rel_account
);
},
( as, err ) => {
if ( err !== 'Duplicate' ) {
return;
}
acctface.getAccountExt( as, holder.id, ext_id );
as.add( ( as, info ) => {
if ( ( info.currency !== p.currency ) ||
( info.alias !== p.alias )
) {
as.error( 'OriginalMismatch' );
}
as.success( info.id );
} );
}
);
} );
// Add bonus amount
as.add( ( as, account_id ) => {
const xfer = {
type: 'Bonus',
src_limit_domain: 'Payments',
src_limit_prefix: 'outbound',
dst_limit_prefix: false,
src_account: p.rel_account,
dst_account: account_id,
amount: p.amount,
currency: p.currency,
ext_id: ext_id,
orig_ts: p.orig_ts,
misc_data: {
info: p.ext_info,
orig_ts: p.orig_ts,
},
};
xt.processXfer( as, xfer );
as.add( ( as ) => reqinfo.result( true ) );
} );
}
clearBonus( as, reqinfo ) {
const ccm = reqinfo.executor().ccm();
const acctface = ccm.iface( 'xfer.accounts' );
const p = reqinfo.params();
const xt = this._xferTools( reqinfo );
const ext_id = xt.makeExtId( p.rel_account, p.bonus_id );
acctface.getAccountHolderExt( as, p.user );
as.add( ( as, holder ) => acctface.getAccountExt( as, holder.id, ext_id ) );
as.add( ( as, info ) => {
if ( !info.enabled && AmountTools.isZero( info.balance ) ) {
if ( info.rel_id !== p.rel_account ) {
as.error( 'AlreadyReleased' );
}
} else {
const xfer = {
type: 'CancelBonus',
src_limit_prefix: false,
dst_limit_prefix: false,
src_account: info.id,
dst_account: p.rel_account,
currency: info.currency,
};
xt.closeBonus( as, xfer );
}
} );
as.add( ( as ) => reqinfo.result( true ) );
}
releaseBonus( as, reqinfo ) {
const ccm = reqinfo.executor().ccm();
const acctface = ccm.iface( 'xfer.accounts' );
const p = reqinfo.params();
const xt = this._xferTools( reqinfo );
const ext_id = xt.makeExtId( p.rel_account, p.bonus_id );
acctface.getAccountHolderExt( as, p.user );
as.add( ( as, holder ) => acctface.getAccountExt( as, holder.id, ext_id ) );
as.add( ( as, info ) => {
if ( !info.enabled && AmountTools.isZero( info.balance ) ) {
if ( info.rel_id === p.rel_account ) {
as.error( 'AlreadyCanceled' );
}
} else {
xt.findAccounts( as, p.user, info.currency, null );
as.add( ( as, main ) => {
const xfer = {
type: 'ReleaseBonus',
src_limit_prefix: false,
dst_limit_prefix: false,
src_account: info.id,
dst_account: main.uuidb64,
currency: info.currency,
};
xt.closeBonus( as, xfer );
} );
}
} );
as.add( ( as ) => reqinfo.result( true ) );
}
/**
* Register futoin.xfers.bonus interface with Executor
* @alias BonusService.register
* @param {AsyncSteps} as - steps interface
* @param {Executor} executor - executor instance
* @param {object} options - implementation defined options
* @returns {BonusService} instance
*/
}
module.exports = BonusService;