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()
Esempio n. 2
0
    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()
Esempio n. 5
0
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]')
Esempio n. 6
0
    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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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)
Esempio n. 11
0
    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)
Esempio n. 12
0
    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)
Esempio n. 13
0
    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)
Esempio n. 17
0
    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)
Esempio n. 18
0
 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')
Esempio n. 19
0
 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)
Esempio n. 20
0
    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)
Esempio n. 21
0
    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)
Esempio n. 30
0
    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)