def pause(self, account_number, **kwargs): """用户账号停机 :param account_number: 用户账号 :type account_number: string """ try: if not account_number: raise ValueError(u'账号不能为空') account = self.db.query(models.TrAccount).get(account_number) if account.status != 1: raise ValueError(u'用户当前状态不允许停机') _datetime = utils.get_currtime() account.last_pause = _datetime account.status = 2 account.sync_ver = tools.gen_sync_ver() accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'pause' accept_log.accept_source = 'console' accept_log.accept_desc = u'用户停机:上网账号:%s' % account_number accept_log.account_number = account.account_number accept_log.accept_time = _datetime accept_log.operator_name = self.operator.username accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] self.db.add(accept_log) self.db.commit() dispatch.pub(evset.ACCOUNT_PAUSE_EVENT, account.account_number, async=True) dispatch.pub(evset.CACHE_DELETE_EVENT, account_cache_key(account.account_number), async=True) for online in self.db.query(models.TrOnline).filter_by(account_number=account_number): dispatch.pub(evset.UNLOCK_ONLINE_EVENT, account_number, online.nas_addr, online.acct_session_id, async=True) return True except Exception as err: self.db.rollback() self.last_error = u'用户停机失败:%s' % utils.safeunicode(err.message) logger.error(self.last_error, tag='account_pause_error', username=account_number) return False
def event_ppmf_user_renew(self, account_number, product_id): with make_db(self.db) as db: try: account = db.query(models.TrAccount).get(account_number) product = db.query(models.TrProduct).get(product_id) if not product: logger.error(u'执行流量包月续费时,用户[%s]资费id[%s]不存在' % (account_number, product_id)) return if product.fee_price > account.balance: logger.error(u'执行流量包月续费时,用户[%s]余额不足' % account_number) return old_balance = account.balance old_flows = account.flow_length account.balance -= product.fee_price account.flow_length = product.fee_flows account.sync_ver = tools.gen_sync_ver() accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'auto_renew' accept_log.accept_source = 'task' accept_log.account_number = account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = 'admin' accept_log.accept_desc = u'用户[%s]流量包月套餐续费, 续费前余额为(%s)元,流量为(%s)G,续费后余额为(%s)元,流量为(%s)G' % ( account_number, utils.fen2yuan(old_balance), utils.kb2gb(old_flows), utils.fen2yuan( account.balance), utils.kb2gb(account.flow_length)) accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) self.db.commit() logger.info(u'用户[%s]流量包月套餐续费完成' % account_number, trace='event') except Exception as err: logger.exception(err) logger.error(u'用户[%s]流量包月套餐续费失败' % account_number, trace='event')
def resume(self, account_number, **kwargs): """用户账号复机 :param account_number: 用户账号 :type account_number: string """ try: if not account_number: raise ValueError(u'账号不能为空') account = self.db.query(models.TrAccount).get(account_number) node_id = self.db.query(models.TrCustomer.node_id).filter(models.TrCustomer.customer_id == models.TrAccount.customer_id, models.TrAccount.account_number == account_number).scalar() if account.status != 2: return self.render_json(code=1, msg=u'用户当前状态不允许复机') account.status = 1 _datetime = datetime.datetime.now() _pause_time = datetime.datetime.strptime(account.last_pause, '%Y-%m-%d %H:%M:%S') _expire_date = datetime.datetime.strptime(account.expire_date + ' 23:59:59', '%Y-%m-%d %H:%M:%S') days = (_expire_date - _pause_time).days new_expire = (_datetime + datetime.timedelta(days=int(days))).strftime('%Y-%m-%d') account.expire_date = new_expire account.sync_ver = tools.gen_sync_ver() accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'resume' accept_log.accept_source = 'console' accept_log.accept_desc = u'用户复机:上网账号:%s' % account_number accept_log.account_number = account.account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = self.operator.username accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] self.db.add(accept_log) self.db.commit() return True except Exception as err: self.db.rollback() self.last_error = u'用户停机失败:%s' % utils.safeunicode(err.message) logger.error(self.last_error, tag='account_resume_error', username=account_number) return False
def post(self): node_cache = {} area_cache = {} product_cache = {} accounts = [ a.account_number for a in self.db.query(models.TrAccount.account_number) ] iform = customer_forms.customer_import_form() f = self.request.files['import_file'][0] try: impctx = utils.safeunicode(f['body']) except Exception as err: logger.exception(err) self.render_error(msg=u'文件格式错误: %s' % utils.safeunicode(err)) return lines = impctx.split('\n') _num = 0 impusers = [] for line in lines: _num += 1 line = line.strip() if not line or u'用户姓名' in line: continue attr_array = line.split(',') if len(attr_array) < 13: return self.render('customer_import_form.html', form=iform, msg=u'第 %s 行错误: 用户字段必须是14个 ' % _num) if attr_array[7] in accounts: continue vform = customer_forms.customer_import_vform() vform.fill(**dict(realname=utils.safeunicode(attr_array[0]), node=utils.safeunicode(attr_array[1]), area=utils.safeunicode(attr_array[2]), product=utils.safeunicode(attr_array[3]), idcard=attr_array[4], mobile=attr_array[5], address=utils.safeunicode(attr_array[6]), account_number=attr_array[7], password=attr_array[8], begin_date=attr_array[9], expire_date=attr_array[10], time_length=utils.hour2sec(attr_array[11]), flow_length=utils.mb2kb(attr_array[12]))) impusers.append(vform) _unums = 0 for form in impusers: try: node_id = self.get_node_id(form.d.node, node_cache) if not node_id: raise ValueError(u'区域:%s不存在' % utils.safeunicode(form.d.node)) area_id = self.get_area_id(form.d.area, area_cache) if not area_id: raise ValueError(u'社区:%s不存在' % utils.safeunicode(form.d.area)) product_id = self.get_product_id(form.d.product, product_cache) if not product_id: raise ValueError(u'资费:%s不存在' % utils.safeunicode(form.d.product)) customer = models.TrCustomer() customer.customer_id = utils.get_uuid() customer.node_id = node_id customer.area_id = area_id customer.realname = form.d.realname customer.idcard = form.d.idcard customer.customer_name = form.d.account_number customer.password = md5(form.d.password.encode()).hexdigest() customer.sex = '1' customer.age = '0' customer.email = '' customer.mobile = form.d.mobile customer.address = form.d.address customer.create_time = form.d.begin_date + ' 00:00:00' customer.update_time = utils.get_currtime() customer.email_active = 0 customer.mobile_active = 0 customer.active_code = utils.get_uuid() customer.sync_ver = tools.gen_sync_ver() self.db.add(customer) accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'open' accept_log.accept_source = 'console' _desc = u'用户导入账号:%s' % form.d.account_number accept_log.accept_desc = _desc accept_log.account_number = form.d.account_number accept_log.accept_time = customer.update_time accept_log.operator_name = self.current_user.username accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) self.db.flush() self.db.refresh(accept_log) order_fee = 0 actual_fee = 0 balance = 0 time_length = 0 flow_length = 0 expire_date = form.d.expire_date product = self.db.query(models.TrProduct).get(product_id) if product.product_policy == BOTimes: time_length = utils.hour2sec(form.d.time_length) elif product.product_policy == BOFlows: flow_length = utils.gb2kb(form.d.flow_length) elif product.product_policy in (PPTimes, PPFlow): balance = utils.yuan2fen(form.d.balance) expire_date = MAX_EXPIRE_DATE order = models.TrCustomerOrder() order.id = utils.get_uuid() order.order_id = utils.gen_order_id() order.customer_id = customer.customer_id order.product_id = product.id order.account_number = form.d.account_number order.order_fee = order_fee order.actual_fee = actual_fee order.pay_status = 1 order.accept_id = accept_log.id order.order_source = 'console' order.create_time = customer.update_time order.order_desc = u'用户导入开户' order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.sync_ver = tools.gen_sync_ver() self.db.add(order) account = models.TrAccount() account.id = utils.get_uuid() account.account_number = form.d.account_number account.customer_id = customer.customer_id account.product_id = order.product_id account.install_address = customer.address account.ip_address = '' account.mac_addr = '' account.password = self.aes.encrypt(form.d.password) account.status = 1 account.balance = 0 account.time_length = time_length account.flow_length = flow_length account.expire_date = expire_date account.user_concur_number = product.concur_number account.bind_mac = product.bind_mac account.bind_vlan = product.bind_vlan account.vlan_id1 = 0 account.vlan_id2 = 0 account.create_time = customer.create_time account.update_time = customer.update_time account.sync_ver = tools.gen_sync_ver() self.db.add(account) _unums += 1 except Exception as e: self.db.rollback() logger.exception(e) return self.render('customer_import_form.html', form=iform, msg=u'导入数据错误 : %s' % utils.safeunicode(e)) self.add_oplog(u'导入开户,用户数:%s' % _unums) self.db.commit() self.redirect('/admin/customer')
def batch_add(self, formdata, **kwargs): try: opennum = int(formdata.get('opennum', 100)) if opennum > 1000: opennum = 1000 user_prefix = formdata.get( 'user_prefix', datetime.datetime.now().strftime('%Y%m%d')) suffix_len = int(formdata.get('suffix_len', 4)) start_num = int(formdata.get('start_num', 1)) pwd_type = int(formdata.get('pwd_type', 0)) password = formdata.get('password', None) product_id = self.parse_arg(formdata, 'product_id', rule=rules.not_null) expire_date = self.parse_arg(formdata, 'expire_date', rule=rules.is_date) node_id = self.parse_arg(formdata, 'node_id', rule=rules.not_null) area_id = self.parse_arg(formdata, 'area_id', defval='') for num in xrange(start_num, opennum + start_num): account_number = '%s%s' % ( user_prefix, string.rjust(str(num), suffix_len, '0')) customer = models.TrCustomer() customer.customer_id = utils.get_uuid() customer.node_id = node_id customer.area_id = area_id customer.agency_id = None customer.realname = account_number customer.customer_name = account_number customer.password = md5(str(random.randint( 999999, 99999999))).hexdigest() customer.idcard = '' customer.sex = '1' customer.age = '0' customer.email = '' customer.mobile = '000000' customer.address = '' customer.create_time = utils.get_currtime() customer.update_time = utils.get_currtime() customer.email_active = 0 customer.mobile_active = 0 customer.active_code = utils.get_uuid() customer.customer_desc = u'批量生成客户' customer.sync_ver = tools.gen_sync_ver() self.db.add(customer) accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'open' accept_log.accept_source = 'console' accept_log.account_number = account_number accept_log.accept_time = customer.create_time accept_log.operator_name = self.operator.operator_name accept_log.accept_desc = u'用户新开户:%s' % customer.customer_name accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) product = self.db.query(models.TrProduct).get(product_id) order = models.TrCustomerOrder() order.order_id = utils.get_uuid() order.customer_id = customer.customer_id order.product_id = product.id order.account_number = account_number if product.product_policy in (PPTimes, PPFlow, PPMonth, PPDay): order.order_fee = 0 else: order.order_fee = product.fee_price order.actual_fee = 0 order.pay_status = 1 order.accept_id = accept_log.id order.order_source = accept_log.accept_source order.create_time = customer.create_time order.order_desc = u'用户批量开通账号' order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.sync_ver = tools.gen_sync_ver() self.db.add(order) account = models.TrAccount() account.account_number = account_number account.ip_address = '' account.customer_id = customer.customer_id account.product_id = order.product_id account.install_address = '' account.mac_addr = '' if pwd_type == 1 and password not in (None, ''): account.password = self.aes.encrypt(password) else: account.password = self.aes.encrypt( str(random.randint(999999, 9999999))) account.status = 0 account.balance = 0 account.time_length = int(product.fee_times) account.flow_length = int(product.fee_flows) account.expire_date = expire_date account.user_concur_number = product.concur_number account.bind_mac = product.bind_mac account.bind_vlan = product.bind_vlan account.vlan_id1 = 0 account.vlan_id2 = 0 account.create_time = customer.create_time account.update_time = customer.create_time account.account_desc = customer.customer_desc account.sync_ver = tools.gen_sync_ver() self.db.add(account) self.add_oplog(u'批量开户总数 %s' % opennum) self.db.commit() return True except Exception as err: self.db.rollback() logger.exception(err, tag='customer_batch_add_error') traceback.print_exc() self.last_error = u'批量开户操作失败:%s' % utils.safeunicode(err.message) return False return
def add(self, formdata, **kwargs): """用户开户 :param formdata: 用户开户参数表 :type formdata: dict formdata params: :param account_number: 用户账号 :type account_number: string :param billing_type: 计费模式,0 首次上线计费 1 立即计费 :type billing_type: int :param customer_id: 客户ID,16-32位字符串(可选) :type customer_id: string :param order_id: 交易ID,16-32位字符串(可选) :type order_id: string :param product_id: 订购资费ID :type product_id: string :param node_id: 用户区域ID :type node_id: string :param area_id: 用户社区ID(可选) :type area_id: string :param agency_id: 代理商ID(可选) :type agency_id: string :param realname: 用户姓名 :type realname: string :param password: 用户账号密码 :type password: string :param ip_address: 用户IP地址 :type ip_address: string :param idcard: 用户身份证号码(可选) :type idcard: string :param email: 用户电子邮箱(可选) :type email: string :param mobile: 用户手机号码(可选) :type mobile: string :param address: 用户地址(可选) :type address: string :param customer_desc: 用户描述备注(可选) :type customer_desc: string :param accept_source: 用户受理来源(可选) :type accept_source: string :param expire_date: 用户到期时间 yyyy-mm-dd :type expire_date: string :param months: 用户订购月数,预付费包月有效 :type days: int :param days: 用户订购天数,预付费包日有效 :type months: int :param fee_value: 交易费用 x.xx 元 :type fee_value: string :param giftflows: 赠送流量 x.xx GB :type giftflows: string :param giftdays: 赠送天数 :type giftdays: int :param charge_code: 收费项目编码 :type charge_code: string :param builder_name: 服务人员名 :type builder_name: string :param vcard_code: 充值卡 :type vcard_code: string :param vcard_pwd: 充值卡密码 :type vcard_pwd: string """ try: account_number = self.parse_arg(formdata, 'account_number', rule=rules.not_null) account_number = account_number.strip() formdata['account_number'] = account_number billing_type = int(formdata.get('billing_type', 1)) pay_status = int(formdata.get('pay_status', 1)) customer_id = self.parse_arg(formdata, 'customer_id', defval=utils.get_uuid()) order_id = self.parse_arg(formdata, 'order_id', defval=utils.get_uuid(), rule=rules.not_null) product_id = self.parse_arg(formdata, 'product_id', rule=rules.not_null) node_id = self.parse_arg(formdata, 'node_id', rule=rules.not_null) area_id = self.parse_arg(formdata, 'area_id', defval='') agency_id = self.parse_arg(formdata, 'agency_id', defval='') realname = self.parse_arg(formdata, 'realname', defval=account_number) realname = realname or account_number password = self.parse_arg(formdata, 'password', rule=rules.not_null) ip_address = self.parse_arg(formdata, 'ip_address', defval='') idcard = self.parse_arg(formdata, 'idcard', defval='') sex = self.parse_arg(formdata, 'sex', defval='1') age = self.parse_arg(formdata, 'age', defval='0') email = self.parse_arg(formdata, 'email', defval='') mobile = self.parse_arg(formdata, 'mobile', defval='') address = self.parse_arg(formdata, 'address', defval='') customer_desc = self.parse_arg(formdata, 'customer_desc', defval='') accept_source = self.parse_arg(formdata, 'accept_source', defval='console') expire_date = self.parse_arg(formdata, 'expire_date', rule=rules.is_date) months = self.parse_arg(formdata, 'months', defval='0', rule=rules.is_number) days = self.parse_arg(formdata, 'days', defval='0', rule=rules.is_number) fee_value = self.parse_arg(formdata, 'fee_value', rule=rules.is_rmb) giftflows = self.parse_arg(formdata, 'giftflows', defval='0', rule=rules.is_number3) giftdays = self.parse_arg(formdata, 'giftdays', defval='0', rule=rules.is_number) charge_code = self.parse_arg(formdata, 'charge_code', defval='') builder_name = self.parse_arg(formdata, 'builder_name', defval='') status = self.parse_arg(formdata, 'status', defval='1', rule=rules.is_number) wechat_oid = self.parse_arg(formdata, 'wechat_oid', defval='') vcard_code = self.parse_arg(formdata, 'vcard_code', defval='') vcard_pwd = self.parse_arg(formdata, 'vcard_pwd', defval='') if not self.check_data(formdata): return False product = self.db.query(models.TrProduct).get(product_id) vcard = None if vcard_code and vcard_pwd: vcard = self.db.query(models.TrValCard).get(vcard_code) if not self.check_vcard(vcard, vcard_pwd, product): return False if hasattr(self.operator, 'agency_id') and self.operator.agency_id is not None: agency_id = self.operator.agency_id customer = models.TrCustomer() customer.customer_id = customer_id customer.node_id = node_id customer.area_id = area_id customer.agency_id = agency_id customer.realname = utils.safeunicode(realname) customer.customer_name = account_number customer.password = md5(password.encode()).hexdigest() customer.idcard = idcard customer.sex = sex customer.age = age customer.email = email customer.mobile = mobile customer.address = address customer.create_time = utils.get_currtime() customer.update_time = utils.get_currtime() customer.email_active = 0 customer.mobile_active = 0 customer.active_code = utils.get_uuid() customer.customer_desc = customer_desc customer.wechat_oid = wechat_oid customer.sync_ver = tools.gen_sync_ver() self.db.add(customer) accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'open' accept_log.accept_source = accept_source accept_log.account_number = account_number accept_log.accept_time = customer.create_time accept_log.operator_name = self.operator.operator_name accept_log.accept_desc = u'用户新开户:(%s)%s' % (customer.customer_name, customer.realname) accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) order_fee = 0 balance = 0 expire_date = expire_date flow_length = 0 if product.product_policy == PPMonth: order_fee = decimal.Decimal( product.fee_price) * decimal.Decimal(months) order_fee = int(order_fee.to_integral_value()) if product.product_policy == PPDay: order_fee = decimal.Decimal( product.fee_price) * decimal.Decimal(days) order_fee = int(order_fee.to_integral_value()) elif product.product_policy == APMonth: order_fee = 0 elif product.product_policy in (BOMonth, BODay): order_fee = int(product.fee_price) elif product.product_policy == BOFlows: order_fee = int(product.fee_price) flow_length = int(product.fee_flows) order = models.TrCustomerOrder() order.order_id = order_id order.customer_id = customer.customer_id order.product_id = product.id order.account_number = account_number order.order_fee = order_fee order.actual_fee = utils.yuan2fen(fee_value) order.pay_status = pay_status order.accept_id = accept_log.id order.order_source = accept_log.accept_source order.create_time = customer.create_time order.order_desc = u'用户新开账号' order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.sync_ver = tools.gen_sync_ver() self.db.add(order) if vcard: vcard.status = 2 vcard.use_time = utils.get_currtime() vcard.customer_id = customer.customer_id if agency_id and pay_status == 1: agency = self.db.query(models.TrAgency).get(agency_id) if agency.amount < order.actual_fee: self.last_error = u'代理商预存款余额不足' return False agency_share = models.TrAgencyShare() agency_share.id = utils.get_uuid() agency_share.agency_id = agency_id agency_share.order_id = order.order_id agency_share.share_rate = agency.share_rate sfee = decimal.Decimal(order.actual_fee) * decimal.Decimal( agency.share_rate) / decimal.Decimal(100) sfee = int(sfee.to_integral_value()) agency_share.share_fee = sfee agency_share.create_time = utils.get_currtime() agency_share.sync_ver = tools.gen_sync_ver() self.db.add(agency_share) agency.amount -= order.actual_fee aorder = models.TrAgencyOrder() aorder.id = utils.get_uuid() aorder.agency_id = agency.id aorder.fee_type = 'cost' aorder.fee_value = -order.actual_fee aorder.fee_total = agency.amount aorder.fee_desc = u'用户 %s 开通扣费' % account_number aorder.create_time = agency_share.create_time aorder.sync_ver = tools.gen_sync_ver() self.db.add(aorder) agency.amount += agency_share.share_fee aorder2 = models.TrAgencyOrder() aorder2.id = utils.get_uuid() aorder2.agency_id = agency.id aorder2.fee_type = 'share' aorder2.fee_value = agency_share.share_fee aorder2.fee_total = agency.amount aorder2.fee_desc = u'用户 %s 开通分成(%s%%)' % (account_number, agency.share_rate) aorder2.create_time = agency_share.create_time aorder2.sync_ver = tools.gen_sync_ver() self.db.add(aorder2) charge_value = 0 if charge_code: charge_log = models.TrChargeLog() charge_log.id = utils.get_uuid() charge_log.order_id = order.order_id charge_log.charge_code = charge_code charge_log.operator_name = accept_log.operator_name charge_log.operate_time = order.create_time charge_log.sync_ver = tools.gen_sync_ver() self.db.add(charge_log) charge_value = int( self.db.query( models.TrCharges).get(charge_code).charge_value or 0) account = models.TrAccount() account.account_number = account_number account.ip_address = ip_address account.customer_id = customer.customer_id account.product_id = order.product_id account.install_address = customer.address account.mac_addr = '' account.password = self.aes.encrypt(password) account.status = status if billing_type == 0: account.status = UsrPreAuth if pay_status == 0: account.status = UsrPadding account.balance = balance - charge_value account.time_length = int(product.fee_times) account.flow_length = flow_length account.expire_date = expire_date account.user_concur_number = product.concur_number account.bind_mac = product.bind_mac account.bind_vlan = product.bind_vlan account.vlan_id1 = 0 account.vlan_id2 = 0 account.create_time = customer.create_time account.update_time = customer.create_time account.account_desc = customer.customer_desc account.sync_ver = tools.gen_sync_ver() self.db.add(account) if pay_status == 0: order.before_account_data = self.warp_account_data( account, status=UsrPadding) order.after_account_data = self.warp_account_data(account, status=1) order.order_desc = u'用户新开账号,赠送天数:%s, 收费项金额:%s' % ( giftdays, utils.fen2yuan(charge_value)) issues = None builder_phone = None if builder_name and pay_status == 1: builder_phone = self.db.query( models.TrBuilder.builder_phone).filter_by( builder_name=builder_name).scalar() issues = models.TrIssues() issues.id = utils.get_uuid() issues.account_number = account.account_number issues.issues_type = '0' issues.content = u'用户新开账号, 请前往安装' issues.builder_name = builder_name issues.status = 0 issues.operator_name = self.operator.operator_name issues.date_time = utils.get_currtime() issues.sync_ver = tools.gen_sync_ver() self.db.add(issues) opsdesc = u'用户新开账号 %s, 赠送天数:%s, 收费项金额:%s' % ( account.account_number, giftdays, utils.fen2yuan(charge_value)) self.add_oplog(opsdesc) self.db.commit() dispatch.pub(ACCOUNT_OPEN_EVENT, account.account_number, async=True) if issues and builder_phone: dispatch.pub(ISSUES_ASSIGN_EVENT, issues.account_number, builder_phone, async=True) self.update_routeros_sync_event(account_number, password, product_id, node_id) return True except Exception as err: self.db.rollback() traceback.print_exc() self.last_error = u'客户开户操作失败:%s' % utils.safeunicode(err) logger.error(self.last_error, tag='customer_add_error', username=formdata.get('account_number')) return False return
def change(self, formdata, **kwargs): """用户资费变更 :param formdata: 用户续费参数表 :type formdata: dict formdata params: :param account_number: 用户账号 :type account_number: string :param product_id: 变更后的资费ID :type product_id: string :param expire_date: 变更后的到期时间 yyyy-mm-dd :type expire_date: string :param balance: 变更后的余额 x.xx 元 :type balance: string :param time_length: 变更后的剩余时长-小时 :type time_length: string :param flow_length: 变更后的剩余流量-GB :type flow_length: string :param add_value: 变更费用 x.xx 元 :type add_value: string :param operate_desc: 变更说明 :type operate_desc: string """ try: account_number = self.parse_arg(formdata, 'account_number', rule=rules.not_null) product_id = self.parse_arg(formdata, 'product_id', rule=rules.not_null) expire_date = self.parse_arg(formdata, 'expire_date', rule=rules.is_date) balance = self.parse_arg(formdata, 'balance', rule=rules.is_rmb) add_value = self.parse_arg(formdata, 'add_value', rule=rules.is_rmb) time_length = self.parse_arg(formdata, 'time_length', rule=rules.is_number3) flow_length = self.parse_arg(formdata, 'flow_length', rule=rules.is_number3) operate_desc = self.parse_arg(formdata, 'operate_desc') account = self.db.query(models.TrAccount).get(account_number) if account.status not in (1, 4): raise ValueError(u'无效用户状态') node_id = self.db.query(models.TrCustomer.node_id).filter(models.TrCustomer.customer_id == models.TrAccount.customer_id, models.TrAccount.account_number == account_number).scalar() product = self.db.query(models.TrProduct).get(product_id) accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'change' accept_log.accept_source = 'console' accept_log.account_number = account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = self.operator.operator_name accept_log.accept_desc = u'用户资费变更为:%s;%s' % (product.product_name, utils.safeunicode(operate_desc)) accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) old_exoire_date = account.expire_date account.product_id = product.id if product.product_policy in (PPMonth, BOMonth, PPDay, BODay): account.expire_date = expire_date account.balance = 0 account.time_length = 0 account.flow_length = 0 elif product.product_policy in (PPTimes, PPFlow): account.expire_date = MAX_EXPIRE_DATE account.balance = utils.yuan2fen(balance) account.time_length = 0 account.flow_length = 0 elif product.product_policy == BOTimes: account.expire_date = MAX_EXPIRE_DATE account.balance = 0 account.time_length = utils.hour2sec(time_length) account.flow_length = 0 elif product.product_policy == BOFlows: account.expire_date = MAX_EXPIRE_DATE account.balance = 0 account.time_length = 0 account.flow_length = utils.gb2kb(flow_length) account.sync_ver = tools.gen_sync_ver() order = models.TrCustomerOrder() order.order_id = utils.gen_order_id() order.customer_id = account.customer_id order.product_id = account.product_id order.account_number = account.account_number order.order_fee = 0 order.actual_fee = utils.yuan2fen(add_value) order.pay_status = 1 order.accept_id = accept_log.id order.order_source = 'console' order.create_time = utils.get_currtime() order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.order_desc = u'用户变更资费,变更前到期:%s,变更后到期:%s' % (old_exoire_date, account.expire_date) order.sync_ver = tools.gen_sync_ver() self.db.add(order) agency_id = self.db.query(models.TrCustomer.agency_id).filter_by(customer_id=account.customer_id).scalar() if agency_id and order.actual_fee > 0: agency = self.db.query(models.TrAgency).get(agency_id) if agency.amount < order.actual_fee: raise ValueError(u'代理商预存款余额不足') agency_share = models.TrAgencyShare() agency_share.id = utils.get_uuid() agency_share.agency_id = agency_id agency_share.order_id = order.order_id agency_share.share_rate = agency.share_rate sfee = decimal.Decimal(order.actual_fee) * decimal.Decimal(agency.share_rate) / decimal.Decimal(100) sfee = int(sfee.to_integral_value()) agency_share.share_fee = sfee agency_share.create_time = utils.get_currtime() agency_share.sync_ver = tools.gen_sync_ver() self.db.add(agency_share) agency.amount -= order.actual_fee agency.sync_ver = tools.gen_sync_ver() aorder = models.TrAgencyOrder() aorder.id = utils.get_uuid() aorder.agency_id = agency.id aorder.fee_type = 'cost' aorder.fee_value = -order.actual_fee aorder.fee_total = agency.amount aorder.fee_desc = u'用户 %s 资费变更扣费' % account_number aorder.create_time = agency_share.create_time aorder.sync_ver = tools.gen_sync_ver() self.db.add(aorder) agency.amount += agency_share.share_fee aorder2 = models.TrAgencyOrder() aorder2.id = utils.get_uuid() aorder2.agency_id = agency.id aorder2.fee_type = 'share' aorder2.fee_value = agency_share.share_fee aorder2.fee_total = agency.amount aorder2.fee_desc = u'用户 %s 变更资费分成(%s%%)' % (account_number, agency.share_rate) aorder2.create_time = agency_share.create_time aorder2.sync_ver = tools.gen_sync_ver() self.db.add(aorder2) self.add_oplog(accept_log.accept_desc) self.db.commit() dispatch.pub(redis_cache.CACHE_DELETE_EVENT, account_cache_key(account.account_number), async=True) return True except Exception as err: self.db.rollback() self.last_error = u'用户资费变更失败:%s' % utils.safeunicode(err) logger.error(self.last_error, tag='account_change_error', username=formdata.get('account_number')) return False
def cancel(self, formdata, **kwargs): """用户销户,将用户状态设置为销户状态,账号不可用,不删除用户数据,数据保留用做查询统计。 :param formdata: 用户销户参数表 :type formdata: dict formdata params: :param account_number: 用户账号 :type account_number: string :param operate_desc: 操作描述 :type operate_desc: string :param fee_value: 费用金额(元) x.xx :type fee_value: string """ try: account_number = self.parse_arg(formdata, 'account_number', rule=rules.not_null) fee_value = self.parse_arg(formdata, 'fee_value', rule=rules.is_rmb) operate_desc = self.parse_arg(formdata, 'operate_desc', defval='') account = self.db.query(models.TrAccount).get(account_number) if account.status != 1: raise ValueError(u'无效用户状态') accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'cancel' accept_log.accept_source = 'console' accept_log.account_number = account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = self.operator.operator_name accept_log.accept_desc = u'用户销户退费%s(元);%s' % ( fee_value, utils.safeunicode(operate_desc)) accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) old_expire_date = account.expire_date order = models.TrCustomerOrder() order.id = utils.get_uuid() order.order_id = utils.gen_order_id() order.customer_id = account.customer_id order.product_id = account.product_id order.account_number = account_number order.order_fee = 0 order.actual_fee = -utils.yuan2fen(fee_value) order.pay_status = 1 order.order_source = 'console' order.accept_id = accept_log.id order.create_time = utils.get_currtime() order.order_desc = accept_log.accept_desc order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.sync_ver = tools.gen_sync_ver() self.db.add(order) account.status = 3 agency_id = self.db.query(models.TrCustomer.agency_id).filter_by( customer_id=account.customer_id).scalar() if agency_id: agency = self.db.query(models.TrAgency).get(agency_id) sfee = decimal.Decimal(order.actual_fee) * decimal.Decimal( agency.share_rate) / decimal.Decimal(100) sfee = int(sfee.to_integral_value()) if agency.amount < sfee: raise ValueError(u'代理商预存款余额不足') agency.amount -= -sfee aorder = models.TrAgencyOrder() aorder.id = utils.get_uuid() aorder.agency_id = agency.id aorder.fee_type = 'sharecost' aorder.fee_value = sfee aorder.fee_total = agency.amount aorder.fee_desc = u'用户 %s 销户退费分摊(%s%%) %s 元' % ( account_number, agency.share_rate, utils.fen2yuan(aorder.fee_value)) aorder.create_time = utils.get_currtime() order.sync_ver = tools.gen_sync_ver() self.db.add(aorder) self.db.commit() dispatch.pub(ACCOUNT_CHANNEL_EVENT, account.account_number, async=True) dispatch.pub(redis_cache.CACHE_DELETE_EVENT, account_cache_key(account.account_number), async=True) for online in self.db.query(models.TrOnline).filter_by( account_number=account.account_number): dispatch.pub(UNLOCK_ONLINE_EVENT, online.account_number, online.nas_addr, online.acct_session_id, async=True) return True except Exception as err: self.db.rollback() self.last_error = u'用户销户失败:%s, %s' % (utils.safeunicode( err.message), err.__class__) logger.error(self.last_error, tag='account_cancel_error', username=formdata.get('account_number')) return False
def renew(self, formdata, **kwargs): """用户续费 :param formdata: 用户续费参数表 :type formdata: dict formdata params: :param account_number: 用户账号 :type account_number: string :param operate_desc: 操作描述 :type operate_desc: string :param fee_value: 费用金额(元) x.xx :type fee_value: string :param months: 订购月数,预付费包月有效 :type months: int :param giftdays: 赠送天数 :type giftdays: int :param expire_date: 到期时间 yyyy-mm-dd :type expire_date: string :param order_id: 订单号(可选) 16-32位字符串 :type order_id: string """ try: account_number = self.parse_arg(formdata, 'account_number', rule=rules.not_null) product_id = self.parse_arg(formdata, 'product_id', rule=rules.not_null) operate_desc = self.parse_arg(formdata, 'operate_desc', defval='') fee_value = self.parse_arg(formdata, 'fee_value', rule=rules.is_rmb) months = self.parse_arg(formdata, 'months', defval='0', rule=rules.is_number) days = self.parse_arg(formdata, 'days', defval='0', rule=rules.is_number) giftdays = self.parse_arg(formdata, 'giftdays', defval='0', rule=rules.is_number) expire_date = self.parse_arg(formdata, 'expire_date', rule=rules.is_date) order_id = self.parse_arg(formdata, 'order_id', defval=utils.gen_order_id(), rule=rules.not_null) vcard_code = self.parse_arg(formdata, 'vcard_code', defval='') vcard_pwd = self.parse_arg(formdata, 'vcard_pwd', defval='') account = self.db.query(models.TrAccount).get(account_number) if account.status in (3, 4, 5): raise ValueError(u'无效用户状态') node_id = self.db.query(models.TrCustomer.node_id).filter( models.TrCustomer.customer_id == models.TrAccount.customer_id, models.TrAccount.account_number == account_number).scalar() product = self.db.query(models.TrProduct).get(account.product_id) vcard = None if vcard_code and vcard_pwd: vcard = self.db.query(models.TrValCard).get(vcard_code) if not self.check_vcard(vcard, vcard_pwd, product): return False accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'next' accept_log.accept_source = 'console' accept_log.accept_desc = u'用户续费:上网账号:%s,续费%s元;%s' % ( account_number, fee_value, utils.safeunicode(operate_desc)) accept_log.account_number = account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = self.operator.operator_name accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) order_fee = 0 if product.product_policy == PPMonth: order_fee = decimal.Decimal( product.fee_price) * decimal.Decimal(months) order_fee = int(order_fee.to_integral_value()) if product.product_policy == PPDay: order_fee = decimal.Decimal( product.fee_price) * decimal.Decimal(days) order_fee = int(order_fee.to_integral_value()) elif product.product_policy in (BOMonth, BOTimes, BOFlows, BODay): order_fee = int(product.fee_price) order = models.TrCustomerOrder() order.id = utils.get_uuid() order.order_id = order_id order.customer_id = account.customer_id order.product_id = product_id order.account_number = account_number order.order_fee = order_fee order.actual_fee = utils.yuan2fen(fee_value) order.pay_status = 1 order.accept_id = accept_log.id order.order_source = 'console' order.create_time = utils.get_currtime() order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.sync_ver = tools.gen_sync_ver() if vcard: vcard.status = 2 vcard.use_time = utils.get_currtime() vcard.customer_id = account.customer_id agency_id = self.db.query(models.TrCustomer.agency_id).filter_by( customer_id=account.customer_id).scalar() if agency_id and order.actual_fee > 0: agency = self.db.query(models.TrAgency).get(agency_id) if agency.amount < order.actual_fee: raise ValueError(u'代理商预存款余额不足') agency_share = models.TrAgencyShare() agency_share.id = utils.get_uuid() agency_share.agency_id = agency_id agency_share.order_id = order.order_id agency_share.share_rate = agency.share_rate sfee = decimal.Decimal(order.actual_fee) * decimal.Decimal( agency.share_rate) / decimal.Decimal(100) sfee = int(sfee.to_integral_value()) agency_share.share_fee = sfee agency_share.create_time = utils.get_currtime() agency_share.sync_ver = tools.gen_sync_ver() self.db.add(agency_share) agency.amount -= order.actual_fee aorder = models.TrAgencyOrder() aorder.id = utils.get_uuid() aorder.agency_id = agency.id aorder.fee_type = 'cost' aorder.fee_value = -order.actual_fee aorder.fee_total = agency.amount aorder.fee_desc = u'用户 %s 续费扣费' % account_number aorder.create_time = agency_share.create_time aorder.sync_ver = tools.gen_sync_ver() self.db.add(aorder) agency.amount += agency_share.share_fee aorder2 = models.TrAgencyOrder() aorder2.id = utils.get_uuid() aorder2.agency_id = agency.id aorder2.fee_type = 'share' aorder2.fee_value = agency_share.share_fee aorder2.fee_total = agency.amount aorder2.fee_desc = u'用户 %s 续费分成(%s%%)' % (account_number, agency.share_rate) aorder2.create_time = agency_share.create_time aorder2.sync_ver = tools.gen_sync_ver() self.db.add(aorder2) if product_id != account.product_id: account.product_id = product_id old_expire_date = account.expire_date if account.status != UsrPreAuth: account.status = 1 account.expire_date = expire_date if product.product_policy == BOTimes: account.time_length += product.fee_times elif product.product_policy == BOFlows: account.flow_length += product.fee_flows account.sync_ver = tools.gen_sync_ver() order.order_desc = u'用户续费,续费前到期:%s,续费后到期:%s, 赠送天数: %s' % ( old_expire_date, account.expire_date, giftdays) self.db.add(order) self.add_oplog(order.order_desc) self.db.commit() dispatch.pub(ACCOUNT_NEXT_EVENT, order.account_number, async=True) dispatch.pub(redis_cache.CACHE_DELETE_EVENT, account_cache_key(account.account_number), async=True) return True except Exception as err: self.db.rollback() self.last_error = u'用户续费失败:%s' % utils.safeunicode(err) logger.error(self.last_error, tag='account_renew_error', username=formdata.get('account_number')) return False return
def event_apm_user_billing(self, account_number): logger.info(u'用户[%s]后付费自动出账任务执行' % account_number) with make_db(self.db) as db: try: account = db.query(models.TrAccount).get(account_number) product = db.query(models.TrProduct).get(account.product_id) fee_precision = self.get_param_value('billing_fee_precision', 'fen') if not product: logger.error(u'执行后付费包月自动出账时,用户[%s]资费id[%s]不存在' % (account_number, product_id)) return accept_log = models.TrAcceptLog() accept_log.id = utils.get_uuid() accept_log.accept_type = 'apm_bill' accept_log.accept_source = 'task' accept_log.account_number = account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = 'admin' accept_log.accept_desc = u'用户[%s]后付费包月自动出账, ' % account_number accept_log.stat_year = accept_log.accept_time[0:4] accept_log.stat_month = accept_log.accept_time[0:7] accept_log.stat_day = accept_log.accept_time[0:10] accept_log.sync_ver = tools.gen_sync_ver() self.db.add(accept_log) order = models.TrCustomerOrder() order.order_id = utils.get_uuid() order.customer_id = account.customer_id order.product_id = product.id order.account_number = account_number order.order_fee = product.fee_price order_bill_fee = product.fee_price order_bill_days = 30 per_day_fee = decimal.Decimal(product.fee_price) / order_bill_days per_day_fee_yuan = utils.fen2yuan(int(per_day_fee.to_integral_value())) this_month_start_str = datetime.datetime.now().strftime('%Y-%m-01 %H:%M:%S') this_month_start = datetime.datetime.strptime(this_month_start_str, '%Y-%m-%d %H:%M:%S') pre_month_start_str = utils.add_months(datetime.datetime.now(), -1).strftime('%Y-%m-01 00:00:00') pre_month_start = datetime.datetime.strptime(pre_month_start_str, '%Y-%m-%d %H:%M:%S') pre_month_end = this_month_start - datetime.timedelta(days=1) pre_month_days = (pre_month_end - pre_month_start).days + 1 user_create_time = datetime.datetime.strptime(account.create_time, '%Y-%m-%d %H:%M:%S') if user_create_time > pre_month_start: order_bill_days = (pre_month_end - user_create_time).days per_day_fee = decimal.Decimal(product.fee_price) / decimal.Decimal(pre_month_days) per_day_fee_yuan = utils.fen2yuan(int(per_day_fee.to_integral_value())) order_bill_fee = int((per_day_fee * order_bill_days).to_integral_value()) if fee_precision == 'yuan': order_bill_fee = int((decimal.Decimal(order_bill_fee) / decimal.Decimal(100)).to_integral_value()) * 100 order.actual_fee = order_bill_fee order.pay_status = 0 order.accept_id = accept_log.id order.order_source = accept_log.accept_source order.create_time = account.create_time order.order_desc = u'用户后付费账单:{0}(日均价={1}/{2}) x {3}(使用天数) '.format(per_day_fee_yuan, utils.fen2yuan(product.fee_price), pre_month_days, order_bill_days) order.stat_year = order.create_time[0:4] order.stat_month = order.create_time[0:7] order.stat_day = order.create_time[0:10] order.sync_ver = tools.gen_sync_ver() self.db.add(order) self.db.commit() logger.info(u'用户[%s]后付费出账完成' % account_number, trace='event') except Exception as err: logger.exception(err) logger.error(u'用户[%s]后付费出账失败' % account_number, trace='event')