示例#1
0
文件: admin.py 项目: sridwan/meong
 def depmut_execute(self, agent_id, type, amount, comment, pin):
     result = {
       'success': 0,
       'balance': 0,
     }
     try:
         int(amount)
     except:
         result['message'] = 'AMOUNT NOT VALID'
         return json.dumps(result)
     # agent must exist
     bc = AgentNotifier()
     c_agent = DBCache(const.AGENT_PREFIX, config.DEFAULT_EXPIRE,
                       const.AGENT_SQL)
     c_agent.setConn(bc.dbconn, bc.cacheconn)
     #print c_agent.sGet(agentid)
     ag = c_agent.sGet(agent_id)
     if not ag:
         result['message'] = 'AGENT NOT REGISTERED'
         return json.dumps(result)
     dm = DepositMutation(20, bc.dbconn, bc.cacheconn)
     prev_bal = dm.getBalance(agent_id)
     if type.upper() == 'C':
         balance = dm.credit(agent_id, int(amount), comment)
         bc.writeNotifyOut(ag['default_protocol'], 'deposit_credit', {
                 'mutation': thousandSeparator(amount),
                 'balance_before': thousandSeparator(prev_bal),
                 'balance': thousandSeparator(balance),
             })
     elif type.upper() == 'D':
         balance = dm.debit(agent_id, int(amount), comment)
         bc.writeNotifyOut(ag['default_protocol'], 'deposit_debit', {
                 'mutation': thousandSeparator(amount),
                 'balance_before': thousandSeparator(prev_bal),
                 'balance': thousandSeparator(balance),
             })
     else:
         result['message'] = 'TYPE NOT RECOGNIZED'
         return json.dumps(result)
     if balance == NOT_ENOUGH_BALANCE:
         result['message'] = 'NOT ENOUGH BALANCE'
         return json.dumps(result)
     elif balance == LOCK_FAILED:
         result['message'] = 'SERVER BUSY'
         return json.dumps(result)
     bc.dbconn.commit()
     msg = '{0}-{1} Deposit: Rp. {2} Before: Rp. {3} After: Rp. {4} ({5}) ID:{6}'.\
           format(ag['agent_id'], ag['agent_name'], thousandSeparator(amount),
                  thousandSeparator(prev_bal), thousandSeparator(balance),
                  comment, dm.last_id)
     for prot in ('ym://b_martian','ym://inileonard', 'ym://sridwan981'):
         bc.writeNotifyOut(prot, 'general_message', {'message': msg})
     bc.dbconn.commit()
     result.update({
         'success': 1,
         'message': 'SUCCESS',
         'balance': balance,
         'mutation_id': dm.last_id,
     })
     return json.dumps(result)
示例#2
0
文件: admin.py 项目: sridwan/meong
 def bundle(self, name, agent_id, price, pin):
     bc = AgentNotifier()
     c_agent = DBCache(const.AGENT_PREFIX, config.DEFAULT_EXPIRE,
                       const.AGENT_SQL)
     c_agent.setConn(bc.dbconn, bc.cacheconn)
     dm = DepositMutation(20, bc.dbconn, bc.cacheconn)
     ag = c_agent.sGet(agent_id)
     if not ag:
         return json.dumps({'success': 0, 'reason': 'AGENT NOT FOUND'})
     sql = '''SELECT * FROM `bundle` WHERE `bundle_name`=%s'''
     c = bc.dbconn.cursor(MySQLdb.cursors.DictCursor)
     c.execute(sql, (name,))
     cs = c.fetchall()
     if len(cs) == 0:
         return json.dumps({'success': 0, 'reason': 'BUNDLE NOT FOUND'})            
     balance = dm.debit(agent_id, int(price), 'Bundle {0}'.format(name))
     if balance < 0:
         return json.dumps({'success': 0, 'reason': 'NOT ENOUGH DEPOSIT'})
     um = UnitMutation(5, bc.dbconn, bc.cacheconn)
     for r in c:
         um.credit(agent_id, r['product_id'], r['unit'], 0, name)
     msg = 'Add bundle {0} to {1}-{2} Rp {3}'.\
           format(name, agent_id, ag['agent_name'], thousandSeparator(price))
     for prot in ('ym://b_martian','ym://inileonard', 'ym://sridwan981'):
         bc.writeNotifyOut(prot, 'general_message', {'message': msg})
     bc.dbconn.commit()
     return json.dumps({'success': 1, 'reason': ''})            
示例#3
0
 def __init__(self):
     super(LoadBalance, self).__init__("LB")
     self.operator = self._loadOperator()
     self.c_product = DBCache(const.PRODUCT_PREFIX, config.DEFAULT_EXPIRE, const.PRODUCT_SQL)
     self.c_op_product = DBCache(const.OP_PRODUCT_PREFIX, config.DEFAULT_EXPIRE, const.OP_PRODUCT_SQL)
     self.c_device = DBCache(const.DEVICES_PREFIX, config.DEFAULT_EXPIRE, const.DEVICES_SQL)
     self.c_base_price = DBCache(const.CHIP_BASE_PRICE_PREFIX, config.DEFAULT_EXPIRE, const.CHIP_BASE_PRICE_SQL)
     map(
         lambda x: x.setConn(self.dbconn, self.cacheconn),
         [self.c_product, self.c_op_product, self.c_device, self.c_base_price],
     )
     # self.hlr_cache = HLRCacheForLB(self.dbconn, self.cacheconn)
     # self.hlr_cache.cacheAllTopupDevice()
     self.lb = LBTopup(self.dbconn)
     self.lb.cleanRebuild()
     self.hm = HLRMap(self.dbconn, self.cacheconn)
     self.hm.rebuild()
     self.dm = DepositMutation(5, self.dbconn, self.cacheconn)
     self.last_op_prod = None
     self.last_device = None
     self.last_hlr_id = None
     self.last_tr_id = None
     self.last_tr_data = None
     self.change_method = None
     self.log = mylogger("LoadBalance", "loadbalance.log")
示例#4
0
文件: admin.py 项目: sridwan/meong
 def transaction_success(self, tran_id, pin):
     bc = AgentNotifier()
     c = bc.dbconn.cursor(MySQLdb.cursors.DictCursor)
     c.execute('''SELECT SQL_NO_CACHE `reg_protocol`,`product_id`,`msisdn_destination`,
                 `agent_id`,`base_price`,`sell_price`,`status`,`order`,`deposit`,`type`
                 FROM `transaction` where `transaction_id`=%s''',
                 (tran_id,))
     r = c.fetchone()
     if not r:
         return json.dumps({'success': 0, 'reason': 'RECORD NOT FOUND'})
     if int(r['status']) == const.TR_RETRIED or \
                 int(r['status']) == const.TR_EXECUTED or \
                 int(r['status']) > const.TR_FAILED_GENERAL_REV:
         return json.dumps({'success': 0, 'reason': 'CANNOT SET STATUS'})
     if int(r['status']) >= const.TR_FAILED_HLR_REV and \
                 int(r['status']) <= const.TR_FAILED_GENERAL_REV :
         dm = DepositMutation(20, bc.dbconn, bc.cacheconn)
         dm.debit(r['agent_id'], r['sell_price'], 'Manual success {0}'.\
                   format(tran_id))
     c_agent_price = DBCache(const.AGENTPRICE_PREFIX, config.DEFAULT_EXPIRE, const.AGENTPRICE_SQL)
     owner = '{0:0>{1}}'.format(1, config.AGENT_ID_LENGTH)
     try:
         if r['agent_id'] != owner:
             fl = getFrontline(bc.dbconn, bc.cacheconn, r['agent_id'])
             if not fl:
                 self.logger.error('<countProfit> Frontline for agent {0} not found'.format(r['agent_id']))
                 raise
         else:
             fl = r['agent_id']
         ag = c_agent_price.sGet((fl, r['product_id'],))
         if not ag:
             self.logger.error('<countProfit> Price for agent {0} not found'.format(r['agent_id']))
             raise       
         profit = int(ag['sell_price']) - int(r['base_price'])
     except:
         profit = 0
     c.execute('''UPDATE `transaction` SET `status`=%s,`profit`=%s
                  WHERE `transaction_id`=%s''',
                  (const.TR_EXECUTED, profit, tran_id,))
     r['references'] = '0'
     bc.notifyTopupSucess(r)
     bc.dbconn.commit()
     return json.dumps({'success': 1, 'reason': 'SUCCESS'})
示例#5
0
文件: admin.py 项目: sridwan/meong
 def transaction_fail(self, tran_id, pin):
     bc = AgentNotifier()
     c = bc.dbconn.cursor(MySQLdb.cursors.DictCursor)
     c.execute('''SELECT SQL_NO_CACHE `reg_protocol`,`product_id`,`msisdn_destination`,
                 `agent_id`,`sell_price`,`status`,`order`,`deposit`,`type`
                 FROM `transaction` where `transaction_id`=%s''',
                 (tran_id,))
     r = c.fetchone()
     if not r:
         return json.dumps({'success': 0, 'reason': 'RECORD NOT FOUND'})
     if int(r['status']) < const.TR_AUTHORIZED or \
                 int(r['status']) >= const.TR_RETRIED:
         return json.dumps({'success': 0, 'reason': 'CANNOT SET STATUS'})
     dm = DepositMutation(20, bc.dbconn, bc.cacheconn)
     dm.credit(r['agent_id'], r['sell_price'], 'reversal Transaction {0}'.\
               format(tran_id))
     c.execute('UPDATE `transaction` set `status`=%s where `transaction_id`=%s',
               (const.TR_FAILED_GENERAL_REV, tran_id,))
     # r['deposit'] = int(r['deposit']) + int(r['sell_price'])
     bc.notifyTopupFail(r, False)
     bc.dbconn.commit()
     return json.dumps({'success': 1, 'reason': 'SUCCESS'})
示例#6
0
文件: admin.py 项目: sridwan/meong
 def deposit_transfer(self, agent_id_from, agent_id_to, amount,
                      order, pin):
     '''Transfer deposit from one agent to another'''
     bc = AgentNotifier()
     dt = deptran.DepositTransfer(10, bc.dbconn, bc.cacheconn)
     result = {
             'success': 0,
             'balance_from': 0,
             'balance_to': 0,
         }
     am = ManageAgentPrice(bc.dbconn, bc.cacheconn)
     tmp = am.verifyAgent(agent_id_from, 'xxxx')
     if tmp['code'] != agent.AGST_WRONGPIN:
         result['message'] = 'AGENT {0} ERROR'.format(agent_id_from)
         return json.dumps(result)
     tmp = am.verifyAgent(agent_id_to, 'xxxx')
     if tmp['code'] != agent.AGST_WRONGPIN:
         result['message'] = 'AGENT {0} ERROR'.format(agent_id_to)
         return json.dumps(result)
     if dt.searchSameTransfer(agent_id_from, agent_id_to, amount, order):
         result['message'] = 'TRANSFER EXIST'
         return json.dumps(result)
     tmp = dt.transfer(agent_id_from, agent_id_to, amount, order, True)
     response = {
             deptran.AMOUNT_ZERO: 'AMOUNT IS ZERO',
             deptran.NOT_ENOUGH_BALANCE: 'NOT ENOUGH BALANCE',
             deptran.AMOUNT_NOT_NUMBER: 'AMOUNT NOT NUMBER',
             deptran.OVER_REVOKE: 'OVER REVOKE',
             deptran.SOURCE_DEST_SAME: 'SOURCE IS THE SAME AS DESTINATION'
         }
     if tmp in response:
         result['message'] = response[tmp]
         return json.dumps(result)
     dm = DepositMutation(20, bc.dbconn, bc.cacheconn)
     result['balance_from'] = dm.getBalance(agent_id_from)
     result['balance_to'] = dm.getBalance(agent_id_to)
     result['message'] = 'SUCCESS'
     result['success'] = 1
     return json.dumps(result)
示例#7
0
 def __init__(self):
     BaseComponent.__init__(self, "AU")
     self.c_operator = DBCache(
         const.OPERATOR_PREFIX,
         config.DEFAULT_EXPIRE,
         const.OPERATOR_SQL,
         user_func={"prefix": lambda x: x.split(",")},
     )
     self.c_product = DBCache(const.PRODUCT_PREFIX, config.DEFAULT_EXPIRE, const.PRODUCT_SQL)
     self.c_agentprice = DBCache(const.AGENTPRICE_PREFIX, config.DEFAULT_EXPIRE, const.AGENTPRICE_SQL)
     self.dm = DepositMutation(5, self.dbconn, self.cacheconn)
     self.um = UnitMutation(5, self.dbconn, self.cacheconn)
     self.log = mylogger("Authorizer", "authorizer.log")
示例#8
0
    def setUp(self):
        self.bc = BaseComponent()
        self.dbconn = self.bc.dbconn
        self.cacheconn = self.bc.cacheconn
        self.cacheconn.delete('{0}_00001'.format(const.MUTATION_PREFIX))
        cursor = self.dbconn.cursor()
        self._resetTable('Deposit_Mutation')
        try:
            cursor.execute('''INSERT INTO `agent` (`agent_id`, `active`, `agent_name`,
              `agent_address`, `agent_type`, `pin`, `upline_id`, `markup`,
              `markup_upline`, `set_price`, `register_date`, `last_activity_date`,
              `last_update`, `last_update_by`) VALUES
              ('00001', 1, 'Bernard Martian', 'Test', 1, '9999', '', 100, 0, 'Test',
              '2010-11-09 18:24:44', '2010-11-09 18:24:51', '2010-11-24 00:50:12', '')''')
        except:
            pass
        cursor.close()
        self.dbconn.commit()

        self.c_agent = DBCache(const.AGENT_PREFIX, config.DEFAULT_EXPIRE,
          const.AGENT_SQL)
        self.c_agent.setConn(self.dbconn, self.cacheconn)
        self.dm = DepositMutation(2, self.dbconn, self.cacheconn)
示例#9
0
class TestDepositMutation(TestAdminHelper):
#----------------------
    def setUp(self):
        self.bc = BaseComponent()
        self.dbconn = self.bc.dbconn
        self.cacheconn = self.bc.cacheconn
        self.cacheconn.delete('{0}_00001'.format(const.MUTATION_PREFIX))
        cursor = self.dbconn.cursor()
        self._resetTable('Deposit_Mutation')
        try:
            cursor.execute('''INSERT INTO `agent` (`agent_id`, `active`, `agent_name`,
              `agent_address`, `agent_type`, `pin`, `upline_id`, `markup`,
              `markup_upline`, `set_price`, `register_date`, `last_activity_date`,
              `last_update`, `last_update_by`) VALUES
              ('00001', 1, 'Bernard Martian', 'Test', 1, '9999', '', 100, 0, 'Test',
              '2010-11-09 18:24:44', '2010-11-09 18:24:51', '2010-11-24 00:50:12', '')''')
        except:
            pass
        cursor.close()
        self.dbconn.commit()

        self.c_agent = DBCache(const.AGENT_PREFIX, config.DEFAULT_EXPIRE,
          const.AGENT_SQL)
        self.c_agent.setConn(self.dbconn, self.cacheconn)
        self.dm = DepositMutation(2, self.dbconn, self.cacheconn)
#----------------------
    def runTest(self):
        test_function = [x for x in dir(self) if x[:6] == 'srtest']
        map(lambda x: getattr(self, x)(), sorted(test_function))
#----------------------
    def srtest010(self):
        balance = self.dm.debit('00001', 10000, 'srtest010')
        self.dbconn.commit()
        self.assertEqual(balance, depmut.NOT_ENOUGH_BALANCE)
        balance = self.dm.credit('00001', 10000, 'srtest010')
        self.dbconn.commit()
        self.assertEqual(balance, 10000)
        balance = self.dm.debit('00001', 5000, 'srtest010')
        self.dbconn.commit()
        self.assertEqual(balance, 5000)
#----------------------
    def srtest020_lock(self):
        self.dm.l_mutation.lockNoWait(self.cacheconn, '00001')
        balance = self.dm.credit('00001', 10000, 'srtest010')
        self.assertEqual(balance, depmut.LOCK_FAILED)
        self.dm.l_mutation.release(self.cacheconn, '00001')
#----------------------
    def srtest030_adminHelperDepositMutation(self):
        post_data = {
          'agent_id': '00001',
          'type': 'D',
          'amount': 5000
        }
        tmp = self._callAdminHelper('deposit_mutation', post_data)
        self.assertEqual(tmp['success'], 1)
        self.assertEqual(tmp['balance'], 0)
        tmp = self._callAdminHelper('deposit_mutation', post_data)
        self.assertEqual(tmp['success'], 0)
        self.assertEqual(tmp['message'], 'NOT ENOUGH BALANCE')
        post_data['type'] = 'X'
        tmp = self._callAdminHelper('deposit_mutation', post_data)
        self.assertEqual(tmp['success'], 0)
        self.assertEqual(tmp['message'], 'TYPE NOT RECOGNIZED')
        post_data['agent_id'] = 'xxx'
        tmp = self._callAdminHelper('deposit_mutation', post_data)
        self.assertEqual(tmp['success'], 0)
        self.assertEqual(tmp['message'], 'AGENT NOT REGISTERED')
#----------------------
    def tearDown(self):
        self.cacheconn.delete('{0}_00001'.format(const.MUTATION_PREFIX))
        self.dbconn.close()
示例#10
0
class LoadBalance(AgentNotifier):
    """Process topup requests and balance them on available devices"""

    def __init__(self):
        super(LoadBalance, self).__init__("LB")
        self.operator = self._loadOperator()
        self.c_product = DBCache(const.PRODUCT_PREFIX, config.DEFAULT_EXPIRE, const.PRODUCT_SQL)
        self.c_op_product = DBCache(const.OP_PRODUCT_PREFIX, config.DEFAULT_EXPIRE, const.OP_PRODUCT_SQL)
        self.c_device = DBCache(const.DEVICES_PREFIX, config.DEFAULT_EXPIRE, const.DEVICES_SQL)
        self.c_base_price = DBCache(const.CHIP_BASE_PRICE_PREFIX, config.DEFAULT_EXPIRE, const.CHIP_BASE_PRICE_SQL)
        map(
            lambda x: x.setConn(self.dbconn, self.cacheconn),
            [self.c_product, self.c_op_product, self.c_device, self.c_base_price],
        )
        # self.hlr_cache = HLRCacheForLB(self.dbconn, self.cacheconn)
        # self.hlr_cache.cacheAllTopupDevice()
        self.lb = LBTopup(self.dbconn)
        self.lb.cleanRebuild()
        self.hm = HLRMap(self.dbconn, self.cacheconn)
        self.hm.rebuild()
        self.dm = DepositMutation(5, self.dbconn, self.cacheconn)
        self.last_op_prod = None
        self.last_device = None
        self.last_hlr_id = None
        self.last_tr_id = None
        self.last_tr_data = None
        self.change_method = None
        self.log = mylogger("LoadBalance", "loadbalance.log")

    def skipError(self):
        c = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        c.execute(
            """UPDATE `transaction` SET `status`=%s
                     WHERE `transaction_id`=%s""",
            (const.TR_FAILED_GENERAL, self.last_tr_id),
        )
        c.close()
        self.writeNotifyOut(
            "sms://08161940700",
            "general_message",
            {"message": "<LoadBalance>: Error while processing " "transaction {0}".format(self.last_tr_id)},
        )
        tr = self.last_tr_data
        tr["deposit"] = int(tr["deposit"]) + int(tr["sell_price"])
        self.notifyTopupFail(tr)
        self.dbconn.commit()
        print "Error while processing transaction {0}".format(self.last_tr_id)
        self.log.error("Error while processing transaction {0}".format(self.last_tr_id))

    def loadBalance(self):
        sql = """SELECT SQL_NO_CACHE `transaction_id`,`reg_protocol`,`agent_id`,
                 `product_id`,`operator_id`,`msisdn_destination`,`sell_price`,
                 `order`,`deposit` FROM `transaction`
                 WHERE `status`={0} and `method`='CH' LIMIT 100"""
        cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute(sql.format(const.TR_AUTHORIZED))
        rows = cursor.fetchall()
        if len(rows) == 0:
            cursor.close()
            return False
        for tran in rows:
            tr_id = tran["transaction_id"]
            self.last_tr_id = tr_id
            self.last_tr_data = dict(tran)
            dest_num = tran["msisdn_destination"]
            print "Topup id {2}, product {0} untuk nomor {1}".format(
                tran["product_id"], tran["msisdn_destination"], tran["transaction_id"]
            )
            self.log.info(
                "<loadBalance>Topup id {2}, product {0} untuk nomor {1}".format(
                    tran["product_id"], tran["msisdn_destination"], tran["transaction_id"]
                )
            )
            prod = self.c_product.sGet(tran["product_id"])
            if not prod:
                self.log.error(
                    '<loadBalance>Not found row in table "Product" ' "with product_id={0}".format(tran["product_id"])
                )
                continue
            op_id = prod["operator_id"]
            op_type = self.operator[op_id]["type"]
            opprod_list = self._extractOperatorProduct(prod)
            if op_type == "G":  # GSM
                result = self._executeTopupGSM(tr_id, op_id, opprod_list, dest_num)
                self.log.info(
                    "<loadBalance>Operator Product {1}\nTopup GSM {0}\nResult={2}".format(prod, opprod_list, result)
                )
            elif op_type == "C":  # CDMA
                result = self._executeTopupCDMA(tr_id, op_id, opprod_list, dest_num)
                self.log.info(
                    "<loadBalance>Operator Product {1}\nTopup CDMA {0}\nResult={2}".format(prod, opprod_list, result)
                )
            protocol = tran["reg_protocol"]
            if result == ET_SUCCESS:
                self._transactionInProgress(tr_id)
                if protocol[:3].lower() == "sms":
                    continue
                self.writeNotifyOut(
                    protocol, "transaction_in_progress", {"product_id": tran["product_id"], "dest": dest_num}
                )
                continue
            elif result == ET_CHANGE_METHOD:
                self._moveToNextMethod(tr_id, self.change_method)
                continue
            next_method = self._getNextMethod(prod)
            if next_method:
                self._moveToNextMethod(tr_id, next_method)
            elif result == ET_HLR_NOT_SUPPORTED:
                self._transactionResult(tr_id, const.TR_FAILED_HLR)
                self.writeNotifyOut(protocol, "hlr_not_supported", {"dest": dest_num})
            elif result == ET_OUT_OF_STOCK:
                self._transactionResult(tr_id, const.TR_OUT_OF_STOCK)
                agent_bal = int(tran["sell_price"]) + self.dm.getBalance(tran["agent_id"])
                self.writeNotifyOut(
                    protocol,
                    "out_of_stock",
                    {"product_id": tran["product_id"], "balance": thousandSeparator(agent_bal)},
                )
        cursor.close()
        self.dbconn.commit()
        return True

    def _moveToNextMethod(self, tr_id, method):
        cursor = self.dbconn.cursor()
        sql = """UPDATE `transaction` set `method`=%s, `hlr_id`=%s WHERE
            `transaction_id`=%s"""
        cursor.execute(sql, (method, self.last_hlr_id, tr_id))
        cursor.close()

    def _getNextMethod(self, prod):
        a = ("method_1_active", "method_2_active", "method_3_active", "method_4_active", "method_5_active")
        m = ("method_1", "method_2", "method_3", "method_4", "method_5")
        methods = map(lambda x: prod[x], [_m for _a, _m in zip(a, m) if prod[_a] == 1])
        try:
            i = methods.index("CH")
            if i >= (len(methods) - 1):
                return None
            return methods[i + 1]
        except:
            return None

    def _extractOperatorProduct(self, prod):
        result = []
        tmp = (
            "operator_product_id_1",
            "operator_product_id_2",
            "operator_product_id_3",
            "operator_product_id_4",
            "operator_product_id_5",
        )
        for i in tmp:
            if len(prod[i]) > 0:
                result.append(prod[i])
        return result

    def _transactionResult(self, tr_id, status):
        cursor = self.dbconn.cursor()
        sql = """UPDATE `transaction` set `status`=%s where `transaction_id`=%s"""
        cursor.execute(sql, (status, tr_id))
        cursor.close()

    def _transactionInProgress(self, tr_id):
        supplier_id = self.c_device.sGet(self.last_device)["supplier_id"]
        base_price = self.c_base_price.sGet((supplier_id, self.last_op_prod))["base_price"]
        cursor = self.dbconn.cursor()
        sql = """UPDATE `transaction` set `status`=%s, `operator_product_id`=%s,
            `device_id`=%s, `hlr_id`=%s, `supplier_id`=%s, `base_price`=%s where `transaction_id`=%s"""
        cursor.execute(
            sql,
            (
                const.TR_INPROGRESS,
                self.last_op_prod,
                self.last_device,
                self.last_hlr_id,
                supplier_id,
                base_price,
                tr_id,
            ),
        )
        cursor.close()

    def _executeTopupGSM(self, tr_id, op_id, prod_list, dest):
        hlr = dest[:8]
        result = self._executeTopup(tr_id, op_id, prod_list, dest, hlr)
        return result

    def _executeTopupCDMA(self, tr_id, op_id, prod_list, dest):
        hlr2 = dest[:4]
        return self._executeTopup(tr_id, op_id, prod_list, dest, hlr2)

    def _executeTopup(self, tr_id, op_id, prod_list, dest, hlr):
        """"""

        def stockOK(dev_id, prod_list):
            for prod_id in prod_list:
                op_prod = self.c_op_product.sGet(prod_id)
                if not self._checkUnitOrBalance(dev_id, op_prod):
                    continue
                else:
                    return op_prod
            return None

        hlr_id, method = self.hm.getHLRID2(op_id, hlr)
        if not hlr_id:
            hlr_id = 0
        elif method.upper() != "CH":
            self.change_method = method
            return ET_CHANGE_METHOD
        dev_list = self.lb.getLB(op_id, hlr_id)
        picked_dev_id = None
        for dev in dev_list:
            dev_id = dev["device_id"]
            op_prod = stockOK(dev_id, prod_list)
            if not op_prod:
                continue
            else:
                picked_dev_id = dev_id
                break
        if not picked_dev_id:
            return ET_OUT_OF_STOCK
        topup_parse = op_prod["topup_parse"]
        self._sendToLeaf(tr_id, dev_id, topup_parse, dest)
        self.last_op_prod = op_prod["operator_product_id"]
        self.last_device = picked_dev_id
        self.last_hlr_id = hlr_id
        self.lb.use(picked_dev_id)
        # print('ET_SUCCESS dev: {0}'.format(picked_dev_id))
        return ET_SUCCESS

    def _checkUnitOrBalance(self, dev_id, op_prod):
        """Check unit or balance of a chip"""

        def checkUnit(dev_id, prod_id):
            cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
            cursor.execute(
                "SELECT SQL_NO_CACHE `balance_unit` from `unit` WHERE "
                "`device_id`=%s and `operator_product_id`=%s LIMIT 1",
                (dev_id, prod_id),
            )
            r = cursor.fetchone()
            # print('<_checkUnitOrBalance - checkUnit> dev_id={1}, prod_id={2}, result={0}'.format(r, dev_id, prod_id))
            cursor.close()
            if not r:
                return False
            if int(r["balance_unit"]) < 1:
                return False
            return True

        def checkBalance(dev_id, amount):
            cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
            cursor.execute(
                "SELECT SQL_NO_CACHE `topup_balance` from `balance` " "WHERE `device_id`=%s LIMIT 1", (dev_id,)
            )
            r = cursor.fetchone()
            cursor.close()
            if not r:
                return False
            if int(r["topup_balance"]) < amount:
                return False
            return True

        if not op_prod:
            return False
        bal_type = op_prod["balance_flag"]
        unit_used = op_prod["unit_used"]
        # print('<_checkUnitOrBalance> bal_type={0}, unit_used={1}'.format(bal_type, unit_used))
        if bal_type.upper() == "U":
            if checkUnit(dev_id, unit_used):
                return True
        else:
            if checkBalance(dev_id, int(op_prod["topup_amount_chip"])):
                return True
        return False

    def _sendToLeaf(self, tran_id, dev_id, parse, dest):
        pin = self.c_device.sGet(dev_id)["pin"]
        server_id, port = dev_id.split(".")
        leaf_server = "{0}@{2}/{1}".format(config.LEAFSERVER, server_id, config.MSG_SERVER)
        parse = multipleReplace({"<dest>": dest, "<pin>": pin}, parse)
        # msg = '{0},{1},{2},{3},{4}'.format(port, tran_id, parse, dest, pin)
        msg = "{0}.{1},{2},{3}".format(server_id, port, tran_id, parse)
        self.sendMessage(leaf_server, "JBDV", msg, commit=False)

    def _loadOperator(self):
        """Get self.operator"""
        result = {}
        cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute(
            """SELECT `operator_id`,`operator_name`,`type`,`prefix`
        FROM `operator` order by `operator_id` ASC"""
        )
        for op in cursor:
            op["prefix"] = op["prefix"].split(",")
            result[op["operator_id"]] = op
        cursor.close()
        return result
示例#11
0
 def setUp(self):
     super(TestAuthorizer, self).setUp()
     self.cacheconn.flush_all()
     cursor = self.dbconn.cursor()
     self._resetTable('Transaction')
     self._resetTable('Notify_Out')
     self._resetTable('Deposit_Mutation')
     cursor.execute('DELETE FROM `operator`')
     cursor.execute('''INSERT INTO `operator` (`operator_id`, `operator_name`, `type`, `prefix`, `stock_check_1`, `stock_check_2`, `sim_balance`, `last_update`, `last_update_by`) VALUES
       (1, 'Telkomsel', 'G', '0812,0813,0852,0853', 'ussd://*776*<pin>#', 'ussd://*676*<pin>#', 'ussd://*888#', '2010-11-17 17:34:44', ''),
       (2, 'Indosat', 'G', '0814,0815,0816,0855,0856,0857,0858', 'data://31.<pin>$', '', 'ussd://*388#', '2010-10-29 18:52:34', ''),
       (3, 'XL', 'G', '0817,0818,0819,0859,0877,0878', 'sms://balance,461', '', 'ussd://*123#', '2010-10-29 18:52:48', ''),
       (4, 'Three', 'G', '0894,0896,0898,0899', 'data://+13.<pin>$', '', '', '2010-10-20 15:08:41', ''),
       (5, 'Axis', 'G', '0831,0832,0833,0838', 'data://13.<pin>$', '', '', '2010-10-20 15:08:36', ''),
       (6, 'Fren', 'G', '0888,0889', '', '', '', '0000-00-00 00:00:00', ''),
       (7, 'Esia', 'C', '4,6,8,9', 'sms:// bal <pin>,898', '', 'sms://talktime,555', '2010-11-17 20:52:29', ''),
       (8, 'Flexi', 'C', '2,3,4,5,6,7,8,9', 'sms://qd#<pin,899', '', '', '2010-10-20 15:10:59', ''),
       (9, 'StarOne', 'C', '3,8', '', '', '', '0000-00-00 00:00:00', ''),
       (10, 'Hepi', 'C', '3,4,5', '', '', '', '0000-00-00 00:00:00', ''),
       (11, 'Smart', 'G', '0881,0882,0883,0884,0885,0886,0887', '', '', '', '0000-00-00 00:00:00', '')''')
     cursor.execute('DELETE FROM `agent_price`')
     cursor.execute('''INSERT INTO `agent_price` (`agent_id`, `product_id`,
       `sell_price`, `markup_upline`, `date_time`, `status`, `last_update`,
       `last_update_by`) VALUES
       ('00001', 'A10', 10150, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'A5', 5150, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'AP10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'AP5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'AX10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'AX20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'AX50', 50100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'E25', 25100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'E50', 50100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'F10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'F20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'F5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'FR10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'FR20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'FR25', 25100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'H10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'H25', 25100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'H5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'M10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'M5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'S10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'S5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SM10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SM20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SM5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SO10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SO20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SO5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SP10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'SP5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'T10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'T20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'T5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'X10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
       ('00001', 'X5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', '')''')
     cursor.execute('DELETE FROM `product`')
     cursor.execute('''INSERT INTO `product` (`product_id`, `product_name`, `operator_id`, `active`, `point`, `operator_product_id_1`, `operator_product_id_2`, `operator_product_id_3`, `operator_product_id_4`, `operator_product_id_5`, `method_1`, `method_1_active`, `method_2`, `method_2_active`, `method_3`, `method_3_active`, `method_4`, `method_4_active`, `method_5`, `method_5_active`, `last_update`, `last_update_by`) VALUES
       ('A10', 'As 10.000', 1, 1, 1, 'SIMPATI10', 'AS10', '', '', '', 'CH', 1, 'H2', 0, 'YM', 0, '', 0, '', 0, '2010-07-08 18:48:06', ''),
       ('A5', 'As 5.000', 1, 1, 1, 'SIMPATI5', 'AS5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:07', ''),
       ('AP10', 'As 10.000 Promo', 1, 1, 1, 'AS5', 'SIMPATI5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:08', ''),
       ('AP5', 'As 5.000 Promo', 1, 0, 1, 'AS5', 'SIMPATI5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:08', ''),
       ('AX10', 'Axis 10.000', 5, 1, 1, 'AXIS10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:09', ''),
       ('AX20', 'Axis 20.000', 5, 1, 1, 'AXIS20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:10', ''),
       ('AX50', 'Axis 50.000', 5, 1, 1, 'AXIS50', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:10', ''),
       ('BR5', 'Broom 5.000', 2, 1, 1, 'INDOSAT5BROOM', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '0000-00-00 00:00:00', ''),
       ('E25', 'Esia 25.000', 7, 1, 1, 'ESIA25', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:11', ''),
       ('E50', 'Esia 50.000', 7, 1, 1, 'ESIA50', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:11', ''),
       ('F10', 'Flexi 10.000', 8, 1, 1, 'FLEXI10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:12', ''),
       ('F20', 'Flexi 20.000', 8, 1, 1, 'FLEXI20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:16', ''),
       ('F5', 'Flexi 5.000', 8, 1, 1, 'FLEXI5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:17', ''),
       ('FR10', 'Fren 10.000', 6, 1, 1, 'FREN10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:17', ''),
       ('FR20', 'Fren 20.000', 6, 1, 1, 'FREN20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:18', ''),
       ('FR25', 'Fren 25.000', 6, 1, 1, 'FREN25', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:19', ''),
       ('H10', 'Hepi 10.000', 10, 1, 1, 'HEPI10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:19', ''),
       ('H25', 'Hepi 25.000', 10, 1, 1, 'HEPI25', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:20', ''),
       ('H5', 'Hepi 5.000', 10, 1, 1, 'HEPI5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:20', ''),
       ('M10', 'Mentari 10.000', 2, 1, 1, 'MENTARI10', 'IM10', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:21', ''),
       ('M5', 'Mentari 5.000', 2, 1, 1, 'MENTARI5', 'IM5', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:22', ''),
       ('S10', 'Simpati 10.000', 1, 1, 1, 'SIMPATI10', 'AS10', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:22', ''),
       ('S5', 'Simpati 5.000', 1, 1, 1, 'SIMPATI5', 'AS5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:23', ''),
       ('SM10', 'Smart 10.000', 11, 1, 1, 'SMART10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:24', ''),
       ('SM20', 'Smart 20.000', 11, 1, 1, 'SMART20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:24', ''),
       ('SM5', 'Smart 5.000', 11, 1, 1, 'SMART5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:25', ''),
       ('SO10', 'StarOne 10.000', 9, 1, 1, 'SO10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:26', ''),
       ('SO20', 'StarOne 20.000', 9, 1, 1, 'SO20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:26', ''),
       ('SO5', 'StarOne 5.000', 9, 1, 1, 'SO5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:27', ''),
       ('SP10', 'Simpati 10.000 Promo', 1, 1, 1, 'SIMPATI10', 'AS10', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:27', ''),
       ('SP5', 'Simpati 5.000 Promo', 1, 1, 1, 'SIMPATI5', 'AS5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:28', ''),
       ('T10', 'Three 10.000', 4, 1, 1, 'THREE10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:29', ''),
       ('T20', 'Three 20.000', 4, 1, 1, 'THREE20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:29', ''),
       ('T5', 'Three 5.000', 4, 1, 1, 'THREE5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:30', ''),
       ('X10', 'XL 10.000', 3, 1, 1, 'XL10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:31', ''),
       ('X25', 'XL 25.000', 3, 1, 1, 'XL25', '', '', '', '', '', 0, '', 0, '', 0, '', 0, '', 0, '0000-00-00 00:00:00', ''),
       ('X5', 'XL 5.000', 3, 1, 1, 'XL5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:31', '')''')
     cursor.close()
     self.dbconn.commit()
     self._createProcess(_prAuthorizer)
     self.ids = []
     self.c_message = DBCache(const.MESSAGE_PREFIX, config.DEFAULT_EXPIRE,
       const.MESSAGE_SQL)
     self.c_message.setConn(self.dbconn, self.cacheconn)
     self.idgen = range(50)
     self.deposit = DepositMutation(1, self.dbconn, self.cacheconn)
     self.deposit.credit('00001', 25000, 'setup credit', True)
示例#12
0
class TestAuthorizer(TestCoreComponent):
    def setUp(self):
        super(TestAuthorizer, self).setUp()
        self.cacheconn.flush_all()
        cursor = self.dbconn.cursor()
        self._resetTable('Transaction')
        self._resetTable('Notify_Out')
        self._resetTable('Deposit_Mutation')
        cursor.execute('DELETE FROM `operator`')
        cursor.execute('''INSERT INTO `operator` (`operator_id`, `operator_name`, `type`, `prefix`, `stock_check_1`, `stock_check_2`, `sim_balance`, `last_update`, `last_update_by`) VALUES
          (1, 'Telkomsel', 'G', '0812,0813,0852,0853', 'ussd://*776*<pin>#', 'ussd://*676*<pin>#', 'ussd://*888#', '2010-11-17 17:34:44', ''),
          (2, 'Indosat', 'G', '0814,0815,0816,0855,0856,0857,0858', 'data://31.<pin>$', '', 'ussd://*388#', '2010-10-29 18:52:34', ''),
          (3, 'XL', 'G', '0817,0818,0819,0859,0877,0878', 'sms://balance,461', '', 'ussd://*123#', '2010-10-29 18:52:48', ''),
          (4, 'Three', 'G', '0894,0896,0898,0899', 'data://+13.<pin>$', '', '', '2010-10-20 15:08:41', ''),
          (5, 'Axis', 'G', '0831,0832,0833,0838', 'data://13.<pin>$', '', '', '2010-10-20 15:08:36', ''),
          (6, 'Fren', 'G', '0888,0889', '', '', '', '0000-00-00 00:00:00', ''),
          (7, 'Esia', 'C', '4,6,8,9', 'sms:// bal <pin>,898', '', 'sms://talktime,555', '2010-11-17 20:52:29', ''),
          (8, 'Flexi', 'C', '2,3,4,5,6,7,8,9', 'sms://qd#<pin,899', '', '', '2010-10-20 15:10:59', ''),
          (9, 'StarOne', 'C', '3,8', '', '', '', '0000-00-00 00:00:00', ''),
          (10, 'Hepi', 'C', '3,4,5', '', '', '', '0000-00-00 00:00:00', ''),
          (11, 'Smart', 'G', '0881,0882,0883,0884,0885,0886,0887', '', '', '', '0000-00-00 00:00:00', '')''')
        cursor.execute('DELETE FROM `agent_price`')
        cursor.execute('''INSERT INTO `agent_price` (`agent_id`, `product_id`,
          `sell_price`, `markup_upline`, `date_time`, `status`, `last_update`,
          `last_update_by`) VALUES
          ('00001', 'A10', 10150, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'A5', 5150, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'AP10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'AP5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'AX10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'AX20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'AX50', 50100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'E25', 25100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'E50', 50100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'F10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'F20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'F5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'FR10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'FR20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'FR25', 25100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'H10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'H25', 25100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'H5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'M10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'M5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'S10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'S5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SM10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SM20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SM5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SO10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SO20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SO5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SP10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'SP5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'T10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'T20', 20100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'T5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'X10', 10100, 0, NULL, 1, '0000-00-00 00:00:00', ''),
          ('00001', 'X5', 5100, 0, NULL, 1, '0000-00-00 00:00:00', '')''')
        cursor.execute('DELETE FROM `product`')
        cursor.execute('''INSERT INTO `product` (`product_id`, `product_name`, `operator_id`, `active`, `point`, `operator_product_id_1`, `operator_product_id_2`, `operator_product_id_3`, `operator_product_id_4`, `operator_product_id_5`, `method_1`, `method_1_active`, `method_2`, `method_2_active`, `method_3`, `method_3_active`, `method_4`, `method_4_active`, `method_5`, `method_5_active`, `last_update`, `last_update_by`) VALUES
          ('A10', 'As 10.000', 1, 1, 1, 'SIMPATI10', 'AS10', '', '', '', 'CH', 1, 'H2', 0, 'YM', 0, '', 0, '', 0, '2010-07-08 18:48:06', ''),
          ('A5', 'As 5.000', 1, 1, 1, 'SIMPATI5', 'AS5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:07', ''),
          ('AP10', 'As 10.000 Promo', 1, 1, 1, 'AS5', 'SIMPATI5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:08', ''),
          ('AP5', 'As 5.000 Promo', 1, 0, 1, 'AS5', 'SIMPATI5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:08', ''),
          ('AX10', 'Axis 10.000', 5, 1, 1, 'AXIS10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:09', ''),
          ('AX20', 'Axis 20.000', 5, 1, 1, 'AXIS20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:10', ''),
          ('AX50', 'Axis 50.000', 5, 1, 1, 'AXIS50', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:10', ''),
          ('BR5', 'Broom 5.000', 2, 1, 1, 'INDOSAT5BROOM', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '0000-00-00 00:00:00', ''),
          ('E25', 'Esia 25.000', 7, 1, 1, 'ESIA25', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:11', ''),
          ('E50', 'Esia 50.000', 7, 1, 1, 'ESIA50', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:11', ''),
          ('F10', 'Flexi 10.000', 8, 1, 1, 'FLEXI10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:12', ''),
          ('F20', 'Flexi 20.000', 8, 1, 1, 'FLEXI20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:16', ''),
          ('F5', 'Flexi 5.000', 8, 1, 1, 'FLEXI5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:17', ''),
          ('FR10', 'Fren 10.000', 6, 1, 1, 'FREN10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:17', ''),
          ('FR20', 'Fren 20.000', 6, 1, 1, 'FREN20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:18', ''),
          ('FR25', 'Fren 25.000', 6, 1, 1, 'FREN25', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:19', ''),
          ('H10', 'Hepi 10.000', 10, 1, 1, 'HEPI10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:19', ''),
          ('H25', 'Hepi 25.000', 10, 1, 1, 'HEPI25', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:20', ''),
          ('H5', 'Hepi 5.000', 10, 1, 1, 'HEPI5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:20', ''),
          ('M10', 'Mentari 10.000', 2, 1, 1, 'MENTARI10', 'IM10', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:21', ''),
          ('M5', 'Mentari 5.000', 2, 1, 1, 'MENTARI5', 'IM5', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:22', ''),
          ('S10', 'Simpati 10.000', 1, 1, 1, 'SIMPATI10', 'AS10', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:22', ''),
          ('S5', 'Simpati 5.000', 1, 1, 1, 'SIMPATI5', 'AS5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:23', ''),
          ('SM10', 'Smart 10.000', 11, 1, 1, 'SMART10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:24', ''),
          ('SM20', 'Smart 20.000', 11, 1, 1, 'SMART20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:24', ''),
          ('SM5', 'Smart 5.000', 11, 1, 1, 'SMART5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:25', ''),
          ('SO10', 'StarOne 10.000', 9, 1, 1, 'SO10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:26', ''),
          ('SO20', 'StarOne 20.000', 9, 1, 1, 'SO20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:26', ''),
          ('SO5', 'StarOne 5.000', 9, 1, 1, 'SO5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:27', ''),
          ('SP10', 'Simpati 10.000 Promo', 1, 1, 1, 'SIMPATI10', 'AS10', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:27', ''),
          ('SP5', 'Simpati 5.000 Promo', 1, 1, 1, 'SIMPATI5', 'AS5', '', '', '', 'CH', 1, 'H2', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:28', ''),
          ('T10', 'Three 10.000', 4, 1, 1, 'THREE10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:29', ''),
          ('T20', 'Three 20.000', 4, 1, 1, 'THREE20', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:29', ''),
          ('T5', 'Three 5.000', 4, 1, 1, 'THREE5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:30', ''),
          ('X10', 'XL 10.000', 3, 1, 1, 'XL10', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:31', ''),
          ('X25', 'XL 25.000', 3, 1, 1, 'XL25', '', '', '', '', '', 0, '', 0, '', 0, '', 0, '', 0, '0000-00-00 00:00:00', ''),
          ('X5', 'XL 5.000', 3, 1, 1, 'XL5', '', '', '', '', 'CH', 1, '', 0, '', 0, '', 0, '', 0, '2010-07-08 18:48:31', '')''')
        cursor.close()
        self.dbconn.commit()
        self._createProcess(_prAuthorizer)
        self.ids = []
        self.c_message = DBCache(const.MESSAGE_PREFIX, config.DEFAULT_EXPIRE,
          const.MESSAGE_SQL)
        self.c_message.setConn(self.dbconn, self.cacheconn)
        self.idgen = range(50)
        self.deposit = DepositMutation(1, self.dbconn, self.cacheconn)
        self.deposit.credit('00001', 25000, 'setup credit', True)
#----------------------
    def runTest(self):
        test_function = [x for x in dir(self) if x[:6] == 'srtest']
        map(lambda x: getattr(self, x)(), sorted(test_function))
#----------------------
    def srtest10_authorized(self):  # TR_AUTHORIZED
        self.newRequest(('1', '00001', 'sms://08161940700', 'A10', '08128191891', 1, 0, 1))
        t = self._waitForRow('SELECT `status` from `transaction` WHERE '
          '`transaction_id`="1" and `status`={0}'.format(const.TR_AUTHORIZED))
        self.assertEqual(t, {'status': const.TR_AUTHORIZED})
        t = self._waitForRow('SELECT `mutation`,`type`,`deposit_balance` FROM '
          '`deposit_mutation` where `deposit_balance`=14850 and `agent_id`="00001"')
        self.assertEqual(t, {'mutation': 10150, 'type': "D", 'deposit_balance': 14850})
#----------------------
    def srtest20_wrong_number(self):  # TR_DENIED_WRONG_NUMBER
        self.newRequest(('2', '00001', 'sms://08161940700', 'A10', '08168191891', 1, 0, 1))
        t = self._waitForRow('SELECT `status` from `transaction` WHERE '
          '`transaction_id`="2" and `status`={0}'.format(const.TR_DENIED_WRONG_NUMBER))
        self.assertEqual(t, {'status': const.TR_DENIED_WRONG_NUMBER})
        t = self._waitForRow('SELECT `command` from `notify_out` where `parameters` '
          'LIKE "sms://08161940700,% 08168191891 %"')
        self.assertEqual(t, {'command': 'SMSG'})
#----------------------
    def srtest30_denied_product(self):  # TR_DENIED_PRODUCT
        self.newRequest(('3', '00001', 'sms://08161940700', 'XXX10', '08168191891', 1, 0, 2))
        self.newRequest(('4', '00001', 'sms://08161940700', 'AP5', '08168191891', 1, 0, 1))
        t = self._waitForRow('SELECT `status` from `transaction` WHERE '
          '`transaction_id`="3" and `status`={0}'.format(const.TR_DENIED_PRODUCT))
        self.assertEqual(t, {'status': const.TR_DENIED_PRODUCT})
        t = self._waitForRow('SELECT `command` from `notify_out` where `parameters` '
          'LIKE "sms://08161940700,% XXX10 %"')
        self.assertEqual(t, {'command': 'SMSG'})
        t = self._waitForRow('SELECT `status` from `transaction` WHERE '
          '`transaction_id`="4" and `status`={0}'.format(const.TR_DENIED_PRODUCT))
        self.assertEqual(t, {'status': const.TR_DENIED_PRODUCT})
        t = self._waitForRow('SELECT `command` from `notify_out` where `parameters` '
          'LIKE "sms://08161940700,% AP5 %"')
        self.assertEqual(t, {'command': 'SMSG'})
        t = self._waitForRow('SELECT COUNT(*) FROM `deposit_mutation`')
        self.assertEqual(t, {'COUNT(*)': 3})
#----------------------
    def srtest40_denied_balance(self):  # TR_DENIED_BALANCE
        self.newRequest(('5', '00001', 'sms://08161940700', 'AX50', '0838000111', 1, 0, 5))
        t = self._waitForRow('SELECT `status` from `transaction` WHERE '
          '`transaction_id`="5" and `status`={0}'.format(const.TR_DENIED_BALANCE))
        self.assertEqual(t, {'status': const.TR_DENIED_BALANCE})
        t = self._waitForRow('SELECT `command` from `notify_out` where `parameters` '
          'LIKE "sms://08161940700,% AX50 %"')
        self.assertEqual(t, {'command': 'SMSG'})
#----------------------
    def newRequest(self, p):
        cursor = self.dbconn.cursor()
        cursor.execute('INSERT INTO `transaction` (`transaction_id`,`agent_id`,'
          '`reg_protocol`,`product_id`,`msisdn_destination`,`order`,`status`,`operator_id`) '
          'VALUES (%s,%s,%s,%s,%s,%s,%s,%s)', p)
        cursor.close()
        self.dbconn.commit()
#----------------------
    def getMessage(self, msg, tosub={}):
        tmp = self.c_message.sGet(msg)['parse']
        tosub = dict(zip(map(lambda x: '<{0}>'.format(x),tosub.keys()),
          map(str,tosub.values())))
        if tosub == {}:
            return tmp
        return multipleReplace(tosub, tmp)
示例#13
0
class Authorizer(BaseComponent):
    """Authorize Topup Request
    """

    def __init__(self):
        BaseComponent.__init__(self, "AU")
        self.c_operator = DBCache(
            const.OPERATOR_PREFIX,
            config.DEFAULT_EXPIRE,
            const.OPERATOR_SQL,
            user_func={"prefix": lambda x: x.split(",")},
        )
        self.c_product = DBCache(const.PRODUCT_PREFIX, config.DEFAULT_EXPIRE, const.PRODUCT_SQL)
        self.c_agentprice = DBCache(const.AGENTPRICE_PREFIX, config.DEFAULT_EXPIRE, const.AGENTPRICE_SQL)
        self.dm = DepositMutation(5, self.dbconn, self.cacheconn)
        self.um = UnitMutation(5, self.dbconn, self.cacheconn)
        self.log = mylogger("Authorizer", "authorizer.log")

    def authorize(self):
        requests = self.checkTopupRequest()
        if len(requests) == 0:
            return False
        for req in requests:
            agent_id, product_id = (req["agent_id"], req["product_id"])
            tr_id, op_id = (req["transaction_id"], req["operator_id"])
            prod_status, prod = self.checkProduct(product_id)
            if prod_status != PRODUCT_AVAILABLE:
                # self.productNotAvailable(req['reg_protocol'], product_id, prod_status)
                self.productNotAvailable(req["reg_protocol"], product_id)
                self.setDenied(tr_id, const.TR_DENIED_PRODUCT)
                continue
            ptype = int(prod["type"])
            if ptype in (1, 3):
                num_status, op_name = self.checkDestination(op_id, req["msisdn_destination"])
                if num_status != DEST_OP_MATCH:
                    self.destOperatorDontMatch(req["reg_protocol"], req["msisdn_destination"], op_name)
                    self.setDenied(tr_id, const.TR_DENIED_WRONG_NUMBER)
                    continue
            if ptype in (1, 2, 3):
                prod_price, markup = self.getPriceForAgent(agent_id, product_id)
                if not prod_price:
                    self.productNotAvailable(req["reg_protocol"], product_id)
                    self.setDenied(tr_id, const.TR_DENIED_PRODUCT)
                    continue
            if ptype in (1, 2):
                bal_stat, balance = self.deductBalance(agent_id, prod_price, tr_id)
            if ptype == 3:
                balance = self.um.debit(agent_id, product_id, 1, tr_id, "Topup {0}".format(tr_id))
                if balance in (NOT_ENOUGH_BALANCE, LOCK_FAILED):
                    bal_stat = BALANCE_NOT_ENOUGH
                    balance = 0
            if bal_stat != BALANCE_OK:
                self.notEnoughBalance(req["reg_protocol"], product_id, balance, req["msisdn_destination"])
                self.setDeniedBalance(tr_id, const.TR_DENIED_BALANCE, balance)
                continue
            self.setAuthorized(tr_id, prod_price, balance, markup)
        self.dbconn.commit()
        return True

    def checkTopupRequest(self):
        cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute(
            "SELECT SQL_NO_CACHE `transaction_id`,`agent_id`,"
            "`product_id`,`reg_protocol`,`msisdn_destination`,`operator_id` "
            "FROM `transaction` where `status`={0} LIMIT 100".format(const.TR_WAIT)
        )
        requests = cursor.fetchall()
        cursor.close()
        return requests

    def checkProduct(self, prodid):
        prod = self.c_product.get(self.dbconn, self.cacheconn, prodid)
        if not prod:
            return (PRODUCT_NOT_REGISTERED, None)
        if prod["active"] == 0:
            return (PRODUCT_NOT_SOLD, None)
        return (PRODUCT_AVAILABLE, prod)

    def checkDestination(self, op_id, dest):
        opdata = self.c_operator.get(self.dbconn, self.cacheconn, op_id)
        if opdata == None:
            print "No data for operator id {0}".format(op_id)
            self.log.critical("No data for operator id {0}".format(op_id))
            return None
        try:
            if opdata["type"] == "G":
                if dest[0:4] in opdata["prefix"]:
                    return (DEST_OP_MATCH, opdata["operator_name"])
                else:
                    return (DEST_OP_DONT_MATCH, opdata["operator_name"])
            elif opdata["type"] == "C":
                if (dest[3] in opdata["prefix"]) or (dest[4] in opdata["prefix"]):
                    return (DEST_OP_MATCH, opdata["operator_name"])
                else:
                    return (DEST_OP_DONT_MATCH, opdata["operator_name"])
        except:
            return (DEST_OP_DONT_MATCH, opdata["operator_name"])

    def deductBalance(self, agentid, price, tuid):
        balance = self.dm.getBalance(agentid)
        if balance < price:
            return (BALANCE_NOT_ENOUGH, balance)
        balance = self.dm.debit(agentid, price, "Topup {0}".format(tuid))
        if balance == LOCK_FAILED:
            return (BALANCE_NOT_ENOUGH, 0)
        return (BALANCE_OK, balance)

    def setAuthorized(self, ids, price, balance, markup):
        cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute(
            """UPDATE `transaction` set `status`={0}, `sell_price`=%s,
        `deposit`=%s, `markup_margin`=%s where `transaction_id`=%s""".format(
                const.TR_AUTHORIZED
            ),
            (price, balance, markup, ids),
        )
        cursor.close()

    def setDenied(self, ids, status):
        cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute("UPDATE `transaction` set `status`={0} " "WHERE `transaction_id`=%s".format(status), (ids,))
        cursor.close()

    def setDeniedBalance(self, ids, status, balance):
        cursor = self.dbconn.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute(
            "UPDATE `transaction` set `status`={0}," "`deposit`=%s where `transaction_id`=%s".format(status),
            (balance, ids),
        )
        cursor.close()

    def getPriceForAgent(self, agentid, prodid):
        ap = self.c_agentprice.get(self.dbconn, self.cacheconn, (agentid, prodid))
        if not ap:
            self.log.warning(
                "<getPriceForAgent> price not found for agent " "{0} and product {1}".format(agentid, prodid)
            )
            return (None, None)
        return (int(ap["sell_price"]), int(ap["markup_upline"]))

    def productNotAvailable(self, prot, prodid):
        self.writeNotifyOut(prot, "prod_not_registered", {"product_id": prodid})

    def notEnoughBalance(self, prot, prodid, balance, dest):
        self.writeNotifyOut(
            prot,
            "agent_not_enough_balance",
            {"product_id": prodid, "balance": thousandSeparator(balance), "dest": dest},
        )

    def destOperatorDontMatch(self, prot, num, opname):
        self.writeNotifyOut(prot, "num_op_dont_match", {"dest": num, "operator": opname})