def cancel_activity(activity_id, cancel_reason=""): """取消活动 1. 取消活动后需要通知用户活动取消,已付款用户将退款 2. 已结算活动不能取消 """ activity = Activity.get_or_404(id=activity_id) if activity.state == Activity.ActivityState.finished: raise ArgumentError(400, "已结束活动不能取消") members = ActivityMember.select().where( ActivityMember.activity == activity_id) with app.db.transaction() as txn: for member in members: member.refund("活动取消") # 修改场次状态为取消 Activity.update(state=Activity.ActivityState.cancelled, cancelled=datetime.now(), cancel_reason=cancel_reason, online_paid_amount=Decimal(0), credit_paid_amount=Decimal(0), cash_paid_amount=Decimal(0), free_times_amount=Decimal(0)).where( Activity.id == activity.id).execute()
def get(self, activity_id, *args, **kwargs): activity = Activity.get_or_404(id=activity_id) if not Activity.is_member(activity.id, user_id=self.current_user): raise ApiException(400, '未参加活动, 不用退出') self.can_leave(activity) activity.leave(user=self.current_user) self.set_status(204)
def gen_next_activity(activity_id): """ 生成下期活动 """ if Activity.select().where(Activity.parent_id == activity_id).exists(): logging.debug("已经存在") return activity = Activity.get_or_404(id=activity_id) # 时间相关都顺延一周 delta = timedelta(days=7) if activity.repeat_end and \ datetime.now() + delta > activity.repeat_end: logging.debug("活动已经结束自动循环") return activity = copy.copy(activity) activity.id = None activity.members_count = 0 activity.comments_count = 0 activity.recommend_time = 0 activity.recommend_region = 0 if activity.join_start: activity.join_start += delta if activity.join_end: activity.join_end += delta activity.cancelled = None activity.cancel_reason = "" activity.finished = None activity.start_time += delta activity.end_time += delta activity.online_paid_amount = 0 activity.credit_paid_amount = 0 activity.cash_paid_amount = 0 activity.free_times_amount = 0 activity.created = datetime.now() activity.updated = datetime.now() activity.state = Activity.ActivityState.opening activity.parent_id = activity_id activity.save() # 更新俱乐部活动数 Team.update_activities_count(activity.team_id)
def initial_data(self): self.team_owner = User.create(name='test_activity') self.team = Team.create(name='club_test_activity', owner_id=self.team_owner.id) self.user = self.creator = User.create(name='activity_creator') self.activity = Activity.create(team=self.team, creator=self.creator, price='10', vip_price='8', leader=self.creator, title='just a test', description='description', need_nickname=True, join_end="3000-12-30 22:59:59", max_members=10, start_time='3000-01-01 00:00:01', end_time='3000-12-31 23:59:59') self.activity_2 = Activity.create(team=self.team, creator=self.creator, price='10', vip_price='8', leader=self.creator, title='just a test', description='description', need_nickname=True, join_end="3000-12-30 22:59:59", max_members=10, start_time='3000-01-01 00:00:01', end_time='3000-12-31 23:59:59') self.activity_member = ActivityMember.create( activity=self.activity, user=self.user, total_fee='0.01', nickname="leave activities", payment_method=TeamOrder.OrderPaymentMethod.WXPAY.value, payment_state=TeamOrder.OrderState.TRADE_BUYER_PAID, ) TeamMemberService.new_order(team=self.team, activity_id=self.activity.id, user=self.user, order_type=TeamOrder.OrderType.ACTIVITY, payment_method='wxpay', total_fee=self.activity.price, payment_fee=self.activity.price, title='TestLeave') TeamOrder.update(state=TeamOrder.OrderState.TRADE_BUYER_PAID)\ .where(TeamOrder.activity_id == self.activity.id, TeamOrder.user == self.user)\ .execute()
def initial_database(): """ 初始化数据库, 重建旧表 创建表 Returns: """ # TODO: 重复代码抽象 from yiyun.helpers import find_subclasses from yiyun.models import BaseModel, Sport, User, Team, Activity # drop old database and create new; test_settings = reject_settings() test_db = test_settings['db_name'] raw_sql = ("drop database {test_db};" "create database {test_db};" "use {test_db};") # create new tables BaseModel._meta.database.execute_sql(raw_sql.format(test_db=test_db)) models = find_subclasses(BaseModel) if not Sport.table_exists(): Sport.create_table() if not User.table_exists(): User.create_table() if not Team.table_exists(): Team.create_table() if not Activity.table_exists(): Activity.create_table() for model in models: if model._meta.db_table.startswith("__"): logging.debug(("table skip: " + model._meta.db_table)) elif model.table_exists(): logging.debug(('table exist: ' + model._meta.db_table)) else: model.create_table() logging.debug(('table created: ' + model._meta.db_table)) logging.debug('create all [ok]')
def post(self): form = self.validated_arguments team = Team.get(id=form.pop("team_id")) self.has_create_permission(team) fields = copy.copy(form) # 如果有地址信息, 获取 GPS 信息 if "city" in form and "address" in form: logging.debug("有 `city` 和 `address` 开始调用远程接口获取 GPS 信息") geocode = yield self.get_geocode(city=form["city"], address=form["address"]) logging.debug("获取到 geocode: {0}".format(geocode)) if geocode.get("geocodes", []): location = geocode['geocodes'][0]['location'].split(",") fields["lat"] = location[1] fields["lng"] = location[0] fields["geohash "] = geohash.encode(float(location[1]), float(location[0])) # TODO: 处理循环类型 if "repeat_type" in form: if form["repeat_type"] == "week": fields["week_day"] = form["start_time"].weekday() + 1 elif form["repeat_type"] == "month": fields["month_day"] = form["start_time"].day activity = Activity.create(team=team, creator=self.current_user, leader=self.current_user, **fields) self.set_status(201) self.write(ActivitySerializer(instance=activity).data)
def test_over_left_count_activity(self): payment = Activity.PaymentType.ONLINE_PAY.value activity = Activity.create(team=self.team, creator=self.creator, leader=self.creator, price='10', vip_price='10', payment_type=payment, title='no online pay', description='on need online pay', state=Activity.ActivityState.opening.value, join_end="3000-12-30 22:59:59", allow_agents=10, start_time='3000-01-01 00:00:01', end_time='3000-12-31 23:59:59', members_count=2, max_members=10) body = { "payment": "wxpay", "nickname": "Nick name", "users_count": 11, } url = self.JOIN_ACTIVITY.format(activity_id=activity.id) self.auth_user = User.create(name='closed activity') response = self.fetch(url, method="POST", body=json.dumps(body), params={'team_id': self.team.id}, headers={"Content-Type": "application/json"}) self.assertEqual(400, response.code, response.body) result = json.loads(response.body.decode()) error = result["error"] self.assertEqual("该活动只有 8 名额了", error, error)
def get(self, activity_id, member_id): activity = Activity.get_or_404(id=activity_id) self.has_read_permission(activity) member = ActivityMember.get_or_404(id=member_id) self.write(InsecureActivityMemberSerializer(member).data)
def get(self, user_id): query = Activity.select( Activity, ActivityMember, TeamOrder, ).join( ActivityMember, on=(ActivityMember.activity == Activity.id).alias('member') ).switch(Activity).join( TeamOrder, join_type=peewee.JOIN_LEFT_OUTER, on=(ActivityMember.order_id == TeamOrder.id).alias('order')).where( Activity.team == self.current_team, ActivityMember.user == user_id).order_by( ActivityMember.id.desc()) query = self.paginate_query(query, per_page=20) activities = [] for activity in query: activity_info = activity.get_info() activity_info['member'] = activity.member.get_info() activity_info['order'] = activity.order.list_info activity_info['order']['state_name'] = activity.order.state_name activities.append(activity_info) self.write({ "activities": activities, "pagination": query.pagination.info })
def test_stoped_activity(self): """活动已报名截止""" payment = Activity.PaymentType.ONLINE_PAY.value activity = Activity.create( team=self.team, creator=self.creator, leader=self.creator, price='10', vip_price='10', start_time='2000-01-01 00:00:01', end_time='3000-12-31 23:59:59', join_end="3000-12-30 22:59:59", payment_type=payment, title='no online pay', description='on need online pay', state=Activity.ActivityState.opening.value, ) body = {"payment": "wxpay", "nickname": "Nick name"} url = self.JOIN_ACTIVITY.format(activity_id=activity.id) self.auth_user = User.create(name='closed activity') response = self.fetch(url, method="POST", body=json.dumps(body), params={'team_id': self.team.id}) self.assertEqual(400, response.code, response.body) result = json.loads(response.body.decode()) error = result["error"] self.assertEqual("活动已报名截止", error, error)
def patch(self, user_id, activity_id): """ 修改报名信息 """ try: activity = Activity.get(id=activity_id) except Activity.DoesNotExist: raise ApiException(404, "活动不存在") self.joined_this_activity(activity_id, user_id) # 校验提交的参数是否合法, 1. 自定义参数; 2. 必填参数是否发生修改 fields = {} fields.update(self.handle_extra_fields(activity=activity)) fields.update(self.handler_required_fields(activity)) if not fields: raise ApiException(400, "填写需要修改的属性和值") ActivityMember.update(**fields)\ .where(ActivityMember.activity == activity_id, ActivityMember.user == user_id)\ .execute() self.set_status(204)
def initial_data(self): self.team_owner = User.create(name='test_activity') self.team = Team.create(name='club_test_activity', owner_id=self.team_owner.id) self.user = self.creator = User.create(name='activity_creator') self.activity = Activity.create(team=self.team, creator=self.creator, price='10', vip_price='8', leader=self.creator, title='just a test', description='description', start_time='3000-01-01 00:00:01', end_time='3000-12-31 23:59:59') self.order = OrderService.new_order(10, self.team, self.user, TeamOrder.OrderType.ACTIVITY, TeamOrder.OrderPaymentMethod.WXPAY, self.activity.id, title="UserOrderTest" ) self.activity.add_member(self.user.id, users_count=1, price=10, free_times=0, total_fee=10, order_id=self.order.id, order_no=self.order.order_no, payment_method=TeamOrder.OrderPaymentMethod.WXPAY, payment_state=TeamOrder.OrderState.TRADE_BUYER_PAID, state=TeamMember.TeamMemberState.normal)
def patch(self, activity_id): """ 修改活动信息 Args: activity_id: Returns: """ activity = Activity.get_or_404(id=activity_id) form = self.validated_arguments self.has_patch_permission(activity) Activity.update(**form).where(Activity.id == activity_id).execute() updated = Activity.get_or_404(id=activity_id) self.write(ActivitySerializer(updated).data)
def get(self, activity_id): activity = Activity.get_or_404(id=activity_id) form = CreateActivityFrom(obj=activity, team=self.current_team) self.render("activity/edit.html", form=form, cities=ChinaCity.get_cities())
def test_finish_activity(self): finish_activity(self.activity.id) try: finish_activity(self.activity.id) except Exception as e: pass finished_activity = Activity.get(id=self.activity.id) rich_team = Team.get(id=self.team.id) new_activity = Activity.get(parent_id=self.activity.id) self.assertEqual(self.online_paid_amount, finished_activity.online_paid_amount) self.assertEqual(finished_activity.state, Activity.ActivityState.finished) self.assertEqual(rich_team.credit, self.online_paid_amount) self.assertIsInstance(new_activity, Activity)
def finish_activities(): """定时执行结算完成的场次 """ activities = Activity.select().where( (Activity.state == Activity.ActivityState.opening.value) & (Activity.end_time <= datetime.now())) for activity in activities: finish_activity.delay(activity.id)
def get(self, activity_id): """ 获取活动详情 Args: activity_id: 活动 ID """ activity = Activity.get_or_404(id=activity_id) serializer = ActivitySerializer(instance=activity) self.write(serializer.data)
def initial_data(self): self.team_owner = User.create(name='test_activity') self.team = Team.create(name='club_test_activity', owner_id=self.team_owner.id) self.user = self.creator = User.create(name='activity_creator') self.activity = Activity.create(team=self.team, creator=self.creator, price='10', vip_price='8', leader=self.creator, title='just a test', description='description')
def get(self, activity_id): activity = Activity.get(id=activity_id) query = ActivityMember.select()\ .where(ActivityMember.activity == activity) query = self.filter_query(query) page = self.paginate_query(query) data = self.get_paginated_data( page=page, alias="members", serializer=self.get_serializer(activity) ) self.write(data)
def _finish_order(self, order: TeamOrder, arguments: dict, payment: PaymentMethod): """ 完成支付流程 Args: order: TeamOrder arguments: dict, 微信服务器回调的 body payment: PaymentMethod, 支付方式 Returns: """ logging.debug('开始终结支付订单[{0}]'.format(order.order_no)) if payment == PaymentMethod.ALIPAY: # 支付宝 gateway_account = arguments["buyer_email"] gateway_trade_no = arguments["trade_no"] else: # 默认违心支付 gateway_trade_no = arguments['transaction_id'] gateway_account = arguments['openid'] TeamOrder.update(state=TeamOrder.OrderState.TRADE_BUYER_PAID, paid=datetime.datetime.now(), gateway_trade_no=gateway_trade_no, gateway_account=gateway_account) \ .where(TeamOrder.order_no == order.order_no) \ .execute() ActivityMember \ .update(payment_method=payment.value, payment_state=TeamOrder.OrderState.TRADE_BUYER_PAID, state=ActivityMember.ActivityMemberState.confirmed, paid=datetime.datetime.now(), confirmed=datetime.datetime.now()) \ .where(ActivityMember.activity == order.activity_id) \ .execute() # 更新活动成员数 Activity.update_members_count(order.activity_id)
def get(self): query = Activity.select( Activity, Sport, ).join( Sport, on=(Activity.sport == Sport.id).alias("sport") ) query = self.filter_query(query) page = self.paginate_query(query) data = self.get_paginated_data(page, alias='activities', serializer=SimpleActivitySerializer) self.write(data)
def test_path_object(self): body = {'title': 'new title', 'need_name': True} url = self.OBJECT_PATH.format(activity_id=self.activity.id) self.auth_user = self.team_owner response = self.fetch(url, method='PATCH', body=json.dumps(body)) self.assertEqual(403, response.code, response.body) self.auth_user = self.creator response = self.fetch(url, method='PATCH', body=json.dumps(body)) self.assertEqual(200, response.code, response.body) updated = Activity.get(id=self.activity.id) self.assertEqual(updated.title, 'new title') self.assertTrue(updated.need_name is True)
def initial_data(self): self.team_owner = User.create(name='test_activity') self.team = Team.create(name='club_test_activity', owner_id=self.team_owner.id) self.user = self.creator = User.create(name='activity_creator') self.activity = Activity.create(team=self.team, creator=self.creator, price='10', vip_price='8', leader=self.creator, title='just a test', description='description', start_time='3000-01-01 00:00:01', end_time='3000-12-31 23:59:59', max_members=10)
def get(self): duplicate_id = self.get_argument("duplicate_id", None) if duplicate_id: activity = Activity.get_or_none(id=duplicate_id) activity.id = None else: activity = Activity( team=self.current_team, contact_person=self.current_team.contact_person, contact_phone=self.current_team.contact_phone, province=self.current_team.province, city=self.current_team.city, address=self.current_team.address ) form = CreateActivityFrom(obj=activity, team=self.current_team) self.render("activity/new.html", form=form, cities=ChinaCity.get_cities())
def create_free_activity(self, payment_type): """ 创建不同支付类型的免费活动 """ activity = Activity.create(team=self.team, creator=self.creator, price='0', vip_price='0', leader=self.creator, payment_type=payment_type, title='no online pay', description='on need online pay', start_time='3000-01-01 00:00:01', end_time='3016-12-31 23:59:59', join_end="3016-12-30 22:59:59", max_members=100) return activity
def test_cash_pay(self): activity = Activity.create(team=self.team, creator=self.creator, price='10', vip_price='8', leader=self.creator, payment_type=Activity.PaymentType.CASH_PAY, title='no online pay', description='on need online pay', start_time='3000-01-01 00:00:01', end_time='3000-12-31 23:59:59', join_end="4000-01-01 22:59:59", max_members=10) url = self.JOIN_ACTIVITY.format(activity_id=activity.id) body = { "payment": TeamOrder.OrderPaymentMethod.WXPAY.value, "nickname": "Nick name" } self.auth_user = User.create(name='no need online pay') response = self.fetch(url, method='POST', body=json.dumps(body), params={'team_id': self.team.id}) result = json.loads(response.body.decode()) expect = { "status": "ok", "state": ActivityMember.ActivityMemberState.confirmed.value, "payment_state": TeamOrder.OrderState.WAIT_BUYER_PAY.value, "order_no": "" } self.assertDictEqual(expect, result, result) self.assertEqual(200, response.code, response.body) with self.assertRaises(TeamOrder.DoesNotExist): TeamOrder.get( user=self.auth_user, activity_id=activity.id, ) member = ActivityMember.get(activity=activity, user=self.auth_user) # 现在支付, 直接确认 self.assertEqual(ActivityMember.ActivityMemberState.confirmed.value, member.state, member.state)
def get(self): """获取活动列表""" keyword = self.get_argument("kw", "") state = intval(self.get_argument("state", -1)) sort = intval(self.get_argument("sort", 0)) query = Activity.select( Activity, Team, ).join(Team, on=(Team.id == Activity.team).alias("team")) is_restrict_by_areas = self.current_user.is_restrict_by_areas() if is_restrict_by_areas: query = query.join(User, on=(User.id == Team.owner_id)).where( User.province << self.current_user.valid_manage_provinces) if state == 0: query = query.where( Activity.state == Activity.ActivityState.cancelled) elif state == 1: query = query.where( Activity.state == Activity.ActivityState.opening) elif state == 2: query = query.where( Activity.state == Activity.ActivityState.finished) if keyword: query = query.where(Activity.title.contains(keyword)) if sort == 2: query = query.order_by(Activity.start_time.desc()) else: query = query.order_by(Activity.id.desc()) activities = self.paginate_query(query) self.render( "activity/list.html", activities=activities, )
def post(self, activity_id): activity = Activity.get_or_404(id=activity_id) form = CreateActivityFrom(self.arguments, team=self.current_team) if form.validate(): form.populate_obj(activity) need_fields = self.get_arguments("need_fields") for field in need_fields: setattr(activity, field, True) geocode = yield self.get_geocode(activity.city, activity.address) if geocode.get("geocodes", []): location = geocode['geocodes'][0]['location'].split(",") activity.lat = location[1] activity.lng = location[0] activity.geohash = geohash.encode(float(location[1]), float(location[0])) if activity.repeat_type == "week": activity.week_day = activity.start_time.weekday() + 1 elif activity.repeat_type == "month": activity.month_day = activity.start_time.day activity.updated = datetime.now() activity.save() self.redirect(self.reverse_url("club_activity_list")) return province = self.get_argument("province", None) if province: form.city.choices = ChinaCity.get_cities(province) self.render("activity/new.html", form=form, cities=ChinaCity.get_cities())
def get(self, activity_id): activity = Activity.get_or_404(id=activity_id) members = ActivityMember.select( ActivityMember, TeamOrder, User ).join( User, on=(ActivityMember.user == User.id).alias("user") ).switch( ActivityMember ).join( TeamOrder, join_type=JOIN_LEFT_OUTER, on=(TeamOrder.id == ActivityMember.order_id).alias("order") ).where( ActivityMember.activity == activity ) activity.total_amount = ActivityMember.select( fn.SUM(ActivityMember.total_fee) ).where( ActivityMember.payment_state << (TeamOrder.OrderState.TRADE_BUYER_PAID, TeamOrder.OrderState.TRADE_FINISHED), ActivityMember.activity == activity ).scalar() or 0 members = self.paginate_query(members) activity.members_count = ActivityMember.select( fn.SUM(ActivityMember.users_count) ).where( ActivityMember.state == ActivityMember.ActivityMemberState.confirmed, ActivityMember.activity == activity ).scalar() or 0 self.render("activity/members.html", activity=activity, members=members)
def get(self, user_id): """ 按批次返回参加的活动 """ query = Activity.select(Activity, ActivityMember, TeamOrder)\ .join(ActivityMember, on=(ActivityMember.activity == Activity.id) .alias('activity_member')) \ .switch(Activity)\ .join( TeamOrder, join_type=JOIN_LEFT_OUTER, on=(TeamOrder.id == ActivityMember.order_id).alias("order") ) \ .where(ActivityMember.user == user_id) query = self.filter_query(query) page = self.paginate_query(query=query) data = self.get_paginated_data(page=page, alias='activities', serializer=MyActivitiesSerializer) self.write(data)