def verify_import_coupon(): """查找2天内,5分钟前的未消费的导入券""" logging.basicConfig(level=logging.INFO, format='[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d] %(message)s') now = datetime.now() start_time = now - timedelta(days=2) end_time = now - timedelta(minutes=5) db = torndb.Connection( host=options.mysql_host, database=options.mysql_database, user=options.mysql_user, password=options.mysql_password) coupon_list = db.query( 'select ic.sn, ' '(select min(id) from supplier_shop ss where ss.supplier_id=g.supplier_id and ss.deleted=0) shop_id ' 'from item i, item_coupon ic, goods g ' 'where i.id=ic.item_id and i.goods_id=g.id ' 'and i.created_at > %s and i.created_at < %s and i.distr_shop_id != %s ' 'and i.status=1 and g.generate_type="IMPORT"', start_time, end_time, options.shop_id_wuba) for coupon in coupon_list: response = yield partner_api_verify(db, coupon.sn) if not response.ok: ok, msg = (False, response.msg) else: verify_result = local_verify(db, coupon.sn, coupon.shop_id, '系统') ok, msg = (verify_result.ok, verify_result.msg) if not ok: logging.error('导入券%s验证失败,失败原因%s', coupon.sn, msg) else: logging.info('导入券%s验证成功', coupon.sn)
def post(self): self.set_header('Content-Type', 'application/json; charset=UTF-8') coupon_sn = self.get_argument('coupon', '') shop_id = self.get_argument('shop', '') # 检查请求的参数 if not coupon_sn or not shop_id: self.write(json_dumps({'error': '请输入正确参数'})) return # 检查电子券 coupon = self.db.get('select * from item i, item_coupon c where c.sn=%s and i.id=c.item_id', coupon_sn) if not coupon: self.write(json_dumps({'error': '券号不存在'})) return # 查找可验证店铺 all_shops = self.db.get('select all_shop from goods where id=%s', coupon.goods_id).all_shop if all_shops == '1': # 所有店铺 shops = self.db.query('select s.id, s.name, s.supplier_name as spname from supplier_shop s ' 'where supplier_id=%s', coupon.sp_id) else: # 指定店铺 shop_ids = self.db.query('select supplier_shop_id from goods_supplier_shop ' 'where goods_id=%s', coupon.goods_id) ids = ','.join([str(item.supplier_shop_id) for item in shop_ids]) shops = self.db.query('select s.id, s.name, s.supplier_name as spname from supplier_shop s ' 'where s.id in (' + ids + ')') if int(shop_id) not in [i.id for i in shops]: self.write({'ok': False, 'msg': '验证门店错误'}) return # 本地检测 check_result = local_check(self.db, coupon_sn, shop_id) if not check_result.ok: self.write(json_dumps({'error': check_result.msg})) return # 合作伙伴API验证 api_result = yield partner_api_verify(self.db, coupon_sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(self.db, coupon_sn, shop_id, self.get_current_user().name) ok, msg = (verify_result.ok, verify_result.msg) if not ok: self.write(json_dumps({'error': '错误,原因:%s' % msg})) else: # 发送验证确认短信 shop_name = self.db.get('select name from supplier_shop where id=%s', shop_id).name CouponConsumedMessage(self.redis, [coupon.sn], shop_name, coupon.mobile).send() self.write(json_dumps({'ok': '验证成功'}))
def verify_coupon(): for coupon in coupons: # 本地检测 check_result = local_check(db, coupon.sn, coupon.shop_id) if not check_result.ok: logging.error('ktv auto verify failed. coupon:%s, msg:%s', coupon, check_result.msg) continue # 合作伙伴API验证 api_result = yield partner_api_verify(db, coupon.sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(db, coupon.sn, coupon.shop_id, '系统') ok, msg = (verify_result.ok, verify_result.msg) if not ok: logging.error('ktv auto verify failed. coupon:%s, msg:%s', coupon, msg) else: logging.info('ktv auto verify ok. coupon:%s', coupon)
def get(self): caller = self.get_argument('caller').encode('utf-8') coupon_sn = self.get_argument('coupon').encode('utf-8') sign = self.get_argument('sign').encode('utf-8') timestamp = self.get_argument('timestamp').encode('utf-8') logging.info('telephone verify. caller: %s, coupon_sn: %s, sign: %s, timestamp: %s', caller, coupon_sn, sign, timestamp) if not caller: logging.error('telephone verify failed: empty caller.') self.write('1|主叫号码无效') return if not coupon_sn: logging.error('telephone verify failed: empty coupon.') self.write('2|券号为空') return if not sign: logging.error('telephone verify failed: empty sign.') self.write('3|签名无效') return if not timestamp: logging.error('telephone verify failed: empty timestamp.') self.write('3|时间戳无效') return if abs(int(time.time()) - int(timestamp)) > 300: logging.error('telephone verify failed: request timeout.') self.write('3|请求超时') return # 暂不检查签名 # todo # 查找电话 supplier_shop = self.db.get('select * from supplier_shop where deleted=0 and verify_phones like %s', '%'+caller+'%') #if not supplier_shop: # #部分商家使用分机,出口线很多,不能一一录入,这里可以使用电话号码的前面一部分进行识别。 # #尝试模糊查找验证电话机 # supplier_user_list = self.db.query('select * from supplier_user where type="ANDROID"') # for su in supplier_user_list: # if caller.startswith(su.loginname): # supplier_shop = su # break if not supplier_shop: logging.error('telehphone verify failed. can not found valid supplier_user %s.', caller) self.write('1|您的电话还未绑定') return coupon = self.db.get('select id, sn, mobile from item_coupon where sn=%s', coupon_sn) if not coupon: if len(coupon_sn) == 9: for i in range(10): coupon = self.db.get('select id, sn, mobile from item_coupon where sn=%s', '%s%s' % (i, coupon_sn)) if coupon: #我们自己的券 check_result = local_check(self.db, coupon.sn, supplier_shop.id) if not check_result.ok: ok, msg = (False, check_result.msg) else: # 合作伙伴API验证 api_result = yield partner_api_verify(self.db, coupon.sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(self.db, coupon.sn, supplier_shop.id, '电话验证') if verify_result.ok: ok, msg = (True, verify_result.msg) else: ok, msg = (False, verify_result.msg) else: results = yield partner_browser_verify(self.db, [coupon_sn], supplier_shop.id) # 记录外部订单 for result in results: if result.ok: goods_info = self.db.get('select g.* from goods g where id=%s', result.goods_id) verify_infos = {'goods_id': result.goods_id, 'shop_id': supplier_shop.id} #创建分销订单 distributor_order_id = self.db.execute( 'insert into distributor_order(order_no, message, distributor_shop_id, created_at) ' 'values (%s, %s, %s, NOW())', result.coupon_sn, json_dumps(verify_infos), result.distributor_shop_id) order_id, order_no = new_distributor_order(self.db, result.distributor_shop_id, goods_info.sales_price, goods_info.sales_price, '') #记录订单信息 new_order = new_distributor_item( db=self.db, order_id=order_id, order_no=order_no, sales_price=None, count=1, goods_info=goods_info, mobile='', distributor_shop_id=result.distributor_shop_id, distributor_goods_id='', distributor_coupons=[{'coupon_sn': result.coupon_sn, 'coupon_pwd': result.coupon_pwd or ''}], use_distributor_coupon=True ) if new_order.ok: #更新分销订单id self.db.execute('update orders set distributor_order_id=%s where id = %s', distributor_order_id, order_id) #更新订单id self.db.execute('update distributor_order set order_id=%s where id=%s', order_id, distributor_order_id) #更新该券验证的门店 self.db.execute('update item set sp_shop_id = %s where order_id=%s', supplier_shop.id, order_id) self.redis.lpush(options.queue_coupon_local_verify, json_dumps({'coupon': result.coupon_sn, 'shop_id': supplier_shop.id, 'retry': 0, 'used_at': datetime.now()})) ok, msg = (results[0].ok, results[0].msg) if not ok: logging.error('telephone verify failed. %s', msg) self.write('2|验证失败') else: logging.info('telephone verify ok. caller: %s, coupon_sn: %s, sign: %s, timestamp: %s', caller, coupon_sn, sign, timestamp) # 发送验证确认短信 CouponConsumedMessage(self.redis, [coupon.sn], supplier_shop.name, coupon.mobile).send() if coupon: face_value = self.db.get('select face_value from item i, item_coupon c where i.id=c.item_id ' 'and c.id=%s', coupon.id).face_value self.write('0|券尾号%s验证成功,面值%s' % (coupon_sn[-4:], upper(face_value).encode('utf-8'))) else: self.write('0|券尾号%s验证成功' % coupon_sn[-4:])
from tornado.options import options from autumn.coupon import local_verify """美团、点评、糯米的券在一百券上验证处理""" common.set_up() db = common.db_client() redis = common.redis_client() while common.running(): coupon = redis.brpoplpush(options.queue_coupon_local_verify, options.queue_coupon_local_verify_processing) task = json.loads(coupon, object_hook=json_hook) logging.info('local coupon verify pop %s ,shop_id:%s ' % (task.coupon, task.shop_id)) #开始对外部券进行本地验证 verify_result = local_verify(db, task.coupon, task.shop_id, '系统', verified_at=task.used_at) ok, msg = (verify_result.ok, verify_result.msg) if ok: # 外部券验证处理完成,从处理队列移除 redis.lrem(options.queue_coupon_local_verify_processing, 0, coupon) logging.info('local coupon verify finish,coupon_sn:%s' % task.coupon) else: logging.info('local coupon verify failed,coupon_sn:%s' % task.coupon)
def post(self): self.set_header('Content-Type', 'application/json; charset=UTF-8') coupon_list = [i.strip() for i in self.get_argument('coupons', '').split(',') if i.strip()] if len(coupon_list) == 0: self.write({'ok': False, 'msg': u'请输入券号'}) return shop_id = self.get_argument('shop_id', 0) #这一步是检查该操作员是否有权限验证券 all_shops = self.db.query('select ss.* from supplier_shop ss, supplier_user su where ss.supplier_id=%s and ' 'ss.deleted=0 and su.id=%s and su.supplier_id=ss.supplier_id and ' ' (su.shop_id=0 or ss.id=su.shop_id)', self.current_user.supplier_id, self.current_user.id) if int(shop_id) not in [i.id for i in all_shops]: self.write({'ok': False, 'msg': u'对不起,您无权执行此操作'}) return is_our_coupon = False coupon_length = 0 messages = PropDict() # 用来存不同的手机号对应的券号 #检测长度是否相同、是否是我们的券 for coupon_sn in coupon_list: coupon = self.db.get('select id, sn, mobile from item_coupon where sn=%s', coupon_sn) if coupon: is_our_coupon = True if coupon_length == 0: coupon_length = len(coupon_sn) elif coupon_length != len(coupon_sn): coupon_length = -1 if coupon_length == -1: self.write({'ok': False, 'msg': u'券号长度必须一致'}) return result_list = [] if is_our_coupon: # 我们自己的券 for coupon_sn in coupon_list: # 本地检测 check_result = local_check(self.db, coupon_sn, shop_id) if not check_result.ok: ok, msg = (False, check_result.msg) else: # 合作伙伴API验证 api_result = yield partner_api_verify(self.db, coupon_sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(self.db, coupon_sn, shop_id, self.current_user.name) ok, msg = (verify_result.ok, verify_result.msg) # 验证通过,记录需要发送确认短信的券 if ok: if messages.get(str(check_result.coupon.mobile)): # 手机号已存在,添加券号到对应手机号 messages.get(str(check_result.coupon.mobile)).append(str(coupon_sn)) else: # 手机号不存在,新建K-V对 messages.update({str(check_result.coupon.mobile): [str(coupon_sn)]}) result_list.append({'coupon_sn': coupon_sn, 'ok': ok, 'msg': msg}) else: mobile = self.get_argument('mobile', '') # 检查手机号合法性 mobile_ptn = re.compile('^1[\d+]{10}$') if not re.match(mobile_ptn, mobile): # 不合法手机号,不记录 mobile = '' # 尝试外部验证 results = yield partner_browser_verify(self.db, coupon_list, shop_id) for result in results: if result.ok: goods_info = self.db.get('select g.* from goods g where id=%s', result.goods_id) verify_infos = {'goods_id': result.goods_id, 'shop_id': shop_id} #创建分销订单 distributor_order_id = self.db.execute( 'insert into distributor_order(order_no, message, distributor_shop_id, created_at) ' 'values (%s, %s, %s, NOW())', result.coupon_sn, json_dumps(verify_infos), result.distributor_shop_id) order_id, order_no = new_distributor_order(self.db, result.distributor_shop_id, goods_info.sales_price, goods_info.sales_price, mobile) #记录订单信息 new_order = new_distributor_item( db=self.db, order_id=order_id, order_no=order_no, sales_price=None, count=1, goods_info=goods_info, mobile=mobile, distributor_shop_id=result.distributor_shop_id, distributor_goods_id='', distributor_coupons=[{'coupon_sn': result.coupon_sn, 'coupon_pwd': result.coupon_pwd or ''}], use_distributor_coupon=True ) if new_order.ok: #更新分销订单id self.db.execute('update orders set distributor_order_id=%s where id = %s', distributor_order_id, order_id) #更新订单id self.db.execute('update distributor_order set order_id=%s where id=%s', order_id, distributor_order_id) #更新该券验证的门店 self.db.execute('update item set sp_shop_id = %s where order_id=%s', shop_id, order_id) self.redis.lpush(options.queue_coupon_local_verify, json_dumps({'coupon': result.coupon_sn, 'shop_id': shop_id, 'retry': 0, 'used_at': datetime.now()})) result_list.append({'coupon_sn': result.coupon_sn, 'coupon_pwd': result.coupon_pwd or '', 'ok': result.ok, 'msg': result.msg}) # 如果有合法券号,发送确认短信 if messages: shop_name = self.db.get('select name from supplier_shop where id=%s', shop_id).name for mobile, coupon_sns in messages.items(): CouponConsumedMessage(self.redis, coupon_sns, shop_name, mobile).send() self.write({'ok': True, 'result': result_list})
def post(self): self.set_header('Content-Type', 'application/json; charset=UTF-8') coupon_sn = self.get_argument('coupon_sn', '').encode('utf-8') logging.info('执行刷单, 券号: %s', coupon_sn) coupon = self.db.get('select c.id cid, i.*, c.* from item i, item_coupon c ' 'where i.id=c.item_id and c.sn=%s', coupon_sn) # 券号错误,直接报错返回 if not coupon: logging.error('刷单错误,券号%s不存在', coupon_sn) self.write({'ok': False}) return # 商户刷单,获得手续费费率 is_op = int(self.get_argument('is_op', '')) if not is_op: rate = Decimal(self.get_argument('rate', '')) / 100 # 获得商户的第一个门店,在此门店验证 shop = self.db.query( 'select ss.* from supplier_shop ss,goods g where ss.supplier_id=g.supplier_id and g.id=%s and ss.deleted=0 ' 'and (g.all_shop=1 or ss.id in (select supplier_shop_id from goods_supplier_shop where goods_id=%s) ) ', coupon.goods_id, coupon.goods_id )[0] # 本地检测 check_result = local_check(self.db, coupon_sn, shop.id) if not check_result.ok: logging.error('刷单错误,券号合法性检查失败') self.write({'ok': False}) return else: # 发送第三方验证请求 api_result = yield partner_api_verify(self.db, coupon_sn) if not api_result.ok: logging.info('刷单提醒,券号%s第三方验证未通过', coupon_sn) self.write({'ok': False}) return # 本地验证 verify_result = local_verify(self.db, coupon_sn, shop.id, self.get_current_user().name) if not verify_result.ok: logging.error('刷单错误,券号%s本地验证失败', coupon_sn) # 验证失败,返回 self.write({'ok': False}) return # 记录一条门店账务明细 supplier_shop_account_id = self.db.get('select account_id from supplier_shop ' 'where id=%s', shop.id).account_id if is_op: # 我们刷单,直接减去进价 amount = - coupon.purchase_price remark = '刷单收回:%s, 商品:%s,售价:%s,付款:%s,' \ % (amount, coupon.goods_name, coupon.sales_price, coupon.payment) fee = Decimal(0) else: # 商户自己刷单,把扣除手续费后的差价还给商户 diff = coupon.payment - coupon.purchase_price # 差价 fee = (coupon.payment * rate).quantize(Decimal('0.01')) # 按付款金额的百分比收手续费 amount = diff - fee # 应返还 remark = '协助商户刷单-扣除手续费:%s, 返还差价:%s, 合计返还:%s, 验证门店:%s, 商品:%s,售价:%s,付款:%s' \ % (fee, diff, amount, shop.name, coupon.goods_name, coupon.sales_price, coupon.payment) self.db.execute('insert into account_sequence(type, account_id, item_id,trade_type,trade_id,' 'amount,created_at,remark, status)' 'values (%s, %s, %s, 1, %s, %s, NOW(),%s,1)', const.seq.CHEAT_ORDER, supplier_shop_account_id, coupon.item_id, coupon.order_id, amount, remark) # 更新 item 状态 cheat_value = coupon.purchase_price + fee # 记录加上手续费后的进价,方便以后算刷单手续费 self.db.execute('update item set cheat_value=%s, cheat_at=NOW() where item.id=%s', cheat_value, coupon.item_id) # 如果是我们刷单,商户后台的账户流水中不予显示 if is_op: logging.info('%s %s', supplier_shop_account_id, coupon.item_id) self.db.execute('update account_sequence set display=2 where account_id=%s and item_id=%s', supplier_shop_account_id, coupon.item_id) # 记录虚拟验证日志 record = """insert into journal (created_at, type, created_by, message, iid) values (now(), 2, %s, %s, %s)""" user = self.get_current_user() message = "券 %s 刷单, 备注: %s" % (coupon_sn, remark) self.db.execute(record, user.name, message, coupon.cid) logging.info('刷单成功') self.write({'ok': True}) return
def get(self): caller = self.get_argument('caller').encode('utf-8') coupon_sn = self.get_argument('coupon').encode('utf-8') sign = self.get_argument('sign').encode('utf-8') timestamp = self.get_argument('timestamp').encode('utf-8') logging.info( 'telephone verify. caller: %s, coupon_sn: %s, sign: %s, timestamp: %s', caller, coupon_sn, sign, timestamp) if not caller: logging.error('telephone verify failed: empty caller.') self.write('1|主叫号码无效') return if not coupon_sn: logging.error('telephone verify failed: empty coupon.') self.write('2|券号为空') return if not sign: logging.error('telephone verify failed: empty sign.') self.write('3|签名无效') return if not timestamp: logging.error('telephone verify failed: empty timestamp.') self.write('3|时间戳无效') return if abs(int(time.time()) - int(timestamp)) > 300: logging.error('telephone verify failed: request timeout.') self.write('3|请求超时') return # 暂不检查签名 # todo # 查找电话 supplier_shop = self.db.get( 'select * from supplier_shop where deleted=0 and verify_phones like %s', '%' + caller + '%') #if not supplier_shop: # #部分商家使用分机,出口线很多,不能一一录入,这里可以使用电话号码的前面一部分进行识别。 # #尝试模糊查找验证电话机 # supplier_user_list = self.db.query('select * from supplier_user where type="ANDROID"') # for su in supplier_user_list: # if caller.startswith(su.loginname): # supplier_shop = su # break if not supplier_shop: logging.error( 'telehphone verify failed. can not found valid supplier_user %s.', caller) self.write('1|您的电话还未绑定') return coupon = self.db.get( 'select id, sn, mobile from item_coupon where sn=%s', coupon_sn) if not coupon: if len(coupon_sn) == 9: for i in range(10): coupon = self.db.get( 'select id, sn, mobile from item_coupon where sn=%s', '%s%s' % (i, coupon_sn)) if coupon: #我们自己的券 check_result = local_check(self.db, coupon.sn, supplier_shop.id) if not check_result.ok: ok, msg = (False, check_result.msg) else: # 合作伙伴API验证 api_result = yield partner_api_verify(self.db, coupon.sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(self.db, coupon.sn, supplier_shop.id, '电话验证') if verify_result.ok: ok, msg = (True, verify_result.msg) else: ok, msg = (False, verify_result.msg) else: results = yield partner_browser_verify(self.db, [coupon_sn], supplier_shop.id) # 记录外部订单 for result in results: if result.ok: goods_info = self.db.get( 'select g.* from goods g where id=%s', result.goods_id) verify_infos = { 'goods_id': result.goods_id, 'shop_id': supplier_shop.id } #创建分销订单 distributor_order_id = self.db.execute( 'insert into distributor_order(order_no, message, distributor_shop_id, created_at) ' 'values (%s, %s, %s, NOW())', result.coupon_sn, json_dumps(verify_infos), result.distributor_shop_id) order_id, order_no = new_distributor_order( self.db, result.distributor_shop_id, goods_info.sales_price, goods_info.sales_price, '') #记录订单信息 new_order = new_distributor_item( db=self.db, order_id=order_id, order_no=order_no, sales_price=None, count=1, goods_info=goods_info, mobile='', distributor_shop_id=result.distributor_shop_id, distributor_goods_id='', distributor_coupons=[{ 'coupon_sn': result.coupon_sn, 'coupon_pwd': result.coupon_pwd or '' }], use_distributor_coupon=True) if new_order.ok: #更新分销订单id self.db.execute( 'update orders set distributor_order_id=%s where id = %s', distributor_order_id, order_id) #更新订单id self.db.execute( 'update distributor_order set order_id=%s where id=%s', order_id, distributor_order_id) #更新该券验证的门店 self.db.execute( 'update item set sp_shop_id = %s where order_id=%s', supplier_shop.id, order_id) self.redis.lpush( options.queue_coupon_local_verify, json_dumps({ 'coupon': result.coupon_sn, 'shop_id': supplier_shop.id, 'retry': 0, 'used_at': datetime.now() })) ok, msg = (results[0].ok, results[0].msg) if not ok: logging.error('telephone verify failed. %s', msg) self.write('2|验证失败') else: logging.info( 'telephone verify ok. caller: %s, coupon_sn: %s, sign: %s, timestamp: %s', caller, coupon_sn, sign, timestamp) # 发送验证确认短信 CouponConsumedMessage(self.redis, [coupon.sn], supplier_shop.name, coupon.mobile).send() if coupon: face_value = self.db.get( 'select face_value from item i, item_coupon c where i.id=c.item_id ' 'and c.id=%s', coupon.id).face_value self.write('0|券尾号%s验证成功,面值%s' % (coupon_sn[-4:], upper(face_value).encode('utf-8'))) else: self.write('0|券尾号%s验证成功' % coupon_sn[-4:])
def post(self): self.set_header('Content-Type', 'application/json; charset=UTF-8') coupon_sn = self.get_argument('coupon', '') shop_id = self.get_argument('shop', '') # 检查请求的参数 if not coupon_sn or not shop_id: self.write(json_dumps({'error': '请输入正确参数'})) return # 检查电子券 coupon = self.db.get( 'select * from item i, item_coupon c where c.sn=%s and i.id=c.item_id', coupon_sn) if not coupon: self.write(json_dumps({'error': '券号不存在'})) return # 查找可验证店铺 all_shops = self.db.get('select all_shop from goods where id=%s', coupon.goods_id).all_shop if all_shops == '1': # 所有店铺 shops = self.db.query( 'select s.id, s.name, s.supplier_name as spname from supplier_shop s ' 'where supplier_id=%s', coupon.sp_id) else: # 指定店铺 shop_ids = self.db.query( 'select supplier_shop_id from goods_supplier_shop ' 'where goods_id=%s', coupon.goods_id) ids = ','.join([str(item.supplier_shop_id) for item in shop_ids]) shops = self.db.query( 'select s.id, s.name, s.supplier_name as spname from supplier_shop s ' 'where s.id in (' + ids + ')') if int(shop_id) not in [i.id for i in shops]: self.write({'ok': False, 'msg': '验证门店错误'}) return # 本地检测 check_result = local_check(self.db, coupon_sn, shop_id) if not check_result.ok: self.write(json_dumps({'error': check_result.msg})) return # 合作伙伴API验证 api_result = yield partner_api_verify(self.db, coupon_sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(self.db, coupon_sn, shop_id, self.get_current_user().name) ok, msg = (verify_result.ok, verify_result.msg) if not ok: self.write(json_dumps({'error': '错误,原因:%s' % msg})) else: # 发送验证确认短信 shop_name = self.db.get( 'select name from supplier_shop where id=%s', shop_id).name CouponConsumedMessage(self.redis, [coupon.sn], shop_name, coupon.mobile).send() self.write(json_dumps({'ok': '验证成功'}))
def post(self): self.set_header('Content-Type', 'application/json; charset=UTF-8') coupon_sn = self.get_argument('coupon_sn', '').encode('utf-8') logging.info('执行刷单, 券号: %s', coupon_sn) coupon = self.db.get( 'select c.id cid, i.*, c.* from item i, item_coupon c ' 'where i.id=c.item_id and c.sn=%s', coupon_sn) # 券号错误,直接报错返回 if not coupon: logging.error('刷单错误,券号%s不存在', coupon_sn) self.write({'ok': False}) return # 商户刷单,获得手续费费率 is_op = int(self.get_argument('is_op', '')) if not is_op: rate = Decimal(self.get_argument('rate', '')) / 100 # 获得商户的第一个门店,在此门店验证 shop = self.db.query( 'select ss.* from supplier_shop ss,goods g where ss.supplier_id=g.supplier_id and g.id=%s and ss.deleted=0 ' 'and (g.all_shop=1 or ss.id in (select supplier_shop_id from goods_supplier_shop where goods_id=%s) ) ', coupon.goods_id, coupon.goods_id)[0] # 本地检测 check_result = local_check(self.db, coupon_sn, shop.id) if not check_result.ok: logging.error('刷单错误,券号合法性检查失败') self.write({'ok': False}) return else: # 发送第三方验证请求 api_result = yield partner_api_verify(self.db, coupon_sn) if not api_result.ok: logging.info('刷单提醒,券号%s第三方验证未通过', coupon_sn) self.write({'ok': False}) return # 本地验证 verify_result = local_verify(self.db, coupon_sn, shop.id, self.get_current_user().name) if not verify_result.ok: logging.error('刷单错误,券号%s本地验证失败', coupon_sn) # 验证失败,返回 self.write({'ok': False}) return # 记录一条门店账务明细 supplier_shop_account_id = self.db.get( 'select account_id from supplier_shop ' 'where id=%s', shop.id).account_id if is_op: # 我们刷单,直接减去进价 amount = -coupon.purchase_price remark = '刷单收回:%s, 商品:%s,售价:%s,付款:%s,' \ % (amount, coupon.goods_name, coupon.sales_price, coupon.payment) fee = Decimal(0) else: # 商户自己刷单,把扣除手续费后的差价还给商户 diff = coupon.payment - coupon.purchase_price # 差价 fee = (coupon.payment * rate).quantize( Decimal('0.01')) # 按付款金额的百分比收手续费 amount = diff - fee # 应返还 remark = '协助商户刷单-扣除手续费:%s, 返还差价:%s, 合计返还:%s, 验证门店:%s, 商品:%s,售价:%s,付款:%s' \ % (fee, diff, amount, shop.name, coupon.goods_name, coupon.sales_price, coupon.payment) self.db.execute( 'insert into account_sequence(type, account_id, item_id,trade_type,trade_id,' 'amount,created_at,remark, status)' 'values (%s, %s, %s, 1, %s, %s, NOW(),%s,1)', const.seq.CHEAT_ORDER, supplier_shop_account_id, coupon.item_id, coupon.order_id, amount, remark) # 更新 item 状态 cheat_value = coupon.purchase_price + fee # 记录加上手续费后的进价,方便以后算刷单手续费 self.db.execute( 'update item set cheat_value=%s, cheat_at=NOW() where item.id=%s', cheat_value, coupon.item_id) # 如果是我们刷单,商户后台的账户流水中不予显示 if is_op: logging.info('%s %s', supplier_shop_account_id, coupon.item_id) self.db.execute( 'update account_sequence set display=2 where account_id=%s and item_id=%s', supplier_shop_account_id, coupon.item_id) # 记录虚拟验证日志 record = """insert into journal (created_at, type, created_by, message, iid) values (now(), 2, %s, %s, %s)""" user = self.get_current_user() message = "券 %s 刷单, 备注: %s" % (coupon_sn, remark) self.db.execute(record, user.name, message, coupon.cid) logging.info('刷单成功') self.write({'ok': True}) return
def post(self): self.set_header('Content-Type', 'application/json; charset=UTF-8') coupon_list = [ i.strip() for i in self.get_argument('coupons', '').split(',') if i.strip() ] if len(coupon_list) == 0: self.write({'ok': False, 'msg': u'请输入券号'}) return shop_id = self.get_argument('shop_id', 0) #这一步是检查该操作员是否有权限验证券 all_shops = self.db.query( 'select ss.* from supplier_shop ss, supplier_user su where ss.supplier_id=%s and ' 'ss.deleted=0 and su.id=%s and su.supplier_id=ss.supplier_id and ' ' (su.shop_id=0 or ss.id=su.shop_id)', self.current_user.supplier_id, self.current_user.id) if int(shop_id) not in [i.id for i in all_shops]: self.write({'ok': False, 'msg': u'对不起,您无权执行此操作'}) return is_our_coupon = False coupon_length = 0 messages = PropDict() # 用来存不同的手机号对应的券号 #检测长度是否相同、是否是我们的券 for coupon_sn in coupon_list: coupon = self.db.get( 'select id, sn, mobile from item_coupon where sn=%s', coupon_sn) if coupon: is_our_coupon = True if coupon_length == 0: coupon_length = len(coupon_sn) elif coupon_length != len(coupon_sn): coupon_length = -1 if coupon_length == -1: self.write({'ok': False, 'msg': u'券号长度必须一致'}) return result_list = [] if is_our_coupon: # 我们自己的券 for coupon_sn in coupon_list: # 本地检测 check_result = local_check(self.db, coupon_sn, shop_id) if not check_result.ok: ok, msg = (False, check_result.msg) else: # 合作伙伴API验证 api_result = yield partner_api_verify(self.db, coupon_sn) if not api_result.ok: ok, msg = (False, api_result.msg) else: # 本地验证 verify_result = local_verify(self.db, coupon_sn, shop_id, self.current_user.name) ok, msg = (verify_result.ok, verify_result.msg) # 验证通过,记录需要发送确认短信的券 if ok: if messages.get(str(check_result.coupon.mobile)): # 手机号已存在,添加券号到对应手机号 messages.get(str( check_result.coupon.mobile)).append( str(coupon_sn)) else: # 手机号不存在,新建K-V对 messages.update({ str(check_result.coupon.mobile): [str(coupon_sn)] }) result_list.append({ 'coupon_sn': coupon_sn, 'ok': ok, 'msg': msg }) else: mobile = self.get_argument('mobile', '') # 检查手机号合法性 mobile_ptn = re.compile('^1[\d+]{10}$') if not re.match(mobile_ptn, mobile): # 不合法手机号,不记录 mobile = '' # 尝试外部验证 results = yield partner_browser_verify(self.db, coupon_list, shop_id) for result in results: if result.ok: goods_info = self.db.get( 'select g.* from goods g where id=%s', result.goods_id) verify_infos = { 'goods_id': result.goods_id, 'shop_id': shop_id } #创建分销订单 distributor_order_id = self.db.execute( 'insert into distributor_order(order_no, message, distributor_shop_id, created_at) ' 'values (%s, %s, %s, NOW())', result.coupon_sn, json_dumps(verify_infos), result.distributor_shop_id) order_id, order_no = new_distributor_order( self.db, result.distributor_shop_id, goods_info.sales_price, goods_info.sales_price, mobile) #记录订单信息 new_order = new_distributor_item( db=self.db, order_id=order_id, order_no=order_no, sales_price=None, count=1, goods_info=goods_info, mobile=mobile, distributor_shop_id=result.distributor_shop_id, distributor_goods_id='', distributor_coupons=[{ 'coupon_sn': result.coupon_sn, 'coupon_pwd': result.coupon_pwd or '' }], use_distributor_coupon=True) if new_order.ok: #更新分销订单id self.db.execute( 'update orders set distributor_order_id=%s where id = %s', distributor_order_id, order_id) #更新订单id self.db.execute( 'update distributor_order set order_id=%s where id=%s', order_id, distributor_order_id) #更新该券验证的门店 self.db.execute( 'update item set sp_shop_id = %s where order_id=%s', shop_id, order_id) self.redis.lpush( options.queue_coupon_local_verify, json_dumps({ 'coupon': result.coupon_sn, 'shop_id': shop_id, 'retry': 0, 'used_at': datetime.now() })) result_list.append({ 'coupon_sn': result.coupon_sn, 'coupon_pwd': result.coupon_pwd or '', 'ok': result.ok, 'msg': result.msg }) # 如果有合法券号,发送确认短信 if messages: shop_name = self.db.get( 'select name from supplier_shop where id=%s', shop_id).name for mobile, coupon_sns in messages.items(): CouponConsumedMessage(self.redis, coupon_sns, shop_name, mobile).send() self.write({'ok': True, 'result': result_list})
import common import logging import json from datetime import datetime, timedelta from autumn.utils import json_hook from tornado.options import options from autumn.coupon import local_verify """美团、点评、糯米的券在一百券上验证处理""" common.set_up() db = common.db_client() redis = common.redis_client() while common.running(): coupon = redis.brpoplpush(options.queue_coupon_local_verify, options.queue_coupon_local_verify_processing) task = json.loads(coupon, object_hook=json_hook) logging.info('local coupon verify pop %s ,shop_id:%s ' % (task.coupon, task.shop_id)) #开始对外部券进行本地验证 verify_result = local_verify(db, task.coupon, task.shop_id, '系统', verified_at=task.used_at) ok, msg = (verify_result.ok, verify_result.msg) if ok: # 外部券验证处理完成,从处理队列移除 redis.lrem(options.queue_coupon_local_verify_processing, 0, coupon) logging.info('local coupon verify finish,coupon_sn:%s' % task.coupon) else: logging.info('local coupon verify failed,coupon_sn:%s' % task.coupon)