def lock_bonus(self): """对订单礼券、抵扣金进行加锁冻结(发生在订单提交支付前)""" from core.models.welfare import FirewoodWorkflow, FirewoodBurning if self.woods_burning: flow = FirewoodWorkflow(self.user_id) flow.pick(self.woods_burning, tags=[FirewoodBurning.Kind.deduction.name]) if self.coupon: self.coupon.shell_out(self.product, self.amount)
def initialize(): if not g.user: return redirect(url_for('accounts.login.login', next=request.path)) # 圣诞游戏获取红包的用户如果没有身份信息则跳转 game_gift = ChristmasGift.get_by_mobile_phone(g.user.mobile) if not has_real_identity( g.user) and game_gift and game_gift.rank.award.firewood_wrapper: return redirect(url_for('profile.auth.supply', next=request.path)) # 礼券管理 g.coupon_manager = CouponManager(g.user.id_) # 为用户创建抵扣金账户 g.firewood_flow = FirewoodWorkflow(g.user.id_) # 用户浏览任意福利相关页,则关闭福利提醒提示 welfare_reminder_group.remove_member(g.user.id_) # 用户红包记录 pileds = FirewoodPiling.get_multi_by_user(g.user.id_) burneds = FirewoodBurning.get_multi_by_user(g.user.id_) g.records = sorted(pileds + burneds, key=attrgetter('creation_time'), reverse=True) # 临时:用户访问该页面时默认将相关通知置为已读 unread_notices = Notification.get_multi_unreads_by_user(g.user.id_) unread_notices = [ n for n in unread_notices if n.kind is welfare_gift_notification ] for un in unread_notices: un.mark_as_read()
def initialize_bankcard_manager(): if hasattr(request, 'oauth'): g.bankcard_manager = BankCardManager(request.oauth.user.id_) g.firewood_flow = FirewoodWorkflow(request.oauth.user.id_) g.coupon_manager = CouponManager(request.oauth.user.id_) else: g.bankcard_manager = None
def confirm_bonus(self): """确认礼券、抵扣金被使用(发生在订单已经被告知成功)""" from core.models.welfare import FirewoodWorkflow if self.status is not self.Status.success: raise ValueError('order %s payment has not succeeded' % self.id_) if self.woods_burning: FirewoodWorkflow(self.user_id).burn(self.woods_burning) if self.coupon: self.coupon.confirm_consumption() self.coupon_record.commit()
def unlock_bonus(self): """释放礼券、抵扣金(发生在订单已经被告知失败)""" from core.models.welfare import FirewoodWorkflow if self.status not in [self.Status.unpaid, self.Status.failure]: raise ValueError('order %s payment has not terminated' % self.id_) if self.woods_burning: FirewoodWorkflow(self.user_id).release(self.woods_burning) if self.coupon: self.coupon.put_back_wallet() for hike in self.profit_hikes: hike.renew()
def invite(): code = request.args.get('inviter', None) or request.cookies.get(INVITER_KEY) is_lottery = request.args.get('lottery', False) if not code: return abort(404) # 兼容已分享错误链接 rs = re.search('^(\d+).*', code) if not rs: abort(404) code = rs.group(1) user_id = transform_digit(code) if g.user: if g.user.id_ == str(user_id): if not is_lottery: return redirect(url_for('.mine')) g.firewood_flow = FirewoodWorkflow(g.user.id_) if not g.firewood_flow.account_uid: return redirect( url_for('profile.auth.supply', next=request.path)) user_lottery = UserLottery.get(g.user.id_) return render_template('activity/lottery/index.html', remain_num=user_lottery.remain_num) else: return redirect(url_for('.login')) user = Account.get(user_id) if not user: abort(404) UserLotteryNum.add_by_share(user.id_) @after_this_request def set_cookie(response): response.set_cookie(key=INVITER_KEY, value=str(code), expires=datetime.now() + timedelta(hours=INVITER_KEY_EXPIRE_HOURS)) return response identity = Identity.get(user_id) inviter_name = identity.masked_name if identity else generate_nickname( user.mobile, ACCOUNT_REG_TYPE.MOBILE) return render_template('invite/invite.html', inviter_name=inviter_name)
def initialize(): if not g.user: return redirect(url_for('accounts.login.login', next=request.path)) g.firewood_flow = FirewoodWorkflow(g.user.id_) if not g.firewood_flow.account_uid: return redirect(url_for('profile.auth.supply', next=request.path))
def unpack(self, user, reserved_sha1=None, allow_piling_firewood=True, dynamic_firewood_worth=None): """Unpacks package to get coupons. :param user: The user who gained this package. :param reserved_sha1: Optional. The reserved SHA1 token. """ from core.models.welfare import Coupon, FirewoodWorkflow self._check_status_transfer( (self.Status.in_air, self.Status.under_foot), self.Status.in_pocket) # checks for reserved package if self.status is self.Status.under_foot: if reserved_sha1 is None: raise ValueError('reserved_sha1 is required') if not safe_str_cmp(reserved_sha1, self.reserved_sha1): raise WrongPackageTokenError('reserved_sha1 is wrong') if self.status is self.Status.in_air and reserved_sha1 is not None: raise ValueError('coupon package has not been reserved') # checks with strategy if self.kind.distributor and not self.kind.distributor.can_unpack( user=user, package=self): raise PackageDistributorDenied('distributor denied', self.id_) self.user_id = user.id_ self.status = self.Status.in_pocket self.unpacked_time = datetime.now() sql = ('update {.table_name} set user_id=%s, status=%s, ' 'unpacked_time=%s where id=%s').format(self) params = (self.user_id, self.status.value, self.unpacked_time, self.id_) db.execute(sql, params) db.commit() # release coupon here if self.kind.coupon_wrappers: try: for wrapper in self.kind.coupon_wrappers: for _ in xrange(wrapper.amount): Coupon.create(wrapper.name, wrapper.kind, self, wrapper.product_matcher_kind, wrapper.platforms, wrapper.expire_time, _commit=False) except: db.rollback() raise else: db.commit() # pile fire woods if allow_piling_firewood and self.kind.firewood_wrapper: FirewoodWorkflow(user.id_).pile( user, self.kind.firewood_wrapper.worth, self, tags=[self.kind.firewood_wrapper.name]) self.clear_cache(self.id_) self.clear_cache_by_user(self.user_id)
def initialize(): if not g.user: return redirect(url_for('accounts.login.login', next=request.path)) g.zhiwang_profile = ZhiwangProfile.add(g.user.id_) g.coupon_manager = CouponManager(g.user.id_) g.firewood_flow = FirewoodWorkflow(g.user.id_)
def checkin(): if not g.user: abort(401) g.firewood_flow = FirewoodWorkflow(g.user.id_) if not g.firewood_flow.account_uid: abort(401)
def initiaize(): if hasattr(request, 'oauth'): g.coupon_manager = CouponManager(request.oauth.user.id_) g.firewood_flow = FirewoodWorkflow(request.oauth.user.id_) # TODO: 此处应根据用户所处平台进行礼券过滤 g.available_coupons = g.coupon_manager.available_coupons
def subscribe_product(user, product, bankcard, order_amount, pay_amount, due_date=None, coupon=None, pocket_deduction_amount=0): """申购产品""" # 检查礼券是否可用、返现账户抵扣是否可用、订单是否可建 if coupon: coupon.check_before_use(product, order_amount) if pocket_deduction_amount > 0: FirewoodWorkflow(user.id_).check_deduction_enjoyable( product, order_amount, pocket_deduction_amount) XMOrder.check_before_adding(user.id_, bankcard.id_, product.product_id, order_amount) # 获取订单优惠信息并检查合法性 hike_list = collect_profit_hikes(user, coupon, pocket_deduction_amount) rate_bonus = max([h.annual_rate for h in hike_list]) if hike_list else Decimal('0') discount_fee = sum([h.deduction_amount for h in hike_list]) assert rate_bonus < Decimal('5.0') # 新米最高加息限制 assert order_amount - discount_fee == pay_amount # 新米使用加息券需要在赎回确认里加入 redeem_confirm = u'1' if rate_bonus > Decimal('0.0') else None rate_fee = float(order_amount * rate_bonus * product.frozen_days / 100 / 365) order_code = XMOrder.gen_order_code() xm_cancel_order_prepare.produce(order_code, delay=TIME_OUT_SECONDS) identity = Identity.get(user.id_) buy_amount = order_amount try: # 向投米发起申购请求 if DEBUG: # 测试环境要求 购买金额x100后为偶数 => 购买成功,否则失败。 if int(buy_amount) % 2 != 0: buy_amount += round_half_up(0.01, 2) buy_amount = round_half_up(buy_amount, 2) response = xinmi.order_apply(product_id=product.product_id, order_id=order_code, buy_amount=buy_amount, discount_fee=discount_fee, user_id=user.id_, province=bankcard.province_id, city=bankcard.city_id, person_name=identity.person_name, person_ricn=identity.person_ricn, mobile=bankcard.mobile_phone, bank_code=bankcard.bank.xm_id, bank_account=bankcard.card_number, account_name=identity.person_name, redeem_confirm=redeem_confirm) except BusinessError as e: raise SubscribeProductError(u'申购产品失败: %s' % e) assert buy_amount == round_half_up(response.buy_amount, 2) if product.product_type == XMProduct.Type.classic: due_date = get_next_work_day( response.buy_time) + datetime.timedelta(days=product.frozen_days) # 创建订单 order = XMOrder.add(user_id=user.id_, product_id=product.product_id, bankcard_id=bankcard.id_, amount=buy_amount, pay_amount=response['total_amount'], expect_interest=response.return_amount + rate_fee, start_date=get_next_work_day(response.buy_time), due_date=due_date, order_code=order_code, pay_code=response.pay_code) # 创建优惠记录 for hike in hike_list: # FIXME: the operation of hikes should be managed in one session Hike.add(user.id_, order.id_, hike.kind, hike.annual_rate, hike.deduction_amount) # 订单预绑定礼券 if coupon: CouponUsageRecord.add(coupon, user, provider_xinmi, order) # 创建抵扣使用记录 if pocket_deduction_amount > 0: FirewoodBurning.add(user, pocket_deduction_amount, FirewoodBurning.Kind.deduction, provider_xinmi, order.id_) return order
def subscribe_product(user, product, bankcard, order_amount, pay_amount, due_date, wrapped_product=None, coupon=None, pocket_deduction_amount=0): """申购产品""" # 检查礼券是否可用、返现账户抵扣是否可用、订单是否可建 if coupon: coupon.check_before_use(wrapped_product or product, order_amount) if pocket_deduction_amount > 0: FirewoodWorkflow(user.id_).check_deduction_enjoyable( wrapped_product or product, order_amount, pocket_deduction_amount) wrapped_product_id = wrapped_product.id_ if wrapped_product else None ZhiwangOrder.check_before_adding(user.id_, bankcard.id_, product.product_id, order_amount, wrapped_product_id) # 获取订单优惠信息并检查合法性 hike_list = collect_profit_hikes(user, coupon, pocket_deduction_amount, wrapped_product) rate_bonus = max([h.annual_rate for h in hike_list]) if hike_list else Decimal('0') deduction_bonus = sum([h.deduction_amount for h in hike_list]) assert rate_bonus < Decimal('5.0') # 指旺最高加息限制 assert order_amount - deduction_bonus == pay_amount try: # 向指旺发起申购请求 response = zhiwang.order_apply_with_coupon( ZhiwangAccount.get_by_local(user.id_).zhiwang_id, # 用户的指旺ID product.product_id, # 用户认购的产品 rate_bonus, # 加息值 order_amount, # 订单金额 pay_amount, # 实际支付金额 bankcard.card_number, # 银行卡号 int(bankcard.bank.zwlib_id), # 银行ID bankcard.mobile_phone, # 银行预留手机号 due_date.strftime('%Y-%m-%d') if due_date else None, # TODO: 认购产品到期日 Division.get(bankcard.province_id, year=2006).name, # 银行卡开卡省份 Division.get(bankcard.city_id, year=2006).name) # 银行卡开卡市 except RemoteError as e: err_msg = e.args[1] err_msg = ZWLIB_ERROR_MAPPING.get(err_msg, err_msg) raise SubscribeProductError(u'申购产品失败: %s' % err_msg) assert pay_amount == response.pay_amount # 创建订单 order = ZhiwangOrder.add(user.id_, product.product_id, bankcard.id_, order_amount, response.pay_amount, response.expect_interest, response.interest_start_date, response.interest_end_date, response.order_code, response.pay_code, wrapped_product_id) # 创建优惠记录 for hike in hike_list: # FIXME: the operation of hikes should be managed in one session Hike.add(user.id_, order.id_, hike.kind, hike.annual_rate, hike.deduction_amount) # 订单预绑定礼券 if coupon: CouponUsageRecord.add(coupon, user, provider_zhiwang, order) # 创建抵扣使用记录 if pocket_deduction_amount > 0: FirewoodBurning.add(user, pocket_deduction_amount, FirewoodBurning.Kind.deduction, provider_zhiwang, order.id_) return order