コード例 #1
0
def make_trade_order(userid, amount, trade_type, comment, pay_type='cash'):
    trade_order = {
        'order_trade_id': app_helper.get_new_order_id(),
        'userid': userid,
        'total_sum': amount,
        'trade_type': trade_type,  #  receipt 收款   refund 退款  consume 消费
        'pay_type': pay_type,
        'pay_time': app_helper.time_str(),
        'cash_sum': amount,
        'comment': comment,
    }
    db.order_trade.update_one(
        {'order_trade_id': trade_order['order_trade_id']},
        {'$set': trade_order},
        upsert=True)

    return trade_order['order_trade_id']
コード例 #2
0
    def POST(self):
        web.header('Content-Type', 'application/json')
        param = web.input(app_id='',
                          session='',
                          shop_id='',
                          order_id='',
                          addr_id='',
                          coupon_id='',
                          cart='',
                          sign='')

        print param

        if '' in (param.app_id, param.session, param.shop_id, param.addr_id,
                  param.cart, param.sign):
            return json.dumps({'ret': -2, 'msg': '参数错误'})

        uname = app_helper.logged(param.session)  # 检查session登录
        if uname:
            #验证签名
            md5_str = app_helper.generate_sign([
                param.app_id, param.session, param.order_id, param.shop_id,
                param.addr_id, param.coupon_id, param.cart
            ])
            if md5_str != param.sign:
                return json.dumps({'ret': -1, 'msg': '签名验证错误'})

            # 记录版本信息
            db.app_user.update_one({'uname': uname},
                                   {'$set': {
                                       'version': 'v1'
                                   }})

            # mice 为黄牛手机号标志,mice==1不可以下单 2015-08-22
            db_user = db.app_user.find_one(
                {'uname': uname},  #, 'mice':{'$ne':1}},
                {
                    'coupon': 1,
                    'address': 1,
                    'credit': 1,
                    'app_id': 1,
                    'mice': 1
                })
            if db_user == None:  # 不应该发生
                return json.dumps({'ret': -9, 'msg': '未找到用户信息'})

            # 检查mice, 排除白名单
            if db_user.get('mice') == 1 and uname not in app_helper.WHITE_LIST:
                print 'mice !!!'
                return json.dumps({'ret': -9, 'msg': '未找到用户信息'})

            app_id = db_user['app_id']

            # 修改未付款的过期订单
            db.order_app.update_many(
                {
                    #'uname'    : uname,
                    'status': 'DUE',
                    'deadline': {
                        '$lt': int(time.time())
                    }
                },
                {'$set': {
                    'status': 'TIMEOUT'
                }})

            # 检查是否有新红包
            #app_helper.check_hb(uname)

            # 先要核对送货地址是否在门店送货范围内!!!!!!! -- 需补充

            # 查找shop
            db_shop = db.base_shop.find_one({'_id': ObjectId(param.shop_id)})
            if db_shop == None:
                return json.dumps({'ret': -6, 'msg': 'shop_id错误'})

            # 查询收货地址
            address = None
            for i in db_user['address']:
                if i[0] == param.addr_id:
                    address = list(i)
                    break
            if address == None:
                return json.dumps({'ret': -7, 'msg': 'addr_id错误'})

            ###########################################################################
            # 用收货电话检查黄牛 2015-08-22
            db_recv = db.recv_tel.find_one({'tel': address[2]})
            if db_recv:
                one_more = 0
                if uname not in db_recv['unames']:  # 补充疑似账号
                    db.recv_tel.update_one({'tel': address[2]},
                                           {'$push': {
                                               'unames': uname
                                           }})
                    one_more = 1
                if len(db_recv['unames']) + one_more > 10:  # 改为10,2015-10-12
                    # 发现 mice
                    mice = 1
                    for b in db_recv['unames']:
                        if b in app_helper.WHITE_LIST:  # 过滤白名单相关号码
                            mice = 0
                            break
                    db.app_user.update_many(
                        {'uname': {
                            '$in': db_recv['unames']
                        }}, {'$set': {
                            'mice': mice
                        }})
                    db.app_user.update_many(
                        {'openid': {
                            '$in': db_recv['unames']
                        }}, {'$set': {
                            'mice': mice
                        }})
                    if one_more == 1:
                        db.app_user.update_one({'uname': uname},
                                               {'$set': {
                                                   'mice': mice
                                               }})
                    if mice == 1:
                        print '!!! mice:', address[
                            2]  #, uname, db_recv['unames']
                        return json.dumps({'ret': -9, 'msg': '黄牛下单1'})
            else:
                db.recv_tel.insert_one({'tel': address[2], 'unames': [uname]})
                print 'insert', address[2]

            # 用收货地址检查黄牛, 不准确,不能标注 2015-08-23
            db_recv = db.recv_addr.find_one({'addr': address[3]})
            if db_recv:
                one_more = 0
                if uname not in db_recv['unames']:
                    db.recv_addr.update_one({'addr': address[3]},
                                            {'$push': {
                                                'unames': uname
                                            }})
                    one_more = 1
                if len(db_recv['unames']) + one_more > 10:  # 改为10,2015-10-12
                    # 发现疑似mice,不标注,因为不确定
                    print '!!! maybe a mice:', address[3].encode(
                        'utf-8')  #, uname, db_recv['unames']
            else:
                db.recv_addr.insert_one({
                    'addr': address[3],
                    'unames': [uname]
                })
                #print 'insert', address[2]

            # 用app_id检查黄牛
            appid_count = db.app_user.find({
                'app_id': app_id
            }, {
                '_id': 1
            }).count()
            if appid_count > 10 and app_id.strip(
            ) != '':  # app_id 可能为空,新绑定的用户 # 改为10,2015-10-12
                # 发现 mice
                db_mice = db.app_user.find({'app_id': app_id}, {'uname': 1})
                mice = []
                for m in db_mice:
                    if m['uname'] in app_helper.WHITE_LIST:  # 过滤白名单
                        mice = []
                        break
                    else:
                        mice.append(m['uname'])
                db.app_user.update_many({'uname': {
                    '$in': mice
                }}, {'$set': {
                    'mice': 1
                }})
                if mice != []:
                    print '!!! mice by app_id: ', mice
                    return json.dumps({'ret': -9, 'msg': '黄牛下单1'})

            # 查黄牛-结束
            ###########################################################################

            # 查找优惠券
            # 未查到,则不使用优惠券
            coupon = None
            for i in db_user['coupon']:
                if i[0] == param.coupon_id:
                    coupon = list(i)
                    break

            # 转换cart数据为json,应该有异常捕获 !!!
            cart = json.loads(param.cart)
            #print cart

            if len(cart) == 0:
                return json.dumps({'ret': -5, 'msg': '购物车无数据'})

            if param.order_id == '':
                #cc = 1
                #while cc!=None:
                #	# 取得sku计数, 不与线下order共用
                #	db_sa = db.user.find_one_and_update(
                #		{'uname'    : 'settings'},
                #		{'$inc'     : {'app_count' : 1}},
                #		{'app_count' : 1}
                #	)
                #	order_id = 'n%06d' % db_sa['app_count']
                #	# 防止订单号重复
                #	cc = db.order_app.find_one({'order_id'  : order_id},{'_id':1})
                order_id = app_helper.get_new_order_id('v1')
                print 'new order_id', order_id
            else:
                order_id = param.order_id

                cc = db.order_app.find_one(
                    {
                        #'uname'     : uname, # 防止app的bug,重复order_id
                        'order_id': order_id,
                    },
                    {
                        'status': 1,
                    })
                if cc != None and cc[
                        'status'] != 'DUE':  # 检查订单状态,只有due才可以checkout
                    print "BUG! order_id status"
                    return json.dumps({'ret': -99, 'msg': '参数错误'})

            # 订单状态:DUE, PAID, ONROAD, COMPLETED, CANCELED, FINISH
            # 默认运费 5元,免邮门槛 29元
            order = {
                'status': 'DUE',
                'uname': uname,
                'shop': db_shop['_id'],
                'user': uname,
                'order_id': order_id,
                'order_source': app_helper.get_devive_type(param.app_id),
                'address': address,  # 收货地址
                'coupon': coupon,  # 使用的优惠券
                'cart': [],
                'cost': '0.00',  # 成本合计,参考
                'total': '0.00',  # 价格小计,加项
                'coupon_disc': '0.00',  # 优惠券抵扣,减项
                'first_disc': '0.00',  # 首单立减, 减项
                'delivery_fee': '0.00',  # 运费,加项
                'due': '0.00',  # 应付价格
                'uname_id': db_user['_id'],
                # for processor
                'next_status': '',
                'lock': 0,
                'man': 0,
                'retry': 0,
                'comment': '',
                'b_time': int(time.time()),
                'e_time': int(time.time()),
                'deadline': int(time.time() + 60 * 15),
            }

            # 统计旧订单数,为0则是首单 2015-09-29
            old_order_num = db.order_app.find(
                {
                    'user': uname,
                    'status': {
                        '$nin': ['DUE', 'TIMEOUT', 'CANCEL']
                    }
                }, {
                    '_id': 1
                }).count()

            # item = {
            #      “product_id” : “k000011”,
            #      “num”        : “5”,
            # }
            # 应该只有 k-prod
            cart_to_return = []
            cate_001 = 0
            b3_sku = 0
            for item in cart:
                # sku
                db_sku = db.sku_store.find_one(
                    {'product_id': item['product_id']}, {
                        'app_title': 1,
                        'is_onsale': 1,
                        'special_price': 1,
                        'ref_price': 1,
                        'maximun': 1,
                        'list_in_app': 1,
                    })
                if db_sku == None:  # 应该不会发生
                    print 'Error: db_sku==None'
                    continue

                if db_sku['list_in_app'] == -3:  # B3 整箱预售 # -3 不启动B3销售
                    r = db.inventory.find_one(  # 线上销售要检查库存
                     {
                      'product_id'  : item['product_id'],
                      'list_in_app' : {'$ne' : 0},
                      'shop'        : ObjectId(setting.B3_shop),
                     },
                     {
                      'cost_price'  : 1,
                      'ref_prod_id' : 1,
                      'price'       : 1,
                      'sku'         : 1,
                      'num'         : 1,
                      'category'    : 1,
                      'first_order' : 1
                     }
                    )
                    b3_sku += 1
                else:
                    r = db.inventory.find_one(  # 线上销售要检查库存
                     {
                      'product_id'  : item['product_id'],
                      'list_in_app' : {'$ne' : 0},
                      'shop'        : db_shop['_id'],
                     },
                     {
                      'cost_price'  : 1,
                      'ref_prod_id' : 1,
                      'price'       : 1,
                      'sku'         : 1,
                      'num'         : 1,
                      'category'    : 1,
                      'first_order' : 1
                     }
                    )
                if r:  # 如果库存数据中没此sku,会忽略掉,此情况应该不会发生
                    new_num = int(item['num'])
                    new_num = new_num if new_num <= r['num'] else r['num']
                    new_num = max(0, new_num)  # 发现过小于零的情况,微信

                    # 检查是不是 001 (水果) 分类
                    if r['category'] == '001':
                        cate_001 += 1

                    # 检查是否限购
                    if db_sku['maximun'] > 0:
                        '''
						# 每日限购,生成当天的时间tick
						tday = app_helper.time_str(format=1)
						begin_d = '%s 00:00:00' % tday
						end_d = '%s 23:59:59' % tday
						begin_t = int(time.mktime(time.strptime(begin_d,"%Y-%m-%d %H:%M:%S")))
						end_t = int(time.mktime(time.strptime(end_d,"%Y-%m-%d %H:%M:%S")))

						print begin_d, end_d, begin_t, end_t

						# 检查时间段内购买记录
						c = db.order_app.find({
							'uname'           : uname,
							'order_id'        : {'$ne':order_id},
							'status'          : {'$ne':'TIMEOUT'},
							'cart.product_id' : item['product_id'],
							'$and'   : [{'b_time' : {'$gt' : begin_t}},
								    {'b_time' : {'$lt' : end_t}}],
						}, {'_id':1}).count()
						print 'findings: ',c
						if c>0: # 限购商品只允许购买1次
							new_num=0
						else:
							new_num=min(new_num, db_sku['maximun'])
							print 'limit : ',new_num
						'''

                        # 每单限购
                        if new_num > db_sku['maximun']:
                            new_num = db_sku['maximun']
                            item['num'] = '%d' % new_num  # 防止iOS闪退!!!
                            print 'limit : ', new_num
                    '''
					# 买一送一 每单限购1件
					if item['product_id'] in app_helper.buy_1_give_1:
						#new_num=min(new_num, 1)
						#print 'buy 1 give 1 limit : ',new_num

						new_item = {
							'product_id' : item['product_id'],
							'num'        : '%d' % new_num,
							'num2'       : new_num,
							'price'      : r['price'],
							'title'      : db_sku['app_title'],
						}
					else:
					'''

                    # 首单可见商品,非首单用户 2015-09-29
                    if r.has_key('first_order') and r[
                            'first_order'] == 1 and old_order_num > 0:
                        # 非首单用户,不让购买,比较生硬
                        new_num = 0
                        item['num'] = '%d' % new_num  # 防止iOS闪退!!!

                    new_item = {
                        'product_id': item['product_id'],
                        'num': item['num'],
                        'num2': new_num,
                        'price': r['price'],
                        'title': db_sku['app_title'],
                    }

                    # 是否有优惠价格
                    if db_sku['is_onsale']==1 and \
                     float(db_sku['special_price'])<float(r['price']):
                        # 优惠价格比门店价格低
                        new_item['price'] = db_sku['special_price']

                    # 计算总价
                    item_price = round(new_num * float(new_item['price']), 2)
                    new_item['price'] = '%.2f' % item_price

                    cart_to_return.append(new_item)  # 返回到app的cart不包含cost

                    cost_price = r['cost_price']

                    #if item[0][0]=='w': # w-prod 信息都用 u-prod的替换
                    #	new_item['product_id'] = r['ref_prod_id']
                    #	new_item['w_id'] = item[0]
                    #	# 查询成本, 从对应u-prod当前成本
                    #	r2 = db.inventory.find_one({ # u-prod
                    #		'shop'       : db_shop['shop'],
                    #		'product_id' : r['ref_prod_id'],
                    #	}, {'cost_price':1})
                    #	cost_price = r2['cost_price']

                    # 计算成本
                    item_cost = round(new_num * float(cost_price), 2)
                    new_item['cost'] = '%.2f' % item_cost

                    # 加入cart
                    order['cart'].append(new_item)

                    # 累计售价和成本
                    order['total'] = '%.2f' % (float(order['total']) +
                                               item_price)
                    order['cost'] = '%.2f' % (float(order['cost']) + item_cost)
                else:
                    # 店内未找到库存, !!!应该不会发生
                    new_item = {
                        'product_id': item['product_id'],
                        'num': item['num'],
                        'num2': 0,
                        'price': '0.00',
                        'cost': '0.00',
                        'title': db_sku['app_title'],
                    }
                    cart_to_return.append(new_item)  # 返回到app的cart不包含cost
                    order['cart'].append(new_item)

            tt = float(order['total'])
            if tt > 0:
                # 免邮门槛
                #if tt<29: # 免邮门槛 29
                if tt < app_helper.free_delivery:  # 免邮门槛
                    order[
                        'delivery_fee'] = '%.2f' % app_helper.delivery_fee  # 运费5元
                '''
				# 首单立减 first_promote元, 商品总额大于 first_promote_threshold元
				cut_now = app_helper.first_promote #
				if cate_001>0 and (tt+float(order['delivery_fee']))>=app_helper.first_promote_threshold and \
					db.order_app.find({'user':uname, 'status':{'$nin':['DUE','TIMEOUT','CANCEL']}},{'_id':1}).count()==0:
					order['first_disc'] = '%.2f' % cut_now
				'''
                # 首单立减 first_promote元, 商品总额大于 first_promote_threshold元
                if cate_001 > 0 and old_order_num == 0:
                    # 符合首单条件,且有一个水果商品
                    print '首单'
                    if str(db_shop['_id']) in app_helper.first_promote2_shop and \
                     (tt+float(order['delivery_fee']))>=app_helper.first_promote2_threshold:
                        # 站点落在 指定站点范围内,使用首单立减2
                        print '首单立减 - 指定站点'
                        order[
                            'first_disc'] = '%.2f' % app_helper.first_promote2
                    elif (tt + float(order['delivery_fee'])
                          ) >= app_helper.first_promote_threshold:
                        # 其他站点使用首单立减1
                        print '首单立减'
                        order['first_disc'] = '%.2f' % app_helper.first_promote

                # 优惠券, 检查有效期, 优惠券门槛为10元
                if float(order['first_disc'])==0.0 and coupon!=None and \
                 coupon[3]==1 and app_helper.time_str(format=1)<=coupon[1]:
                    if len(coupon
                           ) > 5 and coupon[5] == 'apple' and cate_001 < 1:
                        # 水果券,但没有水果 2015-09-29
                        print '水果券没水果'
                        order['coupon'] = None
                    elif len(coupon) > 5 and coupon[5] == 'b3' and b3_sku < 1:
                        # 整箱券,但没有整箱 2015-10-18
                        print '整箱券没整箱'
                        order['coupon'] = None
                    else:
                        if len(coupon) > 4:
                            # (id, 有效期, 金额, 是否已用, 门槛) 2015-09-27
                            # 有门槛信息,使用优惠券门槛信息
                            if (tt + float(order['delivery_fee'])) < coupon[4]:
                                order['coupon'] = None
                            else:
                                order['coupon_disc'] = coupon[2]
                        else:
                            # 使用默认条件
                            if float(coupon[2]) == 6.0 and (
                                    tt + float(order['delivery_fee'])) < 29.9:
                                order['coupon'] = None
                            elif float(coupon[2]) == 9.0 and (
                                    tt + float(order['delivery_fee'])) < 39.9:
                                order['coupon'] = None
                            elif (tt + float(order['delivery_fee'])) < 14.9:
                                order['coupon'] = None
                            else:
                                order['coupon_disc'] = coupon[2]
                else:
                    order['coupon'] = None

                # 计算应付:价格合计 - 优惠券 - 首单立减 + 运费
                print(tt + float(order['delivery_fee']) -
                      float(order['coupon_disc']) - float(order['first_disc']))
                print tt, float(order['delivery_fee']), float(
                    order['coupon_disc']), float(order['first_disc'])
                order['due'] = '%.2f' % (tt + float(order['delivery_fee']) -
                                         float(order['coupon_disc']) -
                                         float(order['first_disc']))

                if float(order['due']) <= 0:
                    order['due'] = '0.10'

            # 如果没有,则insert
            #db.order_app.replace_one({'order_id':order_id}, order, upsert=True)
            db.order_app.update_one({'order_id': order_id}, {
                '$set': order,
                '$push': {
                    'history': (app_helper.time_str(), uname, '提交结算')
                }
            },
                                    upsert=True)

            ret_json = {  # 返回结果,实际有库存的结果,
                'ret': 0,
                'data': {
                    'order_id': order['order_id'],
                    'shop_id': str(order['shop']),
                    'shop': db_shop['name'],  # 可能会变,如果地址与门店不匹配的时候
                    'addr_id': address[0],
                    'cart_num': len(order['cart']),
                    'cart': cart_to_return,
                    'total': order['total'],
                    'coupon': coupon[0] if order['coupon'] else '',
                    'coupon_disc': order['coupon_disc'],
                    'first_disc': order['first_disc'],
                    'delivery_fee': order['delivery_fee'],
                    'due': order['due'],
                    'credit': '%.2f' % db_user.get('credit', 0.0)
                }
            }
            print ret_json
            return json.dumps(ret_json)
        else:
            return json.dumps({'ret': -4, 'msg': '无效的session'})
コード例 #3
0
ファイル: wxpay.py プロジェクト: jack139/fair
    def POST(self, version='v2'):
        web.header('Content-Type', 'application/json')
        if version not in ('v2', 'v3'):
            return json.dumps({'ret': -999, 'msg': '版本错误!'})
        print 'version=', version

        param = web.input(app_id='',
                          session='',
                          order_id='',
                          total='',
                          note='',
                          sign='')

        if version == 'v2':
            if '' in (param.app_id, param.order_id, param.session, param.total,
                      param.sign):
                return json.dumps({'ret': -2, 'msg': '参数错误'})
        elif version == 'v3':
            if '' in (param.app_id, param.session, param.total, param.sign):
                return json.dumps({'ret': -2, 'msg': '参数错误'})

        if web.ctx.has_key('environ'):
            client_ip = web.ctx.environ['REMOTE_ADDR']
        else:
            return json.dumps({'ret': -5, 'msg': '无法取得客户端ip地址'})

        uname = app_helper.app_logged(param.session)  # 检查session登录
        if uname:
            #验证签名
            md5_str = app_helper.generate_sign([
                param.app_id, param.session, param.order_id, param.total,
                param.note
            ])
            if md5_str != param.sign:
                return json.dumps({'ret': -1, 'msg': '签名验证错误'})

            #db_shop = db.base_shop.find_one({'_id':ObjectId(setting.default_shop)},{'name':1})

            # 统一下单接口获取 prepay_id
            nonce_str = app_helper.my_rand(30)
            body = 'U掌柜app'
            trade_type = 'APP'

            if version == 'v2':
                order_id = '%s_%d' % (param.order_id.encode('utf-8'),
                                      int(time.time()))
            elif version == 'v3':
                if len(param.order_id) > 0:
                    order_id = '%s_%d' % (param.order_id.encode('utf-8'),
                                          int(time.time()))
                    print order_id
                else:
                    # 生成order_id
                    order_id = app_helper.get_new_order_id(version).encode(
                        'utf-8')
                    print 'new order_id', order_id

            total_fee = param.total.encode('utf-8')
            para = [('appid', wx_appid), ('body', body), ('mch_id', mch_id),
                    ('nonce_str', nonce_str), ('notify_url', notify_url),
                    ('out_trade_no', order_id),
                    ('spbill_create_ip', client_ip), ('total_fee', total_fee),
                    ('trade_type', trade_type)]

            print para

            stringA = '&'.join('%s=%s' % i for i in para)
            stringSignTemp = '%s&key=%s' % (stringA, api_key)
            sign = hashlib.md5(stringSignTemp).hexdigest().upper()

            para_xml = '<xml>' \
             '<appid>'+wx_appid+'</appid>' \
             '<mch_id>'+mch_id+'</mch_id>' \
             '<nonce_str>'+nonce_str+'</nonce_str>' \
             '<sign>'+sign+'</sign>' \
             '<body>'+body+'</body>' \
             '<out_trade_no>'+order_id+'</out_trade_no>' \
             '<total_fee>'+total_fee+'</total_fee>' \
             '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \
             '<notify_url>'+notify_url+'</notify_url>' \
             '<trade_type>'+trade_type+'</trade_type>' \
             '</xml>'

            print para_xml
            #return json.dumps({'ret' : 0, 'data' : 'here'})

            urllib3.disable_warnings()
            pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False)
            url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
            r = pool.urlopen('POST', url, body=para_xml)
            if r.status == 200:
                data = r.data
                print data
                if version == 'v2':
                    # 记录微信商户订单号
                    db.order_app.update_one(
                        {'order_id': param.order_id},
                        {'$set': {
                            'wx_out_trade_no': order_id
                        }})
                    return json.dumps({'ret': 0, 'data': data})
                elif version == 'v3':
                    if len(param.order_id) > 0:
                        db_order = db.order_app.find_one(
                            {'order_id': param.order_id})
                        if db_order['status'] != 'DUE':
                            print '============================== -100'
                            return json.dumps({
                                'ret': -100,
                                'msg': '订单状态变化,请确认'
                            })
                        ret_json = checkout(
                            version,
                            uname,
                            {
                                'session':
                                param.session,
                                'order_id':
                                param.order_id,
                                'shop_id':
                                str(db_order['shop']),
                                'addr_id':
                                db_order['address'][0],
                                'coupon_id':
                                db_order['coupon'][0]
                                if float(db_order['coupon_disc']) > 0 else '',
                                'cart':
                                json.dumps(db_order['cart']),
                                'app_id':
                                param.app_id,
                                'use_credit':
                                '1' if float(db_order.get('use_credit', '0')) >
                                0 else '',  #2015-11-19
                            })
                        if ret_json['ret'] < 0:
                            # checkout 出错
                            return json.dumps({
                                'ret': ret_json['ret'],
                                'msg': ret_json['msg']
                            })

                        if float(ret_json['data']['due']) != float(
                                db_order.get('due3', db_order['due'])):
                            # checkout后金额有变化,说明库存或优惠券有变化
                            db.order_app.update_one(
                                {'order_id': param.order_id}, {
                                    '$set': {
                                        'status': 'CANCEL'
                                    },
                                    '$push': {
                                        'history':
                                        (app_helper.time_str(), uname['uname'],
                                         '订单取消(微信支付)')
                                    }
                                })
                            print '============================== -100'
                            return json.dumps({
                                'ret': -100,
                                'msg': '很抱歉,数据异常,订单已取消,请重新下单'
                            })

                        # 可支付

                        db.order_app.update_one({'order_id': param.order_id}, {
                            '$set': {
                                'wx_out_trade_no': order_id
                            },
                            '$push': {
                                'history': (app_helper.time_str(),
                                            uname['uname'], '提交微信支付2')
                            }
                        })
                        return json.dumps({
                            'ret': 0,
                            'order_id': param.order_id,
                            'data': data
                        })
                    else:
                        # 生成新订单
                        db_cart = db.app_user.find_one(
                            {'uname': uname['uname']},
                            {'cart_order.%s' % param.session: 1})
                        new_order = dict(db_cart['cart_order'][param.session])
                        new_order['order_id'] = order_id
                        new_order['status'] = 'DUE'
                        new_order['user_note'] = param.note.strip()
                        new_order['wx_out_trade_no'] = order_id
                        new_order['history'] = [(app_helper.time_str(),
                                                 uname['uname'], '提交微信支付')]

                        ret_json = checkout(
                            version,
                            uname,
                            {
                                'session':
                                param.session,
                                'order_id':
                                order_id,
                                'shop_id':
                                str(new_order['shop']),
                                'addr_id':
                                new_order['address'][0],
                                'coupon_id':
                                new_order['coupon'][0]
                                if float(new_order['coupon_disc']) > 0 else '',
                                'cart':
                                json.dumps(new_order['cart']),
                                'app_id':
                                param.app_id,
                                'use_credit':
                                '1' if float(new_order.get('use_credit', '0'))
                                > 0 else '',  #2015-11-23
                            })

                        if ret_json['ret'] < 0:
                            # checkout 出错
                            return json.dumps({
                                'ret': ret_json['ret'],
                                'msg': ret_json['msg']
                            })

                        if float(ret_json['data']['due']) != float(
                                new_order.get('due3', new_order['due'])):
                            # checkout后金额有变化,说明库存或优惠券有变化
                            print '============================== -100'
                            return json.dumps({
                                'ret': -100,
                                'msg': '很抱歉,数据异常,请重新下单'
                            })

                        db.order_app.insert_one(new_order)
                        return json.dumps({
                            'ret': 0,
                            'order_id': order_id,
                            'data': data
                        })
            else:
                return json.dumps({'ret': -1, 'data': r.status})
        else:
            return json.dumps({'ret': -4, 'msg': '无效的session'})
コード例 #4
0
ファイル: order_checkout.py プロジェクト: jack139/fair
def checkout(version, uname, param):
    print param
    # mice 为黄牛手机号标志,mice==1不可以下单 2015-08-22
    db_user = db.app_user.find_one(
        {'uname': uname['uname']},  #, 'mice':{'$ne':1}},
        {
            'coupon': 1,
            'address': 1,
            'credit': 1,
            'app_id': 1,
            'mice': 1
        })
    if db_user == None:  # 不应该发生
        return {'ret': -9, 'msg': '未找到用户信息'}

    # 检查mice, 排除白名单
    if db_user.get(
            'mice') == 1 and uname['uname'] not in app_helper.WHITE_LIST:
        print 'mice !!!'
        return {'ret': -9, 'msg': '未找到用户信息'}

    app_id = db_user['app_id']

    # 修改为付款的过期订单
    r = db.order_app.update_many(
        {
            #'uname'    : {'$in':uname.values()},
            'status': 'DUE',
            'deadline': {
                '$lt': int(time.time())
            }
        },
        {'$set': {
            'status': 'TIMEOUT'
        }})

    # 查找shop
    db_shop = db.base_shop.find_one({'_id': ObjectId(param['shop_id'])})
    if db_shop == None:
        return {'ret': -6, 'msg': 'shop_id错误'}

    # 查询收货地址
    address = None
    for i in db_user['address']:
        if i[0] == param['addr_id']:
            address = list(i)
            break
    if address == None:
        return {'ret': -7, 'msg': 'addr_id错误'}

    # 获得 收货地址 坐标
    if len(address) > 5:  # 使用已有的gps地址
        loc = address[5]
    else:
        ret, loc = lbs.addr_to_loc(address[3].encode('utf-8'))
        if ret < 0:
            # 重试一次
            ret, loc = lbs.addr_to_loc(address[3].encode('utf-8'))
            if ret < 0:
                loc = {'lat': 0, 'lng': 0}
    print loc

    # 多边形检查
    poly_shop = lbs.check_in_poly((loc['lat'], loc['lng']),
                                  db_shop.get('poly_xy', []))
    if poly_shop == None:
        return {'ret': -6, 'msg': 'shop_id错误'}

    ###########################################################################
    # 用收货电话检查黄牛 2015-08-22
    db_recv = db.recv_tel.find_one({'tel': address[2]})
    if db_recv:
        one_more = 0
        if uname['uname'] not in db_recv['unames']:  # 补充疑似账号
            db.recv_tel.update_one({'tel': address[2]},
                                   {'$push': {
                                       'unames': uname['uname']
                                   }})
            one_more = 1
        if len(db_recv['unames']) + one_more > 10:  # 改为10,2015-10-12
            # 发现 mice
            mice = 1
            for b in db_recv['unames']:
                if b in app_helper.WHITE_LIST:  # 过滤白名单相关号码
                    mice = 0
                    break
            db.app_user.update_many({'uname': {
                '$in': db_recv['unames']
            }}, {'$set': {
                'mice': mice
            }})
            db.app_user.update_many({'openid': {
                '$in': db_recv['unames']
            }}, {'$set': {
                'mice': mice
            }})
            if one_more == 1:
                db.app_user.update_one({'uname': uname['uname']},
                                       {'$set': {
                                           'mice': mice
                                       }})
            if mice == 1:
                print '!!! mice:', address[
                    2]  #, uname['uname'], db_recv['unames']
                return {'ret': -9, 'msg': '黄牛下单1'}
    else:
        db.recv_tel.insert_one({'tel': address[2], 'unames': [uname['uname']]})
        #print 'insert', address[2]

    # 用收货地址检查黄牛, 不准确,不能标注 2015-08-23
    db_recv = db.recv_addr.find_one({'addr': address[3]})
    if db_recv:
        one_more = 0
        if uname['uname'] not in db_recv['unames']:
            db.recv_addr.update_one({'addr': address[3]},
                                    {'$push': {
                                        'unames': uname['uname']
                                    }})
            one_more = 1
        if len(db_recv['unames']) + one_more > 10:  # 改为10,2015-10-12
            # 发现疑似mice,不标注,因为不确定
            print '!!! maybe a mice:', address[3].encode(
                'utf-8')  #, uname['uname'], db_recv['unames']
    else:
        db.recv_addr.insert_one({
            'addr': address[3],
            'unames': [uname['uname']]
        })
        #print 'insert', address[2]

    # 用app_id检查黄牛
    appid_count = db.app_user.find({'app_id': app_id}, {'_id': 1}).count()
    if appid_count > 10 and app_id.strip(
    ) != '':  # app_id 可能为空,新绑定的用户 # 改为10,2015-10-12
        # 发现 mice
        db_mice = db.app_user.find({'app_id': app_id}, {'uname': 1})
        mice = []
        for m in db_mice:
            if m['uname'] in app_helper.WHITE_LIST:  # 过滤白名单
                mice = []
                break
            else:
                mice.append(m['uname'])
        db.app_user.update_many({'uname': {
            '$in': mice
        }}, {'$set': {
            'mice': 1
        }})
        if mice != []:
            print '!!! mice by app_id: ', mice
            return {'ret': -9, 'msg': '黄牛下单1'}

    # 查黄牛-结束
    ###########################################################################

    # 查找优惠券
    # 未查到,则不使用优惠券
    coupon = None
    for i in db_user['coupon']:
        if i[0] == param['coupon_id']:
            coupon = list(i)
            break

    # 转换cart数据为json,应该有异常捕获 !!!
    #print param['cart']
    cart = json.loads(param['cart'])
    #print cart

    if len(cart) == 0:
        return {'ret': -5, 'msg': '购物车无数据'}

    if version == 'v2':  # v3 不在这生成订单号
        if param['order_id'] == '':
            #cc = 1
            #while cc!=None:
            #	# 取得sku计数, 不与线下order共用
            #	db_sa = db.user.find_one_and_update(
            #		{'uname'    : 'settings'},
            #		{'$inc'     : {'app_count' : 1}},
            #		{'app_count' : 1}
            #	)
            #	order_id = 'n%06d%s' % (db_sa['app_count'], setting.order_fuffix)
            #	# 防止订单号重复
            #	cc = db.order_app.find_one({'order_id'  : order_id},{'_id':1})
            order_id = app_helper.get_new_order_id(version)
            print 'new order_id', order_id
        else:
            order_id = param['order_id']

            cc = db.order_app.find_one(
                {
                    #'uname'     : {'$in':uname.values()}, # 防止app的bug,重复order_id
                    'order_id': order_id,
                },
                {
                    'status': 1,
                })
            if cc != None and cc['status'] != 'DUE':  # 检查订单状态,只有due才可以checkout
                print "BUG! order_id status"
                return {'ret': -99, 'msg': '订单状态错误'}

    # 订单状态:DUE, PAID, ONROAD, COMPLETED, CANCELED, FINISH
    # 默认运费 5元,免邮门槛 29元
    order = {
        'status': 'DUE',
        'uname': uname['uname'],
        'shop': db_shop['_id'],
        'user': uname['uname'],
        'order_id': order_id if version == 'v2' else '',
        'order_source': app_helper.get_devive_type(param['app_id']),
        'address': address,  # 收货地址
        'coupon': coupon,  # 使用的优惠券
        'cart': [],
        'cost': '0.00',  # 成本合计,参考
        'total': '0.00',  # 价格小计,加项
        'coupon_disc': '0.00',  # 优惠券抵扣,减项
        'first_disc': '0.00',  # 首单立减, 减项
        'delivery_fee': '0.00',  # 运费,加项
        'due': '0.00',  # 应付总金额 2015-11-24
        'openid': uname['openid'],
        'app_uname': uname['uname'],
        'uname_id': db_user['_id'],
        'type': 'HOUR',  # 订单类型, 2015-11-19
        # for processor
        'next_status': '',
        'lock': 0,
        'man': 0,
        'retry': 0,
        'comment': '',
        'b_time': int(time.time()),
        'e_time': int(time.time()),
        'deadline': int(time.time() + 60 * 15),
        'poly_shop': 1 if poly_shop else 0,  # 是否匹配到门店 2015-10-18
        'credit_total': '0.00',  # 余额支付金额 2015-11-24
        'wxpay_total': '0.00',  # 微信支付金额 
        'alipay_total': '0.00',  # 支付宝支付金额 
        'use_credit': '0.00',  # 部分支付时,余额支付金额
        'due3': '0.00',  # 第3方应付金额   use_credit + due3 = due
    }

    # 统计旧订单数,为0则是首单 2015-09-29
    old_order_num = db.order_app.find(
        {
            'user': {
                '$in': uname.values()
            },
            'status': {
                '$nin': ['DUE', 'TIMEOUT', 'CANCEL']
            }
        }, {
            '_id': 1
        }).count()
    # item = {
    #      “product_id” : “k000011”,
    #      “num”        : “5”,
    # }
    # 应该只有 k-prod
    cart_to_return = []
    cart_to_return_b3 = []
    cate_001 = 0
    b3_sku = 0
    all_sku = 0
    num_change = 0
    buy_limit = 0
    only_one = 0
    for item in cart:
        is_b3 = False
        # sku
        db_sku = db.sku_store.find_one({'product_id': item['product_id']}, {
            'app_title': 1,
            'is_onsale': 1,
            'special_price': 1,
            'ref_price': 1,
            'maximun': 1,
            'list_in_app': 1,
        })
        if db_sku == None:  # 应该不会发生
            print 'Error: db_sku==None'
            continue

        all_sku += 1

        if db_sku['list_in_app'] == -3:  # B3 整箱预售 # 不启动B3 2015-10-27
            r = db.inventory.find_one(  # 线上销售要检查库存
             {
              'product_id'  : item['product_id'],
              'list_in_app' : {'$ne' : 0},
              'shop'        : ObjectId(setting.B3_shop),
             },
             {
              'cost_price'  : 1,
              'ref_prod_id' : 1,
              'price'       : 1,
              'sku'         : 1,
              'num'         : 1,
              'category'    : 1,
              'first_order' : 1
             }
            )
            b3_sku += 1
            is_b3 = True  # 标记是B3商品, v3
        elif poly_shop:  # 门店库存
            r = db.inventory.find_one(  # 线上销售要检查库存
             {
              'product_id'  : item['product_id'],
              'list_in_app' : {'$ne' : 0},
              'shop'        : db_shop['_id'],
             },
             {
              'cost_price':1,
              'ref_prod_id':1,
              'price':1,
              'sku':1,
              'num':1,
              'category':1,
              'first_order':1
             }
            )
        else:  # 不在送货范围
            r = None
        if r:  # 如果库存数据中没此sku,会忽略掉,此情况应该不会发生
            new_num = int(item['num'])
            new_num = new_num if new_num <= r['num'] else r['num']
            new_num = max(0, new_num)  # 发现过小于零的情况,微信

            # 检查是不是 001 (水果) 分类
            if r['category'] == '001':
                cate_001 += 1

            # 检查是否限购
            if db_sku['maximun'] > 0:
                '''
				# 每日限购,生成当天的时间tick
				tday = app_helper.time_str(format=1)
				begin_d = '%s 00:00:00' % tday
				end_d = '%s 23:59:59' % tday
				begin_t = int(time.mktime(time.strptime(begin_d,"%Y-%m-%d %H:%M:%S")))
				end_t = int(time.mktime(time.strptime(end_d,"%Y-%m-%d %H:%M:%S")))

				print begin_d, end_d, begin_t, end_t

				# 检查时间段内购买记录
				c = db.order_app.find({
					'uname'           : {'$in':uname.values()},
					'order_id'        : {'$ne':order_id},
					'status'          : {'$ne':'TIMEOUT'},
					'cart.product_id' : item['product_id'],
					'$and'   : [{'b_time' : {'$gt' : begin_t}},
						    {'b_time' : {'$lt' : end_t}}],
				}, {'_id':1}).count()
				print 'findings: ',c
				if c>0: # 限购商品只允许购买1次
					new_num=0
					buy_limit += 1
				else:
					new_num=min(new_num, db_sku['maximun'])
					print 'limit : ',new_num
				'''
                # 每单限购
                if new_num > db_sku['maximun']:
                    new_num = db_sku['maximun']
                    print 'limit : ', new_num

            # 首单可见商品,非首单用户 2015-09-30
            if r.has_key('first_order'
                         ) and r['first_order'] == 1 and old_order_num > 0:
                # 非首单用户,不让购买,还是有人能买到,靠!
                new_num = 0

            # v3 检查是否是互斥商品
            if version == 'v3' and item['product_id'] in app_helper.only_one:
                if only_one > 0:
                    # 已有互斥商品,此商品清零
                    new_num = 0
                else:
                    only_one += 1

            # v3 检查是否买X送Y
            if version == 'v3' and item[
                    'product_id'] in app_helper.buy_X_give_Y.keys():
                numX = app_helper.buy_X_give_Y[item['product_id']][0]
                numY = app_helper.buy_X_give_Y[item['product_id']][1]
                #new_num = int(item['num'])
                new_num_give = int(new_num / numX) * numY
                new_num = new_num if new_num + new_num_give <= r[
                    'num'] else int(r['num'] / (numX + numY)) * numX
                new_num = max(0, new_num)  # 预防小于零的情况
                new_num_give = int(new_num / numX) * numY  # 更新赠品数量

            new_item = {
                'product_id': item['product_id'],
                'num': item['num'],
                'num2': new_num,
                'price': r['price'],
                'title': db_sku['app_title'],
            }

            # v3 买X送Y数量
            if version == 'v3':
                if item['product_id'] in app_helper.buy_X_give_Y.keys():
                    new_item['numyy'] = new_num_give
                else:
                    new_item['numyy'] = 0

            if int(new_num) != int(item['num']):
                num_change += 1

            # 是否有优惠价格
            if db_sku['is_onsale']==1 and \
             float(db_sku['special_price'])<float(r['price']):
                # 优惠价格比门店价格低
                new_item['price'] = db_sku['special_price']

            # 计算总价
            item_price = round(new_num * float(new_item['price']), 2)
            new_item['price'] = '%.2f' % item_price

            if version == 'v3' and is_b3:
                cart_to_return_b3.append(new_item)
            else:
                cart_to_return.append(new_item)  # 返回到app的cart不包含cost

            cost_price = r['cost_price']

            #if item[0][0]=='w': # w-prod 信息都用 u-prod的替换
            #	new_item['product_id'] = r['ref_prod_id']
            #	new_item['w_id'] = item[0]
            #	# 查询成本, 从对应u-prod当前成本
            #	r2 = db.inventory.find_one({ # u-prod
            #		'shop'       : db_shop['shop'],
            #		'product_id' : r['ref_prod_id'],
            #	}, {'cost_price':1})
            #	cost_price = r2['cost_price']

            # 计算成本
            item_cost = round(new_num * float(cost_price), 2)
            new_item['cost'] = '%.2f' % item_cost

            # 加入cart
            order['cart'].append(new_item)

            # 累计售价和成本
            order['total'] = '%.2f' % (float(order['total']) + item_price)
            order['cost'] = '%.2f' % (float(order['cost']) + item_cost)
        else:
            # 店内未找到库存, !!!应该不会发生
            new_item = {
                'product_id': item['product_id'],
                'num': item['num'],
                'num2': 0,
                'price': '0.00',
                'cost': '0.00',
                'title': db_sku['app_title'],
            }
            cart_to_return.append(new_item)  # 返回到app的cart不包含cost
            order['cart'].append(new_item)

            # 记录判断数量变化
            if int(new_item['num2']) != int(item['num']):
                num_change += 1

    tt = float(order['total'])
    if tt > 0:
        # 免邮门槛
        if str(order['shop']) in app_helper.delivery_by_shop.keys():
            delivery_fee = app_helper.delivery_by_shop[str(
                order['shop'])]['delivery_fee']
            free_delivery = app_helper.delivery_by_shop[str(
                order['shop'])]['free_delivery']
        else:
            delivery_fee = app_helper.delivery_fee
            free_delivery = app_helper.free_delivery

        #if tt<29: # 免邮门槛 29
        if tt < free_delivery:  # 免邮门槛
            order['delivery_fee'] = '%.2f' % delivery_fee  # 运费5元

        # 首单立减 first_promote元, 商品总额大于 first_promote_threshold元
        if cate_001 > 0 and old_order_num == 0:
            # 符合首单条件,且有一个水果商品
            print '首单'
            if str(db_shop['_id']) in app_helper.first_promote2_shop and \
             (tt+float(order['delivery_fee']))>=app_helper.first_promote2_threshold:
                # 站点落在 指定站点范围内,使用首单立减2
                print '首单立减 - 指定站点'
                order['first_disc'] = '%.2f' % app_helper.first_promote2
            elif (tt + float(order['delivery_fee'])
                  ) >= app_helper.first_promote_threshold:
                # 其他站点使用首单立减1
                print '首单立减'
                order['first_disc'] = '%.2f' % app_helper.first_promote

        # 优惠券, 检查有效期, 优惠券门槛为10元
        if float(order['first_disc'])==0.0 and coupon!=None and \
         coupon[3]==1 and app_helper.time_str(format=1)<=coupon[1]:
            print '检查抵用券'
            if len(coupon) > 5 and coupon[5] == 'apple' and cate_001 < 1:
                # 水果券,但没有水果 2015-09-29
                print '水果券没水果'
                order['coupon'] = None
            elif len(coupon) > 5 and coupon[5] == 'b3' and b3_sku < 1:
                # 整箱券,但没有整箱 2015-10-18
                print '整箱券没整箱'
                order['coupon'] = None
            else:
                if len(coupon) > 4:
                    # (id, 有效期, 金额, 是否已用, 门槛) 2015-09-27
                    # 有门槛信息,使用优惠券门槛信息
                    if (tt + float(order['delivery_fee'])) < coupon[4]:
                        order['coupon'] = None
                    else:
                        order['coupon_disc'] = coupon[2]
                else:
                    # 使用默认条件
                    if float(coupon[2]) == 6.0 and (
                            tt + float(order['delivery_fee'])) < 29.9:
                        order['coupon'] = None
                    elif float(coupon[2]) == 9.0 and (
                            tt + float(order['delivery_fee'])) < 39.9:
                        order['coupon'] = None
                    elif (tt + float(order['delivery_fee'])) < 14.9:
                        order['coupon'] = None
                    else:
                        order['coupon_disc'] = coupon[2]
        else:
            order['coupon'] = None

        # 计算应付:价格合计 - 优惠券 - 首单立减 + 运费
        print(tt + float(order['delivery_fee']) - float(order['coupon_disc']) -
              float(order['first_disc']))
        print tt, float(order['delivery_fee']), float(
            order['coupon_disc']), float(order['first_disc'])
        order['due'] = '%.2f' % (tt + float(order['delivery_fee']) - float(
            order['coupon_disc']) - float(order['first_disc']))

        # 不能是负的, 要付一点
        if float(order['due']) <= 0:
            order['due'] = '0.10'

        # 是否使用余额(部分)支付, 2015-11-19
        if param.has_key('use_credit') and param['use_credit'] == '1':  # 使用余额
            my_due = float(order['due'])
            my_credit = db_user.get('credit', 0.0)
            if my_credit > my_due:
                order['due3'] = '0.00'
                order['use_credit'] = '%.2f' % my_due
            else:
                order['due3'] = '%.2f' % (my_due - my_credit)
                order['use_credit'] = '%.2f' % my_credit
        else:
            order['use_credit'] = '0.00'
            order['due3'] = order['due']

    # 准备可用的优惠券 2015-09-11
    coupon_list = []
    for i in db_user['coupon']:
        if app_helper.time_str(format=1) > i[1]:  # 过期抵用券
            continue
        elif i[3] != 1:
            continue

        # 检查优惠券条件 b3_sku
        if tt > 0 and float(order['first_disc']) == 0.0:
            if len(i) > 5 and i[5] == 'apple' and cate_001 < 1:  # 水果券没水果
                continue
            if len(i) > 5 and i[5] == 'b3' and b3_sku < 1:  # 整箱券没整箱 2015-10-18
                continue
            if len(i) > 4:  # 带门槛优惠券
                if (tt + float(order['delivery_fee'])) < i[4]:
                    continue
            else:
                # 过滤不符合条件的优惠券
                if float(i[2]) == 6.0 and (
                        tt + float(order['delivery_fee'])) < 29.9:
                    continue
                elif float(i[2]) == 9.0 and (
                        tt + float(order['delivery_fee'])) < 39.9:
                    continue
                elif (tt + float(order['delivery_fee'])) < 14.9:
                    continue
            coupon_list.append({
                'id': i[0],
                'valid': i[1],
                'cash': i[2],
                'status': 'unused',
                'msg1': '条件1',
                'msg2': '条件2',
            })

    coupon_list = quick(coupon_list)

    # 如果没有,则insert
    #db.order_app.replace_one({'order_id':order_id}, order, upsert=True)
    if version == 'v2':
        db.order_app.update_one({'order_id': order_id}, {
            '$set': order,
            '$push': {
                'history': (app_helper.time_str(), uname['uname'], '提交结算')
            }
        },
                                upsert=True)
    elif version == 'v3':
        db.app_user.update_one(
            {'uname': uname['uname']},
            {'$set': {
                'cart_order.%s' % param['session']: order
            }})

    # 提示信息
    #print all_sku, b3_sku
    if poly_shop == False:
        msg_alert = True
        if b3_sku > 0:
            if all_sku > b3_sku:
                #message = '很抱歉,普通商品无法配送到当前地址,商品已更新' #,整箱预售商品可正常购买'
                msg_alert = False
                message = ''
            else:  # 只有 b3 商品时不提醒
                msg_alert = False
                message = ''
        else:
            message = '很抱歉,收货地址不在配送范围内,购物车商品已清空'
    else:
        if num_change > 0:
            msg_alert = True
            message = '库存不足,已更新商品数量,请查看'
        elif buy_limit > 0:
            msg_alert = True
            message = '部分商品限购,已更新商品数量,请查看'
        else:
            msg_alert = False
            message = ''

    if version == 'v2':
        ret_json = {  # 返回结果,实际有库存的结果,
            'ret': 0,
            'data': {
                'order_id': order['order_id'],
                'shop_id': str(order['shop']),
                'shop': db_shop['name'],  # 可能会变,如果地址与门店不匹配的时候
                'addr_id': address[0],
                'cart_num': len(order['cart']),
                'cart': cart_to_return,
                'total': order['total'],
                'coupon_list': coupon_list,  # 可用的优惠券 
                'coupon': coupon[0] if order['coupon'] else '',
                'coupon_disc': order['coupon_disc'],
                'first_disc': order['first_disc'],
                'delivery_fee': order['delivery_fee'],
                'due': order['due'],
                'credit': '%.2f' % db_user.get('credit', 0.0),
                'alert': msg_alert,
                'message': message,
            }
        }
    elif version == 'v3':
        hh = time.localtime().tm_hour
        if hh >= 9 and hh < 20:
            alert_title = False
            cart_title = ''
        else:
            alert_title = True
            if hh >= 20 and hh <= 23:
                cart_title = '目前是掌柜打烊时间,预计明日9点送出'
            else:
                cart_title = '目前是掌柜打烊时间,预计今日9点送出'

        if b3_sku > 0:
            if hh < 16:
                # 明天
                tomorrow_tick = int(time.time()) + 3600 * 24
                tomorrow = time.strftime("%m月%d日",
                                         time.localtime(tomorrow_tick))
                cart_title_b3 = '以下预售商品,预计明天%s送达' % tomorrow
            else:
                # 后天
                the_day_after_tick = int(time.time()) + 3600 * 24 * 2
                the_day_after = time.strftime(
                    "%m月%d日", time.localtime(the_day_after_tick))
                cart_title_b3 = '以下预售商品,预计后天%s送达' % the_day_after
        else:
            cart_title_b3 = ''

        ret_json = {  # 返回结果,实际有库存的结果,
            'ret': 0,
            'data': {
                'shop_id': str(order['shop']),
                'shop': db_shop['name'],  # 可能会变,如果地址与门店不匹配的时候
                'addr_id': address[0],
                'cart_num': len(order['cart']),
                'cart': cart_to_return,
                'cart_b3': cart_to_return_b3,
                'total': order['total'],
                'coupon_list': coupon_list,  # 可用的优惠券 
                'coupon': coupon[0] if order['coupon'] else '',
                'coupon_disc': order['coupon_disc'],
                'first_disc': order['first_disc'],
                'delivery_fee': order['delivery_fee'],
                'due': order['due3'],  # 返回的事第3方需支付的金额 2015-11-24
                'use_credit': order['use_credit'],  # 使用余额的金额 2015-11-19
                'credit': '%.2f' % db_user.get('credit', 0.0),
                'alert': msg_alert,
                'message': message,
                'alert_title': alert_title,
                'cart_title': cart_title,
                'alert_title_b3': True,
                'cart_title_b3': cart_title_b3,
            }
        }
    print ret_json

    return ret_json
コード例 #5
0
    def POST(self):
        web.header('Content-Type', 'application/json')
        param = web.input(session_id='', pay_sum='', pay_type='')

        if param.session_id=='':
            return json.dumps({'ret' : -1, 'msg' : 'session_id参数错误'})

        uname = app_helper.wx_logged(param.session_id)
        if uname is None:
            return json.dumps({'ret' : -4, 'msg' : '无效的session_id'})

        if '' in (param.pay_sum, param.pay_type):
            return json.dumps({'ret' : -2, 'msg' : '参数错误'})

        if not param['pay_sum'].isdigit():
            return json.dumps({'ret' : -2, 'msg' : '参数错误'})

        if int(param.pay_type)==3:
            pay_type='wxpay'
        else:
            return json.dumps({'ret' : -5, 'msg' : '错误的pay_type'})

        #--------------------------------------------------

        #生产充值流水号
        deposit_order_id = app_helper.get_new_order_id('vx','d').encode('utf-8')
        print 'new deposit_order_id', deposit_order_id

        wx_total_fee = '%d'%int(param['pay_sum'])
        ali_total_fee = '%.2f'%float(int(wx_total_fee)/100.0)


        # 微信支付,获得prepay信息
        if pay_type=='wxpay':
            if web.ctx.has_key('environ'):
                client_ip = web.ctx.environ['REMOTE_ADDR']
            else:
                return json.dumps({'ret' : -7, 'msg' : '无法取得客户端ip地址'})

            r = wxpay_helper.get_prepay_id(wx_appid, mch_id, 
                    'JSAPI', client_ip, deposit_order_id, wx_total_fee,
                    uname['openid'].encode('utf-8'))
            if r.status==200:
                wx_prepay_data = r.data
            else:
                return json.dumps({'ret' : -6, 'data' : r.status}) # 获取prepay信息错误
        else:
            wx_prepay_data = ''

        print wx_prepay_data

        # 生成充值订单
        new_deposit_order = {
            'userid'           : uname['userid'],
            'recharge_id'      : deposit_order_id,
            'order_trade_flow_id'   : '', # 交易记录的id,收到钱时候才填
            'create_time'      : app_helper.time_str(),
            'recharge_sum'     : wx_total_fee,  # 实际充值金额, 如果有满送,在这里处理
            'due'              : wx_total_fee,  # 实际应付的金额,支付成功时会核对这个金额
            'pay_type'         : pay_type, 
            'status'           : 'DUE',
            'wx_prepay_data'   : wx_prepay_data,
            'deadline'         : int(time.time())+60*15,
        }

        db.order_recharge.update_one(
            {'recharge_id' : deposit_order_id},
            {'$set' : new_deposit_order},
            upsert=True
        )

        ret_data = {
            'order_trade_id' : deposit_order_id,  # 实际返回的是充值订单号
            'pay_type'       : int(param.pay_type), 
            'notify_url'     : '', # 支付宝和微信的异步通知回调url
        }

        # 回调地址
        ret_data['notify_url'] = notify_url_wx
        print notify_url_wx

        if wx_prepay_data!='':
            try:
                import xml.etree.cElementTree as ET
            except ImportError:
                import xml.etree.ElementTree as ET

            xml=ET.fromstring(wx_prepay_data)
            ret_data['appid']  = xml.find('appid').text if xml.find('appid') is not None else ''
            ret_data['mch_id']  = xml.find('mch_id').text if xml.find('mch_id') is not None else ''
            ret_data['prepay_id']  = xml.find('prepay_id').text if xml.find('prepay_id') is not None else ''


        # 返回
        return json.dumps({
            'ret'  : 0,
            'data' : ret_data,
        })
コード例 #6
0
    def POST(self, version='v3'):
        web.header('Content-Type', 'application/json')
        if version not in ('v2', 'v3'):
            return json.dumps({'ret': -999, 'msg': '版本错误!'})
        print 'version=', version

        param = web.input(app_id='',
                          session='',
                          order_id='',
                          total='',
                          note='',
                          sign='')

        if '' in (param.app_id, param.session, param.total, param.sign):
            return json.dumps({'ret': -2, 'msg': '参数错误'})

        uname = app_helper.app_logged(param.session)  # 检查session登录
        if uname:
            #验证签名
            md5_str = app_helper.generate_sign([
                param.app_id, param.session, param.order_id, param.total,
                param.note
            ])
            if md5_str != param.sign:
                return json.dumps({'ret': -1, 'msg': '签名验证错误'})

            #db_shop = db.base_shop.find_one({'_id':ObjectId(setting.default_shop)},{'name':1})

            if len(param.order_id) > 0:
                print param.order_id

                db_order = db.order_app.find_one({'order_id': param.order_id})
                if db_order['status'] != 'DUE':
                    print '============================== -100'
                    return json.dumps({'ret': -100, 'msg': '订单状态变化,请确认'})

                ret_json = checkout(
                    version,
                    uname,
                    {
                        'session':
                        param.session,
                        'order_id':
                        param.order_id,
                        'shop_id':
                        str(db_order['shop']),
                        'addr_id':
                        db_order['address'][0],
                        'coupon_id':
                        db_order['coupon'][0]
                        if float(db_order['coupon_disc']) > 0 else '',
                        'cart':
                        json.dumps(db_order['cart']),
                        'app_id':
                        param.app_id,
                        'use_credit':
                        '1' if float(db_order.get('use_credit', '0')) > 0 else
                        '',  #2015-11-19
                    })
                if ret_json['ret'] < 0:
                    # checkout 出错
                    return json.dumps({
                        'ret': ret_json['ret'],
                        'msg': ret_json['msg']
                    })

                if float(ret_json['data']['due']) != float(
                        db_order.get(
                            'due3',
                            db_order['due'])):  # 返回的是需第三方支付的金额,所有比对due3,而不是due
                    # checkout后金额有变化,说明库存或优惠券有变化
                    db.order_app.update_one({'order_id': param.order_id}, {
                        '$set': {
                            'status': 'CANCEL'
                        },
                        '$push': {
                            'history': (app_helper.time_str(), uname['uname'],
                                        '订单取消(支付宝)')
                        }
                    })
                    print '============================== -100'
                    return json.dumps({
                        'ret': -100,
                        'msg': '很抱歉,数据异常,订单已取消,请重新下单'
                    })

                # 可支付
                db.order_app.update_one({'order_id': param.order_id}, {
                    '$push': {
                        'history':
                        (app_helper.time_str(), uname['uname'], '提交支付宝支付2')
                    }
                })
                return json.dumps({'ret': 0, 'order_id': param.order_id})

            else:
                # 生成order_id
                order_id = app_helper.get_new_order_id(version)

                print 'new order_id', order_id

                # 生成新订单
                db_cart = db.app_user.find_one(
                    {'uname': uname['uname']},
                    {'cart_order.%s' % param.session: 1})
                new_order = dict(db_cart['cart_order'][param.session])
                new_order['order_id'] = order_id
                new_order['status'] = 'DUE'
                new_order['user_note'] = param.note.strip()
                new_order['history'] = [(app_helper.time_str(), uname['uname'],
                                         '提交支付宝支付')]

                ret_json = checkout(
                    version,
                    uname,
                    {
                        'session':
                        param.session,
                        'order_id':
                        order_id,
                        'shop_id':
                        str(new_order['shop']),
                        'addr_id':
                        new_order['address'][0],
                        'coupon_id':
                        new_order['coupon'][0]
                        if float(new_order['coupon_disc']) > 0 else '',
                        'cart':
                        json.dumps(new_order['cart']),
                        'app_id':
                        param.app_id,
                        'use_credit':
                        '1' if float(new_order.get('use_credit', '0')) > 0 else
                        '',  #2015-11-23
                    })

                if ret_json['ret'] < 0:
                    # checkout 出错
                    return json.dumps({
                        'ret': ret_json['ret'],
                        'msg': ret_json['msg']
                    })

                if float(ret_json['data']['due']) != float(
                        new_order.get('due3', new_order['due'])):
                    # checkout后金额有变化,说明库存或优惠券有变化
                    print '============================== -100'
                    return json.dumps({'ret': -100, 'msg': '很抱歉,数据异常,请重新下单'})

                db.order_app.insert_one(new_order)
                return json.dumps({'ret': 0, 'order_id': order_id})
        else:
            return json.dumps({'ret': -4, 'msg': '无效的session'})
コード例 #7
0
ファイル: wxpay.py プロジェクト: jack139/fair
	def POST(self):
		web.header('Content-Type', 'application/json')
		param = web.input(openid='', session_id='', pt_order_id='', order_id='', type='', total='')

		print param

		if '' in (param.total, param.type):
			return json.dumps({'ret' : -2, 'msg' : '参数错误'})

		if web.ctx.has_key('environ'):
			client_ip = web.ctx.environ['REMOTE_ADDR']
		else:
			return json.dumps({'ret' : -5, 'msg' : '无法取得客户端ip地址'})

		if param.openid=='' and param.session_id=='':
			return json.dumps({'ret' : -2, 'msg' : '参数错误1'})

		# 同时支持openid和session_id
		if param.openid!='':
			uname = app_helper.check_openid(param.openid)
		else:
			uname = app_helper.wx_logged(param.session_id)

		if uname:
			db_shop = db.base_shop.find_one({'_id':ObjectId(setting.default_shop)},{'name':1})

			db_session = db.app_sessions.find_one({'session_id':param.session_id},{'ticket':1}) 
			ticket = db_session.get('ticket','')

			# 修改为付款的过期订单
			r = db.order_app.update_many({
				'uname'    : {'$in' : uname.values()},
				'status'   : 'DUE',
				'deadline' : {'$lt':int(time.time())}
			}, {'$set': {'status':'TIMEOUT'}})

			# 统一下单接口获取 prepay_id
			nonce_str = app_helper.my_rand(30)
			body = 'U掌柜app'
			trade_type = 'JSAPI'
			if len(param.order_id)>0:
				#order_id = '%s_%d' % (param.order_id.encode('utf-8'), int(time.time()))
				order_id = param.order_id.encode('utf-8')
			else:
				# 生成order_id, 2015-10-29
				order_id = app_helper.get_new_order_id('x').encode('utf-8')
				# 拼团订单 t 开头
				if param.type=='TUAN':
					order_id = 't'+order_id[1:]
			total_fee = param.total.encode('utf-8')
			openid = uname['openid'].encode('utf-8')
			para = [
				('appid'            , wx_appid),
				('body'             , body),
				('mch_id'           , mch_id),
				('nonce_str'        , nonce_str),
				('notify_url'       , notify_url),
				('openid'           , openid),
				('out_trade_no'     , order_id),
				('spbill_create_ip' , client_ip),
				('total_fee'        , total_fee),
				('trade_type'       , trade_type)
			]

			#print para

			stringA = '&'.join('%s=%s' % i for i in para)
			stringSignTemp = '%s&key=%s' % (stringA, api_key)
			sign = hashlib.md5(stringSignTemp).hexdigest().upper()

			para_xml = '<xml>' \
				'<appid>'+wx_appid+'</appid>' \
				'<mch_id>'+mch_id+'</mch_id>' \
				'<nonce_str>'+nonce_str+'</nonce_str>' \
				'<sign>'+sign+'</sign>' \
				'<body>'+body+'</body>' \
				'<out_trade_no>'+order_id+'</out_trade_no>' \
				'<total_fee>'+total_fee+'</total_fee>' \
				'<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \
				'<notify_url>'+notify_url+'</notify_url>' \
				'<trade_type>'+trade_type+'</trade_type>' \
				'<openid>'+openid+'</openid>' \
				'</xml>'

			print para_xml
			#return json.dumps({'ret' : 0, 'data' : 'here'})

			urllib3.disable_warnings()
			pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False)
			url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
			r = pool.urlopen('POST', url, body=para_xml)
			if r.status==200:
				data = r.data
				print data
				# 检查和生成订单
				if len(param.order_id)>0:
					db_order = db.order_app.find_one({'order_id':param.order_id})
					if db_order['status']!='DUE':
						print '============================== -100'
						return json.dumps({'ret' : -100, 'msg' : '订单状态变化,请确认'})

					# 再次 checkout
					if param.type=='TUAN':
						ret_json = pt_checkout( uname, {
							'region_id'   : db_order['region_id'],
							'addr_id'     : db_order['address'][0],
							'coupon_id'   : db_order['coupon'][0] if float(db_order['coupon_disc'])>0 else '',
							'cart'        : json.dumps(db_order['cart']),
							'pt_order_id' : db_order['pt_order_id'],
						})
						if ret_json['ret']<0:
							# checkout 出错
							return json.dumps({'ret' : ret_json['ret'], 'msg' : ret_json['msg']})
					else:
						ret_json = checkout( uname, {
							'shop_id'     : str(db_order['shop']),
							'addr_id'     : db_order['address'][0],
							'coupon_id'   : db_order['coupon'][0] if float(db_order['coupon_disc'])>0 else '',
							'cart'        : json.dumps(db_order['cart']),
							'order_id'    : db_order['order_id'],
						})
						if ret_json['ret']<0:
							# checkout 出错
							return json.dumps({'ret' : ret_json['ret'], 'msg' : ret_json['msg']})

						if float(ret_json['data']['due'])!=float(db_order['due']):
							# checkout后金额有变化,说明库存或优惠券有变化
							db.order_app.update_one({'order_id':param.order_id},{
								'$set'  : {'status': 'CANCEL'},
								'$push' : {'history':(app_helper.time_str(), uname['uname'], '订单取消(微信支付)')}
							})
							print '============================== -100'
							return json.dumps({'ret' : -100, 'msg' : '很抱歉,数据异常,订单已取消,请重新下单'})

					# 可支付
					db.order_app.update_one({'order_id':param.order_id},{
						'$set'  : {'wx_out_trade_no':order_id},
						'$push' : {'history':(app_helper.time_str(), uname['openid'], '提交微信支付2')}
					})
					if param.type=='TUAN':
						# 拼团订单
						return json.dumps({
							'ret'         : 0, 
							'order_id'    : param.order_id, 
							'pt_order_id' : db_order['pt_order_id'],
							'position'    : db_order['position'], 
							'data'        : data, 
							'ticket'      : ticket
						})
					else:
						# 1小时订单
						return json.dumps({
							'ret'      : 0, 
							'order_id' : param.order_id, 
							'data'     : data, 
							'ticket'   : ticket
						})
				else:
					# 生成新订单
					db_cart = db.app_user.find_one({'openid':uname['openid']},{'cart_order_wx':1})
					if param.type=='TUAN':
						# 拼团订单
						if not db_cart.has_key('cart_order_wx'):
							print 'fail: 不该发生, 缺少购物车数据'
							return json.dumps({'ret' : -9, 'msg' : '系统错误,请重试!'})

						new_order = dict(db_cart['cart_order_wx'][0])
						new_order['order_id']=order_id
						new_order['status']='DUE'
						new_order['user_note']=param.note.strip()
						new_order['wx_out_trade_no']=order_id
						new_order['history']=[(app_helper.time_str(), uname['openid'], '提交微信支付')]

						# 如果是新开团,添加pt_order
						if len(db_cart['cart_order_wx'])>1:
							new_pt_order = dict(db_cart['cart_order_wx'][1])
							new_pt_order['pt_order_id']='pt'+order_id[1:]
							new_pt_order['status']='WAIT'
							new_pt_order['history']=[(app_helper.time_str(), uname['openid'], '等待开团')]
							db.pt_order.insert_one(new_pt_order)
							# 订单数据里添加 pt_order_id
							new_order['pt_order_id']=new_pt_order['pt_order_id']

						# 再次 checkout
						ret_json = pt_checkout( uname, {
							'region_id'   : new_order['region_id'],
							'addr_id'     : new_order['address'][0],
							'coupon_id'   : new_order['coupon'][0] if float(new_order['coupon_disc'])>0 else '',
							'cart'        : json.dumps(new_order['cart']),
							'pt_order_id' : new_order['pt_order_id'],
						})
						if ret_json['ret']<0:
							print 'checkout 检查未通过,不能支付'
							return json.dumps({'ret' : -9, 'msg' : ret_json['msg']})

						db.order_app.insert_one(new_order)
						return json.dumps({
							'ret'         : 0, 
							'order_id'    : new_order['order_id'], 
							'pt_order_id' : new_order['pt_order_id'],
							'position'    : new_order['position'], # 测试
							'data'        : data, 
							'ticket'      : ticket
						})

					else:
						# 1小时订单
						new_order = dict(db_cart['cart_order_wx'])
						new_order['order_id']=order_id
						new_order['status']='DUE'
						new_order['user_note']=param.note.strip()
						new_order['wx_out_trade_no']=order_id
						new_order['history']=[(app_helper.time_str(), uname['openid'], '提交微信支付')]

						# 再次 checkout
						ret_json = checkout( uname, {
							'shop_id'     : str(new_order['shop']),
							'addr_id'     : new_order['address'][0],
							'coupon_id'   : new_order['coupon'][0] if float(new_order['coupon_disc'])>0 else '',
							'cart'        : json.dumps(new_order['cart']),
							'order_id'    : new_order['order_id'],
						})
						if ret_json['ret']<0:
							print 'checkout 检查未通过,不能支付'
							return json.dumps({'ret' : -9, 'msg' : ret_json['msg']})

						if float(ret_json['data']['due'])!=float(new_order['due']):
							# checkout后金额有变化,说明库存或优惠券有变化
							print '============================== -100'
							return json.dumps({'ret' : -100, 'msg' : '很抱歉,数据异常,请重新下单'})

						db.order_app.insert_one(new_order)
						return json.dumps({
							'ret'         : 0, 
							'order_id'    : order_id, 
							'data'        : data, 
							'ticket'      : ticket
						})
			else:
				return json.dumps({'ret' : -1, 'data' : r.status})
		else:
			return json.dumps({'ret' : -4, 'msg' : '无效的openid'})
コード例 #8
0
ファイル: elm_port.py プロジェクト: jack139/fair
def u_new_order(order_id):
    order_app_db = db.order_app.find_one({'elm_order_id': order_id},
                                         {'order_id': 1})
    if order_app_db:
        print 'elm ********* 订单已存在'
        return 'ok'
    else:
        restaurant_info_path_url = "/order/{0}/".format(order_id)
        method = 'GET'
        params = {}
        response = elm_helper.elm_port(restaurant_info_path_url, params,
                                       method)
        dict = json.loads(response)
        if dict['code'] == 200:
            print dict['data']
            detail = dict['data']['detail']
            #print dict['data']['restaurant_id']
            address = [
                'elm',
                dict['data']['consignee'],
                dict['data']['phone_list'][0],
                #dict['data']['address'],
                #dict['data']['address'].encode('utf-8')+'('+dict['data']['delivery_poi_address'].encode('utf-8')+')',
                dict['data']['delivery_poi_address']
                if dict['data']['delivery_poi_address'] != None else
                dict['data']['address'],
            ]
            status = 'PAID'
            '''根据restaurant_id查询shop_id'''
            shop_id = db_rep.shop_restaurant.find_one(
                {'elm_restaurant_id': dict['data']['restaurant_id']},
                {'shop_id': 1})
            print 'elm *********** shop_id: ', shop_id
            if shop_id == None:
                print 'elm ???????????? 未找到 restaurant_id'
                return 'error'
            order_id = 'e' + app_helper.get_new_order_id(
                've')  # 新订单号逻辑 2015-10-24
            delivery_fee = dict['data']['deliver_fee']
            first_disc = 0.0
            cost = 0.0
            first_disc = 0.0
            user = '******'
            due = dict['data']['original_price']
            history = [[
                dict['data']['created_at'], dict['data']['phone_list'][0],
                '饿了吗接单'
            ]]
            retry = 0
            #print dict['data']['created_at'],type(dict['data']['created_at'])
            e_time = int(
                time.mktime(
                    time.strptime(dict['data']['created_at'],
                                  '%Y-%m-%d %H:%M:%S')))
            b_time = int(
                time.mktime(
                    time.strptime(dict['data']['created_at'],
                                  '%Y-%m-%d %H:%M:%S')))
            coupon = []
            uname = 'elm'
            coupon_disc = 0.0
            comment = ''
            man = 0
            pay = dict['data']['original_price']
            paid_tick = int(
                time.mktime(
                    time.strptime(dict['data']['created_at'],
                                  '%Y-%m-%d %H:%M:%S')))
            change = 0.0
            paid_time = dict['data']['created_at']
            deadline = int(
                time.mktime(
                    time.strptime(dict['data']['created_at'],
                                  '%Y-%m-%d %H:%M:%S')))
            lock = 0
            next_status = ''
            paid2_tick = int(
                time.mktime(
                    time.strptime(dict['data']['created_at'],
                                  '%Y-%m-%d %H:%M:%S')))
            paid2_time = dict['data']['created_at']
            pay_type = 'elm'
            user_note = dict['data']['description']

            cart = []
            elm_order_id = dict['data']['order_id']
            total = 0

            b2 = []  # C端商品 2015-10-09
            b3 = []  # B3整箱预售商品 2015-10-09
            b3_total = 0.0  # 2015-10-09
            for g2 in detail['group']:
                for g in g2:  # 可能多个篮子
                    '''根据shop_id和elm_food_id查询produc_id'''
                    product_id_db = db_rep.product_category.find_one(
                        {
                            'shop': shop_id['shop_id'],
                            'elm_food_id': g['id']
                        }, {'product_id': 1})
                    if product_id_db == None:
                        print 'elm ???????????? 未找到elm_food_id', g['id']
                        return 'error'
                    print 'elm *********** food_id: ', g['id']
                    num = g['quantity']
                    num2 = g['quantity']
                    title = g['name']
                    price = g['quantity'] * g['price']
                    total += price
                    item = {
                        "cost": cost,
                        "product_id": product_id_db['product_id'],
                        "num2": num2,
                        "title": title,
                        "price": price,
                        "num": num,
                        'elm_food_id': g['id']
                    }
                    #cart.append(item)

                    # 记录销售量
                    db.sku_store.update_one(
                        {'product_id': item['product_id']},
                        {'$inc': {
                            'volume': float(item['num2'])
                        }})

                    r3 = db.sku_store.find_one(
                        {'product_id': item['product_id']}, {'list_in_app': 1})
                    if r3['list_in_app'] == -3:  # B3商品不需要改库存 # -3 不启动B3销售 2015-10-27
                        b3_total += float(item['price'])
                        b3.append(item)
                        item['title'] = item['title'] + u'(整箱预售,次日送达)'
                        b2.append(item)
                        continue

                    # 买X送Y
                    if item['product_id'] in app_helper.buy_X_give_Y.keys():
                        print 'elm 买X送Y'
                        numX = app_helper.buy_X_give_Y[item['product_id']][0]
                        numY = app_helper.buy_X_give_Y[item['product_id']][1]
                        item['numyy'] = int(item['num2'] / numX) * numY  # 赠
                    else:
                        item['numyy'] = 0

                    #if item['product_id'] in app_helper.buy_1_give_1:
                    #	print '买一送一'
                    #	lc_num2 = float(item['num2'])
                    #	item['num2'] = int(lc_num2 + lc_num2)
                    #	item['title'] = item['title'].replace(u'买一送一',u'特惠活动')

                    # 过滤数量价格为零的
                    if item['num2'] == 0 and float(item['price']) == 0.0:
                        continue

                    # num2 实际购买数量, numyy 赠送数量, v3之后才有munyy  2015-10-20
                    num_to_change = float(item['num2']) + float(
                        item.get('numyy', 0.0))
                    r2 = db.inventory.find_one_and_update(  # 不检查库存,有可能负库存
                     {
                      'product_id' : item['product_id'],
                      'shop'       : shop_id['shop_id'],
                     },
                     {
                      '$inc'  : {
                       'num'         : 0-num_to_change, # num2 实际购买数量
                       'pre_pay_num' : num_to_change, # 记录预付数量
                      }
                      #'$push' : { 'history' : (helper.time_str(),
                      #	helper.get_session_uname(), '售出 %s' % str(item['num']))},
                     },
                     {'_id':1}
                    )
                    #print r
                    if r2 == None:  # 不应该发生
                        print 'elm *********** 修改库存失败,请联系管理员!'
                        return 'ok'
                        #return json.dumps({'ret' : -9, 'msg' : '修改库存失败,请联系管理员!'})
                    else:
                        b2.append(item)

                    #print shop_id['shop_id'],'==='
                    #print product_id_db['product_id']
                    #print g['id']

                    # 更新elm库存数据
                    app_helper.elm_modify_num(shop_id['shop_id'],
                                              item['product_id'])

            # 新的订单信息
            r = {
                'address': address,
                'b_time': b_time,
                'cart': b2,  #cart,
                'comment': comment,
                'cost': '%.2f' % cost,
                'coupon': coupon,
                'coupon_disc': '%.2f' % coupon_disc,
                'deadline': deadline,
                'delivery_fee': '%.2f' % delivery_fee,
                'due': '%.2f' % due,
                'e_time': e_time,
                'first_disc': '%.2f' % first_disc,
                'history': history,
                'lock': lock,
                'man': man,
                'next_status': next_status,
                'order_id': order_id,
                'order_source': 'elm',
                'paid2_tick': paid2_tick,
                'paid2_time': paid2_time,
                'paid_tick': paid_tick,
                'paid_time': paid_time,
                'pay': '%.2f' % pay,
                'pay_type': pay_type,
                'retry': retry,
                'shop': shop_id['shop_id'],
                'status': status,
                'total': '%.2f' % total,
                'uname': uname,
                'user': user,
                'elm_order_id': elm_order_id,
                'user_note': user_note,
                'type': 'HOUR',
                'credit_total': '0.00',  # 余额支付金额 2015-11-24
                'wxpay_total': '0.00',  # 微信支付金额 
                'alipay_total': '0.00',  # 支付宝支付金额 
                'use_credit': '0.00',  # 部分支付时,余额支付金额
                'due3': '0.00',  # 第3方应付金额   use_credit + due3 = due
            }

            # 检查是否有b3商品, 3种情况
            # 1. b2, b3 都有,拆单
            # 2. 只有b3,站点改为B3站点,保留收货站点
            # 3. 只有b2,保持订单不变
            #print b2
            #print b3
            if len(b3) > 0 and (len(b2) - len(b3)) > 0:  # 情况1
                print "elm 拆单"
                r4 = r.copy()
                r4['order_id'] = r4['order_id'] + u'-b3'
                r4['shop_0'] = r['shop']
                r4['shop'] = ObjectId(setting.B3_shop)
                r4['cart'] = b3
                r4['status'] = status
                r4['elm_order_id'] = elm_order_id  # 饿了吗 订单号
                r4['paid_time'] = app_helper.time_str()
                r4['paid_tick'] = int(time.time())
                r4['history'] = [(app_helper.time_str(), 'elm_port', 'elm-拆单')]
                r4['total'] = '%.2f' % b3_total
                r4['cost'] = '0.00'
                r4['coupon_disc'] = '0.00'
                r4['first_disc'] = '0.00'
                r4['delivery_fee'] = '0.00'
                r4['due'] = '0.00'
                db.order_app.insert_one(r4)  # 增加子订单
            elif len(b3) > 0:  # 情况 2
                print "elm 订单改到B3站点"
                db.order_app.update_one({'order_id': order_id}, {
                    '$set': {
                        'shop_0': r['shop'],
                        'shop': ObjectId(setting.B3_shop),
                    }
                })
            else:  # 情况3,什么都不做
                print "elm 订单保持不变"

            print 'elm *********** order_id: ', order_id
            '''将查询的订单详情插入U掌柜数据库中'''
            db.order_app.insert_one(r)
            return 'ok'
        else:
            print 'elm ???????????? elm 订单拉取失败'
            print dict
            return 'error'