示例#1
0
def token_check(req: Request, permission_limit: str = None):
    try:
        token = req.META['HTTP_AUTH_TOKEN']
        token_json = authentication.parse_token(token)
        user_id = token_json['user_id']
    except Exception:
        raise CheckException(status=status.HTTP_401_UNAUTHORIZED,
                             result_code=status.HTTP_401_UNAUTHORIZED,
                             message=_('Invalid token'))
    cache_token = cache.get(CACHE_KEY_MOBILE_CLEANING_TOKEN_PREFIX +
                            str(user_id))
    if token != cache_token or token_json[
            'mobile_type'] != MOBILE_CLIENT_TYPE_CLEANING:
        raise CheckException(status=status.HTTP_401_UNAUTHORIZED,
                             result_code=status.HTTP_401_UNAUTHORIZED,
                             message=_('Invalid token'))
    cache.set(CACHE_KEY_MOBILE_CLEANING_TOKEN_PREFIX + str(user_id),
              cache_token, MOBILE_TOKEN_VALID_HOURS * 3600)
    if permission_limit is not None:
        user = CleaningAccount.objects.filter(user_id=user_id).get()
        if user.account_type != permission_limit:
            raise CheckException(status=status.HTTP_403_FORBIDDEN,
                                 result_code=status.HTTP_403_FORBIDDEN,
                                 message=_('Permission denied'))
    else:
        user = CleaningAccount(user_id=user_id)
    return user
示例#2
0
def register(request: Request):
    if len(request.data['password']) < 6 or len(request.data['password']) > 20:
        raise CheckException(
            result_code=result_code.MR_ILLEGAL_PASSWORD_LENGTH,
            message=_('Password is too short or too long'))
    try:
        email = request.data['email']
        validate_email(email)
    except ValidationError:
        raise CheckException(result_code=result_code.MR_ILLEGAL_EMAIL_ADDR,
                             message=_('Illegal email address'))
    account_type = request.data['account_type']
    if account_type != models.RECYCLE_ACCOUNT_NORMAL_USER and \
       account_type != models.RECYCLE_ACCOUNT_GARBAGE_COLLECTOR:
        raise CheckException(result_code=result_code.MR_ILLEGAL_ACCOUNT_TYPE,
                             message=_('Illegal account type'))
    if RecycleAccount.objects.filter(user_name=request.data['user_name']):
        raise CheckException(result_code=result_code.MR_USER_NAME_USED,
                             message=_('User name has been used'))
    new_user = RecycleAccount(user_name=request.data['user_name'],
                              password=request.data['password'],
                              account_type=account_type,
                              email=email,
                              credit=0)
    new_user.save()
    return login_response(user=new_user, message=_('Sign up successfully'))
示例#3
0
def bulletin(req: Request, group_id: str, limit_num: str, start_time: str = None, end_time: str = None):
    user = account.token_check(req)
    if not check_utils.check_group_member(user_id=user.user_id, group_id=int(group_id)):
        raise CheckException(result_code=result_code.MC_USER_NOT_GROUP_MEMBER,
                             message=_('User does not belong to this group'))
    bulletins = []
    for b in CleaningGroupBulletin.objects.filter(
            view_utils.general_query_time_limit(start_time=start_time, end_time=end_time, group_id=int(group_id)))[:int(limit_num)]:
        bulletins.append(view_utils.get_bulletin_dict(b))
    if len(bulletins) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND, result_code=result_code.MC_GROUP_BULLETIN_NOT_FOUND,
                             message=_('Bulletin not found'))
    return view_utils.get_json_response(bulletin_list=bulletins)
示例#4
0
def login(request: Request):
    try:
        account = RecycleAccount.objects.filter(
            user_name=request.data['user_name']).get()
    except (ValueError, RecycleAccount.DoesNotExist):
        raise CheckException(result_code=result_code.MR_LOGIN_USER_NOT_EXIST,
                             message=_('User does not exist'),
                             status=status.HTTP_401_UNAUTHORIZED)

    if not account.password == request.data['password']:
        raise CheckException(
            result_code=result_code.MR_LOGIN_INCORRECT_PASSWORD,
            message=_('Incorrect password'),
            status=status.HTTP_401_UNAUTHORIZED)
    return login_response(user=account, message=_('Login successfully'))
def get_orders(req: Request, order_status: str = None, start_time: str = None, end_time: str = None,
               limit_num: str = None):
    if order_status is not None and order_status != 'in_progress' and order_status != 'delivering' \
            and order_status != 'cancelled' and order_status != 'finished':
        raise NotFound()
    if order_status == 'in_progress':
        order_status = models.ORDER_IN_PROGRESS
    elif order_status == 'delivering':
        order_status = models.ORDER_DELIVERING
    elif order_status == 'cancelled':
        order_status = models.ORDER_CANCELLED
    elif order_status == 'finished':
        order_status = models.ORDER_FINISHED

    user = token_check(req=req)
    order_list = []
    for e in models.Order.objects.filter(buyer=user).filter(
            view_utils.general_query_time_limit(end_time=end_time, start_time=start_time, status=order_status))[
             :int(limit_num)]:
        order = view_utils.get_model_dict(e, excluded_fields=['buyer', 'delivery_address', 'delivery'])
        if e.delivery_address:
            order['delivery_address'] = json.loads(e.delivery_address)
        if e.delivery:
            order['delivery'] = json.loads(e.delivery)
        order_list.append(order)
    if len(order_list) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND,
                             result_code=result_code.MR_ORDER_NOT_FOUND,
                             message=_('Order not found'))
    return view_utils.get_json_response(order_list=order_list)
示例#6
0
def check_login(req: Request, user_id: str):
    user = token_check(req=req)
    if str(user.user_id) != user_id:
        raise CheckException(status=status.HTTP_401_UNAUTHORIZED,
                             result_code=status.HTTP_401_UNAUTHORIZED,
                             message=_('Token does not match this user.'))
    return view_utils.get_json_response()
示例#7
0
def get_user_info_by_id(req: Request, user_id: str):
    user = token_check(req=req)
    try:
        user = CleaningAccount.objects.filter(user_id=int(user_id)).get()
        return view_utils.get_json_response(
            user=view_utils.get_cleaning_user_info_dict(user=user))
    except CleaningAccount.DoesNotExist:
        raise CheckException(result_code=result_code.MC_USER_INFO_NOT_FOUND,
                             message=_('User does not exist'),
                             status=status.HTTP_404_NOT_FOUND)
示例#8
0
def post_bulletin(req: Request):
    user = account.token_check(req=req, permission_limit=CLEANING_ACCOUNT_TYPE_MANAGER)
    if not check_utils.check_group_member(user_id=user.user_id, group_id=int(req.data['group_id'])):
        raise CheckException(result_code=result_code.MC_USER_NOT_GROUP_MEMBER,
                             message=_('User does not belong to this group'))
    new_bulletin = CleaningGroupBulletin(group_id=int(req.data['group_id']),
                                         poster=user, title=str(req.data['title']),
                                         text=str(req.data['text_content']))
    new_bulletin.save()
    return view_utils.get_json_response(status=status.HTTP_201_CREATED,
                                        message='Post new bulletin successfully')
示例#9
0
def get_recycle_record(req: Request, limit_num: str, start_time: str=None, end_time: str=None):
    user = account.token_check(req=req, permission_limit=models.RECYCLE_ACCOUNT_GARBAGE_COLLECTOR)
    result_list = []
    for r in models.RecycleCleaningRecord.objects.filter(view_utils.general_query_time_limit(start_time=start_time,
                                                                                             end_time=end_time,
                                                                                             user=user))[:int(limit_num)]:
        result_list.append(view_utils.get_model_dict(r, excluded_fields=['user']))
    if len(result_list) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND, result_code=result_code.MR_RECYCLE_RECORD_NOT_FOUND,
                             message=_('No record'))
    return view_utils.get_json_response(recycle_record_list=result_list)
示例#10
0
def get_delivery_addr(req: Request):
    user = token_check(req=req)
    user = RecycleAccount.objects.filter(user_id=user.user_id).get()
    if not user.delivery_address:
        raise CheckException(
            status=status.HTTP_404_NOT_FOUND,
            result_code=result_code.MR_DELIVER_ADDRESS_NOT_FOUND,
            message=_('Delivery address not found'))
    try:
        addr_list = json.loads(user.delivery_address)
        if not isinstance(addr_list, list) or len(addr_list) == 0:
            raise CheckException(
                status=status.HTTP_404_NOT_FOUND,
                result_code=result_code.MR_DELIVER_ADDRESS_NOT_FOUND,
                message=_('Delivery address not found'))
        return view_utils.get_json_response(address_list=addr_list)
    except json.JSONDecodeError:
        raise CheckException(
            status=status.HTTP_404_NOT_FOUND,
            result_code=result_code.MR_DELIVER_ADDRESS_NOT_FOUND,
            message=_('Delivery address not found'))
示例#11
0
def post_recycle_record(req: Request):
    user = account.token_check(req=req, permission_limit=models.RECYCLE_ACCOUNT_GARBAGE_COLLECTOR)
    try:
        recycle_point = models.RecyclePoint.objects.filter(point_id=req.data['recycle_point_id']).get()
    except models.RecyclePoint.DoesNotExist:
        raise CheckException(status=status.HTTP_404_NOT_FOUND, result_code=result_code.MR_RECYCLE_RECORD_RECYCLE_POINT_NOT_FOUND,
                             message=_('Recycle point not found'))
    if recycle_point.owner_id != user.user_id:
        raise CheckException(result_code=result_code.MR_RECYCLE_POINT_NOT_MANAGED,
                             message=_('The recycle point does not be managed by you'))
    if recycle_point.bottle_num is not None and recycle_point.bottle_num == 0:
        raise CheckException(result_code=result_code.MR_RECYCLE_POINT_EMPTY,
                             message=_('The recycle point is empty'))
    new_record = models.RecycleCleaningRecord(user=user, recycle_point=recycle_point,
                                              bottle_num=recycle_point.bottle_num)
    new_record.save()
    if recycle_point.bottle_num is not None:
        recycle_point.bottle_num = 0
    recycle_point.save()
    return view_utils.get_json_response(status=status.HTTP_201_CREATED,
                                        message=_('Post recycle record successfully'))
def get_commodities(req: Request, keyword: str = None, start_time: str = None, end_time: str = None,
                    limit_num: str = None):
    commodity_list = []
    for e in models.Commodity.objects.filter(
            view_utils.general_query_time_limit(end_time=end_time, start_time=start_time, title__icontains=keyword))[
             :int(limit_num)]:
        commodity_list.append(
            view_utils.get_model_dict(e, excluded_fields=['description', 'stock', 'quantity_limit', 'type']))
    if len(commodity_list) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND,
                             result_code=result_code.MR_COMMODITY_NOT_FOUND,
                             message=_('Commodity not found'))
    return view_utils.get_json_response(commodity_list=commodity_list)
示例#13
0
def all_groups(req: Request):
    user = account.token_check(req)
    groups = []
    try:
        groups.append(view_utils.get_group_dict(CleaningGroup.objects.filter(group_id=SPECIAL_WORK_GROUP_ID).get()))
    except CleaningGroup.DoesNotExist:
        pass
    for gm in CleaningGroupMembership.objects.filter(user=user):
        groups.append(view_utils.get_group_dict(gm.group))
    if len(groups) == 0:
        raise CheckException(result_code=result_code.MC_GROUP_NOT_FOUND,
                             status=status.HTTP_404_NOT_FOUND,
                             message=_('Group not found'))
    return view_utils.get_json_response(group_list=groups)
示例#14
0
def get_events(req: Request,
               start_time: str = None,
               end_time: str = None,
               limit_num: str = None):
    event_list = []
    for e in models.Event.objects.filter(
            view_utils.general_query_time_limit(
                end_time=end_time, start_time=start_time))[:int(limit_num)]:
        event_list.append(view_utils.get_model_dict(e))
    if len(event_list) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND,
                             result_code=result_code.MR_EVENT_NOT_FOUND,
                             message=_('Event not found'))
    return view_utils.get_json_response(event_list=event_list)
示例#15
0
def get_feedback(req: Request,
                 limit_num: str,
                 start_time: str = None,
                 end_time: str = None):
    feedback_list = []
    for fb in models.Feedback.objects.filter(
            view_utils.general_query_time_limit(
                end_time=end_time, start_time=start_time))[:int(limit_num)]:
        feedback_list.append(view_utils.get_feedback_dict(fb))
    if len(feedback_list) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND,
                             result_code=result_code.MP_FEEDBACK_NOT_FOUND,
                             message=_('No feedback'))
    return view_utils.get_json_response(feedback_list=feedback_list)
示例#16
0
def login(request: Request):
    try:
        account = CleaningAccount.objects.filter(
            user_id=int(request.data['user_id'])).get()
    except (ValueError, CleaningAccount.DoesNotExist):
        raise CheckException(result_code=result_code.MC_LOGIN_USER_NOT_EXIST,
                             message=_('User does not exist'),
                             status=status.HTTP_401_UNAUTHORIZED)

    if not account.password == request.data['password']:
        raise CheckException(
            result_code=result_code.MC_LOGIN_INCORRECT_PASSWORD,
            message=_('Incorrect password'),
            status=status.HTTP_401_UNAUTHORIZED)
    token_str = authentication.generate_token(
        user_id=account.user_id, mobile_type=MOBILE_CLIENT_TYPE_CLEANING)
    cache.set(CACHE_KEY_MOBILE_CLEANING_TOKEN_PREFIX + str(account.user_id),
              token_str, MOBILE_TOKEN_VALID_HOURS * 3600)
    res = view_utils.get_json_response(result_code=result_code.SUCCESS,
                                       message=_('Login successfully'),
                                       status=status.HTTP_201_CREATED,
                                       token=token_str)
    return res
def post_work_record(req: Request):
    user = account.token_check(req=req, permission_limit=CLEANING_ACCOUNT_TYPE_CLEANER)
    try:
        trash = Trash.objects.filter(trash_id=int(req.data['trash_id'])).get()
    except Trash.DoesNotExist:
        raise CheckException(status=status.HTTP_404_NOT_FOUND, result_code=result_code.MC_TRASH_NOT_FOUND,
                             message=_('Trash not found'))
    user_longitude = float(req.data['longitude'])
    user_latitude = float(req.data['latitude'])
    if not check_utils.check_location(longitude=user_longitude, latitude=user_latitude):
        raise CheckException(result_code=result_code.MC_ILLEGAL_LOCATION,
                             message=_('Illegal location'))
    if not check_utils.check_distance(p1_longitude=user_longitude, p1_latitude=user_latitude,
                                      p2_longitude=trash.longitude, p2_latitude=trash.latitude,
                                      distance_limit=50.0):
        raise CheckException(result_code=result_code.MC_TOO_FAR_AWAY_FROM_TRASH,
                             message=_('Too far away from specific trash'))
    new_record = CleaningWorkRecord(user=user, trash=trash)
    new_record.save()
    mqtt_broker_utils.publish_message(full_topic=settings.MQTT_TOPIC_LATEST_WORK_RECORD,
                                      message=json.dumps(view_utils.get_work_record_dict(new_record)))
    scheduler_utils.add_cleaning_reminder(trash_id=trash.trash_id)
    return view_utils.get_json_response(status=status.HTTP_201_CREATED,
                                        message=_('Post new work record successfully'))
def get_work_record(req: Request, limit_num: str, user_id: str = None, trash_id: str = None,
                    start_time: str = None, end_time: str = None):
    account.token_check(req)
    work_record_list = []
    q = CleaningWorkRecord.objects.filter(
        view_utils.general_query_time_limit(start_time=start_time, end_time=end_time))
    if user_id is not None:
        q.filter(user_id=int(user_id))
    if trash_id is not None:
        q.filter(trash_id=int(trash_id))
    for wr in q[:int(limit_num)]:
        work_record_list.append(view_utils.get_work_record_dict(wr))
    if len(work_record_list) == 0:
        raise CheckException(status=status.HTTP_404_NOT_FOUND, result_code=result_code.MC_WORK_RECORD_NOT_FOUND,
                             message=_('Work record not found'))
    return view_utils.get_json_response(work_record_list=work_record_list)
def get_commodity_detail(req: Request, commodity_id: str):
    commodity_id = int(commodity_id)
    try:
        commodity_images = []
        for ci in models.CommodityImage.objects.filter(commodity_id=commodity_id):
            commodity_images.append(view_utils.get_encoded_file(ci.image))

        e = models.Commodity.objects.get(commodity_id=commodity_id)
        commodity = view_utils.get_model_dict(e, excluded_fields=['thumbnail'],
                                              modify_fields=dict(commodity_type='type'))
        commodity['commodity_images'] = commodity_images
        return view_utils.get_json_response(commodity=commodity)
    except models.Commodity.DoesNotExist:
        raise CheckException(status=status.HTTP_404_NOT_FOUND,
                             result_code=result_code.MR_COMMODITY_NOT_FOUND,
                             message=_('Commodity not found'))
def get_credit_records(req: Request,
                       start_time: str = None,
                       end_time: str = None,
                       limit_num: str = None):
    user = account.token_check(req)
    credit_record_list = []
    for cr in models.RecycleCreditRecord.objects.filter(
            view_utils.general_query_time_limit(end_time=end_time,
                                                start_time=start_time,
                                                user=user))[:int(limit_num)]:
        credit_record_list.append(
            view_utils.get_model_dict(cr, excluded_fields=['user']))
    if len(credit_record_list) == 0:
        raise CheckException(
            status=status.HTTP_404_NOT_FOUND,
            result_code=result_code.MR_CREDIT_RECORD_NOT_FOUND,
            message=_('Credit record not found'))
    return view_utils.get_json_response(credit_record_list=credit_record_list)
示例#21
0
def set_new_delivery_addr(req: Request):
    user = token_check(req=req)
    user = RecycleAccount.objects.filter(user_id=user.user_id).get()
    data_addr_list = req.data['new_addr_list']
    if not isinstance(data_addr_list, list):
        raise ParseError()
    for addr in data_addr_list:
        if not isinstance(addr, dict):
            raise ParseError()
        if not 'name' in addr or not 'phone_number' in addr or not 'address' in addr:
            raise ParseError()
        if not str(addr['phone_number']).isdigit():
            raise CheckException(result_code=result_code.MR_ILLEGAL_PHONE,
                                 message=_('Illegal phone number'))
    user.delivery_address = json.dumps(data_addr_list)
    user.save()
    return view_utils.get_json_response(
        status=status.HTTP_201_CREATED,
        message=_('Save new delivery address successfully'))
def new_order(req: Request):
    global lock_dict_lock
    global commodity_lock_dict
    user = token_check(req=req)
    user = models.RecycleAccount.objects.filter(user_id=user.user_id).get()
    order = models.Order(buyer=user)
    order.quantity = int(req.data['quantity'])
    if order.quantity <= 0:
        raise CheckException(result_code=result_code.MR_ILLEGAL_QUANTITY,
                             message=_('Illegal quantity(<=0)'))

    try:
        commodity_id = int(req.data['commodity_id'])
        commodity = models.Commodity.objects.get(commodity_id=commodity_id)
    except models.Commodity.DoesNotExist:
        raise CheckException(status=status.HTTP_404_NOT_FOUND,
                             result_code=result_code.MR_COMMODITY_NOT_FOUND,
                             message=_('Commodity not found'))

    lock_dict_lock.acquire()
    if str(commodity_id) not in commodity_lock_dict:
        commodity_lock_dict.update({str(commodity_id): threading.Lock()})
    commodity_lock = commodity_lock_dict[str(commodity_id)]
    lock_dict_lock.release()

    commodity_lock.acquire()
    try:
        if commodity.commodity_type == models.COMMODITY_TYPE_PHYSICAL:
            if 'delivery_address' not in req.data:
                raise ParseError()
            addr = req.data['delivery_address']
            if not 'name' in addr or not 'phone_number' in addr or not 'address' in addr:
                raise ParseError()
            if not str(addr['phone_number']).isdigit():
                raise CheckException(result_code=result_code.MR_ILLEGAL_PHONE, message=_('Illegal phone number'))
            order.delivery_address = to_json(addr)

        if order.quantity > commodity.stock:
            raise CheckException(status=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                 result_code=result_code.MR_INSUFFICIENT_STOCK,
                                 message=_('Insufficient stock'))
        if order.quantity > commodity.quantity_limit:
            raise CheckException(status=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                 result_code=result_code.MR_QUANTITY_EXCEEDS_LIMIT,
                                 message=_('Quantity exceeds limit'))
        if commodity.credit * order.quantity > user.credit:
            raise CheckException(status=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                 result_code=result_code.MR_INSUFFICIENT_CREDIT,
                                 message=_('Insufficient credit'))

        commodity.stock -= order.quantity
        commodity.save()

        order.order_id = timezone.datetime.now().strftime('CM%Y%m%d%H%M%S%f')
        order.credit = commodity.credit
        order.title = commodity.title
        order.commodity_id = commodity.commodity_id

        if 'remark' in req.data:
            order.remark = req.data['remark']

        order.save()
        new_credit_record = models.RecycleCreditRecord(user=user,
                                                       item_description='%s x%d' %
                                                                        (commodity.title, order.quantity),
                                                       credit=-(commodity.credit * order.quantity))
        new_credit_record.save()
        user.credit += new_credit_record.credit
        user.save()
    except Exception as e:
        raise e
    finally:
        commodity_lock.release()
    return view_utils.get_json_response(status=status.HTTP_201_CREATED, message=_('Submit order successfully'))
def recycle_bottle(req: Request):
    user = account.token_check(req)
    try:
        rp = models.RecyclePoint.objects.filter(
            point_id=int(req.data['recycle_point_id'])).get()
    except models.RecyclePoint.DoesNotExist:
        raise CheckException(
            status=status.HTTP_404_NOT_FOUND,
            result_code=result_code.MR_CREDIT_RECORD_RECYCLE_POINT_NOT_FOUND,
            message=_('Recycle point not found'))
    if rp.bottle_num is None:
        raise CheckException(
            result_code=result_code.MR_CREDIT_RECORD_RECYCLE_POINT_NOT_FOUND,
            message=_('This recycle point does not accept bottles'))
    user_longitude = float(req.data['longitude'])
    user_latitude = float(req.data['latitude'])
    if not check_utils.check_location(longitude=user_longitude,
                                      latitude=user_latitude):
        raise CheckException(result_code=result_code.MR_ILLEGAL_LOCATION,
                             message=_('Illegal location'))
    if not check_utils.check_distance(p1_longitude=user_longitude,
                                      p1_latitude=user_latitude,
                                      p2_longitude=rp.longitude,
                                      p2_latitude=rp.latitude,
                                      distance_limit=50.0):
        raise CheckException(
            result_code=result_code.MR_TOO_FAR_AWAY_FROM_RECYCLE_POINT,
            message=_('Too far away from specific recycle point'))
    quantity = int(req.data['quantity'])
    if quantity <= 0:
        quantity = 1
    elif quantity > settings.TN_RECYCLE_BOTTLE_MAX_QUANTITY:
        quantity = settings.TN_RECYCLE_BOTTLE_MAX_QUANTITY

    red_packet_credit = 0
    cache_red_packet = cache.get(
        '%s%d' % (recycle_point.CACHE_KEY_RED_PACKET_PREFIX, rp.point_id))
    max_red_packet_credit = recycle_point.check_red_packet_valid(
        cache_red_packet, rp.point_id)
    if max_red_packet_credit > 0:
        if max_red_packet_credit > quantity:
            max_red_packet_credit = quantity
        if random.random() < recycle_point.RED_PACKET_PROBABILITY:
            red_packet_credit = random.randint(1, max_red_packet_credit)
            cache_red_packet['total'] -= red_packet_credit
            cache.set(
                '%s%d' %
                (recycle_point.CACHE_KEY_RED_PACKET_PREFIX, rp.point_id),
                cache_red_packet, None)

    new_credit_record = models.RecycleCreditRecord(
        user=user,
        item_description='Recycled bottle x%d' % quantity,
        credit=quantity + red_packet_credit)
    new_credit_record.save()
    user = models.RecycleAccount.objects.filter(user_id=user.user_id).get()
    user.credit += new_credit_record.credit
    user.save()
    rp.bottle_num += quantity
    rp.save()
    return view_utils.get_json_response(
        status=status.HTTP_201_CREATED,
        message=_('Recycle bottle successfully'),
        credit=new_credit_record.credit,
        red_packet_credit=red_packet_credit)