Пример #1
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)
    def test_online_pay_activity(self):
        url = self.JOIN_ACTIVITY.format(activity_id=self.activity.id)
        body = {"payment": "wxpay", "nickname": "Nick name"}
        self.auth_user = User.create(name='join activity')
        response = self.fetch(url,
                              method='POST',
                              body=json.dumps(body),
                              params={'team_id': self.team.id})
        self.assertEqual(200, response.code, response.body)

        order = TeamOrder.get_or_none(user=self.auth_user,
                                      activity_id=self.activity.id)
        self.assertIsNotNone(order, "加入活动时订单 `TeamOrder` 未创建")

        result = json.loads(response.body.decode())
        expect = {
            "status": "ok",
            "state": ActivityMember.ActivityMemberState.wait_confirm.value,
            "payment_state": TeamOrder.OrderState.WAIT_BUYER_PAY.value,
            "order_no": order.order_no
        }
        self.assertDictEqual(expect, result, result)

        member = ActivityMember.get_or_none(activity=self.activity,
                                            user=self.auth_user)
        self.assertIsNotNone(member, "加入活动后 `ActivityMember` 未添加记录")
Пример #3
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)
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()
Пример #5
0
    def joined_this_activity(self, activity_id, user_id):
        """用户是否参加了对应活动"""
        try:
            member = ActivityMember.get(activity=activity_id,
                                        user=user_id)
        except ActivityMember.DoesNotExist:
            raise ApiException(400, "未参加该活动")

        return member
 def test_patch_activity_profile(self):
     url = self.ACTIVITY_PROFILE.format(user_id=self.user.id,
                                        activity_id=self.activity.id)
     body = {"nickname": "new nick"}
     self.auth_user = self.user
     response = self.fetch(url, method="PATCH", body=json.dumps(body))
     self.assertEqual(204, response.code, response.body)
     updated = ActivityMember.get(activity=self.activity.id, user=self.user)
     self.assertEqual("new nick", updated.nickname)
    def test_activity_member_detail(self):
        member = ActivityMember.get(activity=self.activity, user=self.user)
        url = self.MEMBER_DETAIL.format(activity_id=self.activity.id,
                                        member_id=member.id)
        self.auth_user = self.creator
        response = self.fetch(url)
        self.assertEqual(200, response.code, response.body.decode())

        self.auth_user = User.create(name="permission deny")
        response = self.fetch(url)
        self.assertEqual(403, response.code, response.body.decode())
Пример #8
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)
    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)
Пример #10
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',
                                     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()
Пример #11
0
    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)
Пример #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',
                                        need_nickname=True,
                                        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="my activities")
Пример #13
0
    def get(self):
        orders = ActivityMember.select(
            ActivityMember,
            TeamOrder,
            User
        ).join(
            TeamOrder, on=(TeamOrder.id == ActivityMember.order_id).alias("order")
        ).switch(
            ActivityMember
        ).join(
            User, on=(ActivityMember.user == User.id).alias("user")
        ).where(
            TeamOrder.team == self.current_team,
            TeamOrder.refund_state > TeamOrder.OrderRefundState.NO_REFUND
        ).order_by(
            TeamOrder.refunded_time.desc()
        )

        orders = self.paginate_query(orders)

        self.render("activity/refunded_orders.html",
                    orders=orders
                    )
Пример #14
0
    def test_cash_free_activity(self):
        """
        参加免费活动不需要支付
        线下支付活动的 ActivityMember.state 应该为 `确认` confirmed
        """

        activity = self.create_free_activity(
            payment_type=Activity.PaymentType.CASH_PAY.value)

        url = self.JOIN_ACTIVITY.format(activity_id=activity.id)
        body = {
            "payment": TeamOrder.OrderPaymentMethod.WXPAY.value,
            "nickname": "Nick name"
        }

        self.auth_user = User.create(name='free activity')
        response = self.fetch(url,
                              method='POST',
                              body=json.dumps(body),
                              params={'team_id': self.team.id})
        self.assertEqual(200, response.code, response.body)
        result = json.loads(response.body.decode())
        expect = {
            "status": "ok",
            "state": ActivityMember.ActivityMemberState.confirmed.value,
            "payment_state": TeamOrder.OrderState.TRADE_BUYER_PAID.value,
            "order_no": ""
        }
        self.assertDictEqual(expect, result, result)

        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)
Пример #15
0
    def initial_data(self):
        self.leader = User.create(name="imleader")
        self.team = Team.create(name="test_finish_activity",
                                owner_id=self.leader.id)
        self.activity = Activity.create(
            team=self.team,
            creator=self.leader,
            leader=self.leader,
            title="test_finish_activity",
            description="test_stoped_activity",
            price=Decimal(15),
            max_members=30,
            start_time=datetime.datetime.now() - datetime.timedelta(hours=2),
            end_time=datetime.datetime.now() - datetime.timedelta(hours=1),
            payment_type=0,
            repeat_type="weekly",
            state=Activity.ActivityState.opening)

        self.online_paid_amount = 0

        for i in range(0, 5):
            user = User.create(name="test_%s" % i)
            order = TeamOrder.create(
                team=self.team,
                user=user,
                order_type=0,
                activity_id=self.activity.id,
                title="test_finish",
                order_no=TeamOrder.get_new_order_no(),
                credit_fee=0,
                total_fee=self.activity.price,
                payment_fee=self.activity.price,
                payment_method="wxpay",
                state=TeamOrder.OrderState.TRADE_BUYER_PAID,
                paid=self.activity.start_time,
                created=self.activity.start_time,
                finished=self.activity.start_time)
            ActivityMember.create(
                team=self.team,
                activity=self.activity,
                user=user,
                price=self.activity.price,
                users_count=1,
                total_fee=self.activity.price,
                payment_state=order.state,
                payment_method="wxpay",
                order_id=order.id,
                order_no=order.order_no,
                state=ActivityMember.ActivityMemberState.confirmed,
                free_times=0,
            )

            self.online_paid_amount += self.activity.price

        for i in range(0, 3):
            user = User.create(name="test2_%s" % i)
            order = TeamOrder.create(team=self.team,
                                     user=user,
                                     order_type=0,
                                     activity_id=self.activity.id,
                                     title="test_finish",
                                     order_no=TeamOrder.get_new_order_no(),
                                     credit_fee=0,
                                     total_fee=self.activity.price,
                                     payment_fee=self.activity.price,
                                     payment_method="wxpay",
                                     state=TeamOrder.OrderState.WAIT_BUYER_PAY,
                                     created=self.activity.start_time,
                                     finished=self.activity.start_time)
            ActivityMember.create(
                team=self.team,
                activity=self.activity,
                user=user,
                price=self.activity.price,
                users_count=1,
                total_fee=self.activity.price,
                payment_state=order.state,
                payment_method="wxpay",
                order_id=order.id,
                order_no=order.order_no,
                state=ActivityMember.ActivityMemberState.wait_confirm,
                free_times=0,
            )
Пример #16
0
def finish_activity(activity_id):
    """结算活动场次

        1. 将用户在线支付费用转到俱乐部账户
        2. 标记场次和订单状态为完成
        3. 记录俱乐部账户变化
    """

    activity = Activity.get_or_404(id=activity_id)

    if activity.end_time > datetime.now():
        raise Exception("活动场次未结束")

    if activity.state == Activity.ActivityState.cancelled:
        raise Exception("活动场次已取消")

    if activity.state == Activity.ActivityState.finished:
        raise Exception("活动场次已结算")

    # 计算在线支付完成交易的总额
    online_paid_amount = TeamOrder.select(fn.SUM(TeamOrder.payment_fee)).where(
        TeamOrder.activity_id == activity_id,
        TeamOrder.state >= TeamOrder.OrderState.TRADE_BUYER_PAID.value,
        TeamOrder.refund_state == TeamOrder.OrderRefundState.NO_REFUND,
        TeamOrder.payment_method <<
        TeamOrder.ONLINE_PAYMENT_METHODS).scalar() or 0

    # 计算余额支付完成交易的总额
    credit_paid_amount = TeamOrder.select(fn.SUM(TeamOrder.credit_fee)).where(
        TeamOrder.activity_id == activity_id, TeamOrder.state >=
        TeamOrder.OrderState.TRADE_BUYER_PAID.value).scalar() or 0

    # 使用次数
    free_times_amount = ActivityMember.select(fn.SUM(
        ActivityMember.free_times)).where(
            ActivityMember.state ==
            ActivityMember.ActivityMemberState.confirmed).scalar() or 0

    # online_paid_amount= DecimalField(default=Decimal(0), verbose_name="在线支付收入")
    # credit_paid_amount= DecimalField(default=Decimal(0), verbose_name="余额支付收入")
    # cash_paid_amount= DecimalField(default=Decimal(0), verbose_name="现金支付收入")
    # free_times_amount = IntegerField(default=0, verbose_name="次卡支付数量")

    with app.db.transaction() as txn:
        team = Team.select().where(
            Team.id == activity.team.id).for_update().get()

        # 将收入打到俱乐部账上
        Team.update(
            credit=Team.credit + online_paid_amount,
            total_receipts=Team.total_receipts + online_paid_amount,
            updated=datetime.now()).where(Team.id == team.id).execute()

        # 将订单修改状态为已完成
        TeamOrder.update(
            state=TeamOrder.OrderState.TRADE_FINISHED.value,
            finished=datetime.now()).where(
                TeamOrder.activity_id == activity_id,
                TeamOrder.state == TeamOrder.OrderState.TRADE_BUYER_PAID.value,
                TeamOrder.refund_state ==
                TeamOrder.OrderRefundState.NO_REFUND.value).execute()

        # 修改场次状态为已结算
        Activity.update(state=Activity.ActivityState.finished,
                        finished=datetime.now(),
                        online_paid_amount=online_paid_amount,
                        credit_paid_amount=credit_paid_amount,
                        free_times_amount=free_times_amount).where(
                            Activity.id == activity_id).execute()

        # 记录俱乐部账户变更
        TeamAccountLog.create(team_id=team.id,
                              credit_change=online_paid_amount,
                              change_type=0,
                              credit_before=team.credit,
                              credit_after=team.credit + online_paid_amount,
                              note="活动结算:%s(%s)" %
                              (activity.title, activity.start_time),
                              activity_id=activity_id,
                              operator_id=0)

    # 生成下期活动
    gen_next_activity(activity_id)