def product_owner_reviews(request): try: user = User.objects.get(id=request.GET.get('owner_id')) except User.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) except ValueError: return CoastalJsonResponse(status=response.STATUS_404) reviews = Review.objects.filter(order__owner=user) review_avg_score = reviews.aggregate(Avg('score'), Count('id')) reviews_list = [] for review in reviews: review_info = { 'date': format_date(review.date_created), 'score': review.score, 'content': review.content } review_info.update(review.owner.basic_info(prefix='guest_')) reviews_list.append(review_info) result = { 'owner': user.basic_info(), 'review_count': review_avg_score['id__count'], 'reviews': reviews_list, } return CoastalJsonResponse(result)
def product_add(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) form = ProductAddForm(request.POST) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=response.STATUS_400) product = form.save(commit=False) product.owner = request.user if 'lon' and 'lat' in form.data: tf = TimezoneFinder() product.timezone = tf.timezone_at(lng=form.cleaned_data['lon'], lat=form.cleaned_data['lat']) product.distance_from_coastal = distance_from_coastline( form.cleaned_data['lon'], form.cleaned_data['lat']) or float('inf') product.save() pid = product.id black_out_date(pid, form) amenities = form.cleaned_data.get('amenities') for a in amenities: product.amenities.add(a) # TODO: remove the 'images' and remove images from ProductAddForm images = form.cleaned_data.get('images') for i in images: i.product = product i.save() data = {'product_id': product.id} return CoastalJsonResponse(data)
def update_profile(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) form = UserProfileForm(request.POST, request.FILES) if form.is_valid(): user = request.user if request.FILES: setattr(user.userprofile, 'photo', form.cleaned_data['photo']) for key in form.data: if key == 'name': name_list = form.cleaned_data['name'].split() if len(name_list) > 1: setattr(user, 'last_name', name_list.pop()) setattr(user, 'first_name', ' '.join(name_list)) else: if key in form.cleaned_data: setattr(user.userprofile, key, form.cleaned_data[key]) user.save() user.userprofile.save() data = { 'user_id': user.id, 'logged': request.user.is_authenticated(), 'has_agency_info': user.userprofile.has_agency_info, 'email': user.email, 'email_confirmed': user.userprofile.email_confirmed, 'name': user.get_full_name(), 'photo': user.basic_info()['photo'], 'purpose': user.userprofile.purpose, } return CoastalJsonResponse(data) return CoastalJsonResponse(form.errors, status=response.STATUS_400)
def validate_email(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) user = request.user validate = user.validateemail_set.order_by('created_date').first() if validate: timespan = timezone.now() - validate.created_date if timespan.total_seconds() < 300: data = { 'email_confirmed': validate.user.userprofile.email_confirmed } return CoastalJsonResponse(data) else: user.userprofile.email_confirmed = 'sending' user.userprofile.save() validate_instance = ValidateEmail() validate_instance.save(user=user) subject = 'Email Verification' message = '''Hi %s, To complete the process of publishing and transaction on Coastal, you must confirm your email address below: http://%s/account/confirm-email/?token=%s The link will be invalid 24 hours later. Please resend if this happens. Thanks, The Coastal Team ''' % (user.email, settings.SITE_DOMAIN, validate_instance.token) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email], connection=None, html_message=None) data = {'email_confirmed': user.userprofile.email_confirmed} return CoastalJsonResponse(data)
def sale_detail(request): if request.method != 'GET': return CoastalJsonResponse(status=response.STATUS_405) try: sale_offer = SaleOffer.objects.get(id=request.GET.get('sale_offer_id')) except SaleOffer.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) except ValueError: return CoastalJsonResponse(status=response.STATUS_404) result = { 'owner': sale_offer.owner.basic_info(), 'guest': sale_offer.guest.basic_info(), 'product': { 'id': sale_offer.product.id, 'name': sale_offer.product.name, 'for_rental': sale_offer.product.for_rental, 'for_sale': sale_offer.product.for_sale, }, 'sale_price': sale_offer.product.sale_price, 'sale_price_display': sale_offer.product.get_sale_price_display(), 'offer_price': sale_offer.price, 'offer_price_display': sale_offer.get_price_display(), 'conditions': sale_offer.get_condition_list(), 'status': sale_offer.get_status_display(), } result.update(sale_payment_info(sale_offer, sale_offer.guest)) return CoastalJsonResponse(result)
def register(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) register_form = RegistrationForm(request.POST) if not register_form.is_valid(): return CoastalJsonResponse(register_form.errors, status=response.STATUS_400) cleaned_data = register_form.cleaned_data user = create_user(cleaned_data['email'], cleaned_data['password']) logger.debug('Logging user is %s, User token is %s, User uuid is %s' % ( cleaned_data['email'], cleaned_data['token'], cleaned_data['uuid'], )) auth_login(request, user) if cleaned_data['uuid'] and cleaned_data['token']: bind_token(cleaned_data['uuid'], cleaned_data['token'], user) data = { 'user_id': user.id, 'logged': request.user.is_authenticated(), "has_agency_info": user.userprofile.has_agency_info, 'email': user.email, 'email_confirmed': user.userprofile.email_confirmed, 'name': user.get_full_name(), 'photo': user.basic_info()['photo'], } return CoastalJsonResponse(data)
def update_caption(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) product_image = ProductImage.objects.filter(id=request.POST.get('id')) if not product_image: return CoastalJsonResponse(message='image not exist') product_image.update(caption=request.POST.get('caption')) return CoastalJsonResponse()
def delete_image(request): if not request.POST.get('images'): return CoastalJsonResponse({'images': 'The field is required'}, status=response.STATUS_400) images = request.POST.get('images').split(',') for image in images: image = ProductImage.objects.filter(id=image) image.delete() return CoastalJsonResponse(message='OK')
def black_dates_for_rental(request): from datetime import timedelta product_id = request.GET.get('product_id') rental_unit = request.GET.get('rental_unit') try: product = Product.objects.get(id=product_id) except: return CoastalJsonResponse(status=response.STATUS_404, message="The product does not exist.") date_ranges = product.blackoutdate_set.all() data = [] for dr in date_ranges: data.append( [localtime(dr.start_date).date(), localtime(dr.end_date).date()]) date_ranges2 = RentalOutDate.objects.filter( product=product).order_by('start_date') if product.category_id == product_defs.CATEGORY_ADVENTURE: for dr in date_ranges2: start_date = localtime(dr.start_date) end_date = localtime(dr.end_date) if start_date.hour != 0: start_date = (start_date + timedelta(days=1)).replace(hour=0) if end_date.hour != 0: end_date = end_date.replace(hour=0) end_date -= timedelta(minutes=1) if start_date < end_date: data.append([start_date.date(), end_date.date()]) else: for dr in date_ranges2: start_date = localtime(dr.start_date) end_date = localtime(dr.end_date) if rental_unit == 'day': if product.category_id in (product_defs.CATEGORY_HOUSE, product_defs.CATEGORY_APARTMENT, product_defs.CATEGORY_ROOM): start_date = start_date - timedelta(hours=12) end_date = end_date - timedelta(hours=12) - timedelta( seconds=1) data.append([start_date.date(), end_date.date()]) else: end_date = end_date - timedelta(seconds=1) data.append([start_date.date(), end_date.date()]) else: if start_date.hour == 12: start_date += timedelta(hours=12) if end_date.hour == 12: end_date -= timedelta(hours=12) if start_date != end_date: end_date -= timedelta(seconds=1) data.append([start_date.date(), end_date.date()]) return CoastalJsonResponse(data)
def sent_message(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) form = HelpCenterForm(request.POST) if form.is_valid(): form.save() data = {'send': 'success'} else: data = {'send': 'failed'} return CoastalJsonResponse(data)
def check_email(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) form = CheckEmailForm(request.POST) if form.is_valid(): return CoastalJsonResponse({ 'exists': User.objects.filter( username=form.cleaned_data['email'].lower()).exists() }) return CoastalJsonResponse(form.errors, status=response.STATUS_400)
def delete_dialogue(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) dialogue = Dialogue.objects.filter( id=request.POST.get('dialogue_id')).first() if not dialogue: return CoastalJsonResponse(status=response.STATUS_404) dialogue.is_deleted = True dialogue.save() return CoastalJsonResponse()
def product_update(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) try: product = Product.objects.get(id=request.POST.get('product_id')) except Product.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) product_start_time = product.exp_start_time product_end_time = product.exp_end_time form = ProductUpdateForm(request.POST, instance=product) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=response.STATUS_400) black_out_date(request.POST.get('product_id'), form) if 'amenities' in form.cleaned_data: for a in form.cleaned_data.get('amenities'): product.amenities.add(a) if 'images' in form.cleaned_data: for i in form.cleaned_data.get('images'): i.product = product i.save() if 'lan' and 'lat' in form.cleaned_data: product.distance_from_coastal = distance_from_coastline( form.cleaned_data['lon'], form.cleaned_data['lat']) or float('inf') product.save() if form.cleaned_data.get('action') == 'cancel': product.status = 'cancelled' product.save() if form.cleaned_data.get('action') == 'publish': if product.validate_publish_data(): product.publish() product.active_product = timezone.now() product.save() else: return CoastalJsonResponse( {'action': 'There are invalid data for publish.'}, status=response.STATUS_400) exp_start_time = form.cleaned_data.get('exp_start_time') exp_end_time = form.cleaned_data.get('exp_end_time') if exp_start_time != product_start_time or exp_end_time != product_end_time: recreate_rental_out_date(product) return CoastalJsonResponse()
def facebook_login(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) form = FacebookLoginForm(request.POST) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=response.STATUS_400) logger.debug( 'Logging user is %s, User token is %s, User uuid is %s, User name is %s, User client is Facebook' % (form.cleaned_data['userid'], form.cleaned_data['token'], form.cleaned_data['uuid'], form.cleaned_data['name'])) user = User.objects.filter(username=form.cleaned_data['userid']).first() if user: is_first = not bool(user.last_login) auth_login(request, user) else: user = User.objects.create( username=form.cleaned_data['userid'], email=form.cleaned_data['email'], first_name=form.cleaned_data.get('first_name', ''), last_name=form.cleaned_data.get('last_name', '')) UserProfile.objects.create(user=user, email_confirmed='confirmed', client='facebook') CoastalBucket.objects.create(user=user) is_first = not bool(user.last_login) auth_login(request, user) if form.cleaned_data['token']: bind_token(form.cleaned_data['uuid'], form.cleaned_data['token'], user) if settings.DEBUG: try: publish_log_in(user) except (NoEndpoint, DisabledEndpoint): pass push_user_notifications.delay(user.id) data = { 'user_id': user.id, 'logged': user.is_authenticated(), "has_agency_info": user.userprofile.has_agency_info, 'email': user.email, 'email_confirmed': user.userprofile.email_confirmed, 'name': user.get_full_name(), 'photo': user.basic_info()['photo'], 'first_login': is_first, } return CoastalJsonResponse(data)
def stripe_add_card(request): """ Add credit card for stripe payment :param request: request.POST data {"token": "tok_19UiVAIwZ8ZTWo9bF8Z6L6Ua"} :return: """ try: add_card(request.user, request.POST.get('token')) except Exception: CoastalJsonResponse({"add_card": "failed"}) return CoastalJsonResponse({ "add_card": "success", "card_list": get_card_list(request.user) })
def delete_offer(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) try: sale_offer = SaleOffer.objects.get( id=request.POST.get('sale_offer_id')) except SaleOffer.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) except ValueError: return CoastalJsonResponse(status=response.STATUS_404) sale_offer.is_deleted = True sale_offer.save() return CoastalJsonResponse()
def images_360(request): images_view = ProductImage.objects.filter( image_type='360-view', product__status='published').order_by('-product__score')[0:90] image_list = [] for image_360 in images_view: image_info = { 'product_id': image_360.product_id, 'for_rental': image_360.product.for_rental, 'for_sale': image_360.product.for_sale, 'rental_price': image_360.product.rental_price, 'sale_price': image_360.product.sale_price, 'currency': image_360.product.currency, 'rental_unit': image_360.product.rental_unit, 'rental_unit_display': image_360.product.get_rental_unit_display(), 'image': image_360.image.url, 'name': image_360.product.name, 'rental_price_display': image_360.product.get_rental_price_display(), 'sale_price_display': image_360.product.get_sale_price_display(), } image_list.append(image_info) result = [] for i in image_list: if i['product_id'] not in [p['product_id'] for p in result]: result.append(i) return CoastalJsonResponse(result[0:30])
def my_order_dates(request): user = request.user now_year = timezone.now() now_year = timezone.datetime(now_year.year, now_year.month, 1, tzinfo=now_year.tzinfo) next_year = timezone.datetime(now_year.year + 1, now_year.month, 1, tzinfo=now_year.tzinfo) order_list = user.owner_orders.filter( Q(end_datetime__gte=now_year) & Q(start_datetime__lt=next_year)) date_list = [] for order in order_list: begin_time, end_time = order.start_datetime, order.end_datetime for every_day in rrule(DAILY, dtstart=begin_time, until=end_time): if every_day >= now_year and every_day < next_year: format_day = timezone.datetime( every_day.year, every_day.month, every_day.day).strftime("%Y-%m-%d") if format_day not in date_list: date_list.append(format_day) return CoastalJsonResponse(date_list)
def delete_order(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) try: rental_order = RentalOrder.objects.get( id=request.POST.get('rental_order_id')) except RentalOrder.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) except ValueError: return CoastalJsonResponse(status=response.STATUS_404) rental_order.is_deleted = True rental_order.save() return CoastalJsonResponse()
def logout(request): if request.user.is_authenticated(): logger.debug('Logout user is %s, unbind token is %s ' % (request.user, request.POST.get('token'))) unbind_token(request.POST.get('token'), request.user) auth_logout(request) return CoastalJsonResponse()
def update_ordering(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) order_list = request.POST.get('ordered_list').split(',') product = Product.objects.filter(id=request.POST.get('product_id')).first() if not product: return CoastalJsonResponse(message='product not exist') product_image = product.productimage_set.all() if len(order_list) != len(product_image): return CoastalJsonResponse( message='Incoming length inconsistencies and product images') for index in range(len(order_list)): ProductImage.objects.filter(id=order_list[index]).update( display_order=index) return CoastalJsonResponse()
def product_image_upload(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) data = request.POST.copy() if 'product_id' in data: data['product'] = data.get('product_id') form = ImageUploadForm(data, request.FILES) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=response.STATUS_400) image = form.save() data = { 'image_id': image.id, 'url': image.image.url, } return CoastalJsonResponse(data)
def payment_stripe(request): """ :param request: POST data {"sale_offer_id": 1, "card_id": "card_19UiVAIwZ8ZTWo9bYTC4hguE"} :return: json data {} """ CHARGED_STATUS_LIST = ('pay', 'finished') if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) try: sale_offer = SaleOffer.objects.get( guest=request.user, id=request.POST.get('sale_offer_id')) except SaleOffer.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) except ValueError: return CoastalJsonResponse(status=response.STATUS_404) if sale_offer.status in CHARGED_STATUS_LIST: return CoastalJsonResponse(status=response.STATUS_1500) if sale_offer.status != 'charge': return CoastalJsonResponse( {'order': 'The order status should be Unpaid'}, status=response.STATUS_405) card = request.POST.get('card_id') if not card: return CoastalJsonResponse({"card_id": "It is required."}, status=response.STATUS_400) success = stripe_charge(sale_offer, request.user, card) if success: owner = sale_offer.owner bucket = CoastalBucket.objects.get(user=owner) bucket.balance += sale_offer.price_usd bucket.save() Transaction.objects.create( bucket=bucket, type='in', order_number=sale_offer.number, amount=sale_offer.price_usd, ) sale_offer.status = 'finished' sale_offer.date_succeed = timezone.now() send_transaction_email(sale_offer.product_id, sale_offer.id, 'sale') sale_offer.save() reward_invite_referrer(request.user) try: publish_paid_owner_offer(sale_offer) except (NoEndpoint, DisabledEndpoint): pass return CoastalJsonResponse({ "payment": success and 'success' or 'failed', "status": sale_offer.get_status_display(), })
def dialogue_list(request): dialogues = Dialogue.objects.filter( Q(owner=request.user) | Q(guest=request.user)).order_by('-date_updated') dialogues = dialogues.annotate( num_all_messages=Count('message', distinct=True)).filter( num_all_messages__gt=0) unread_dialogues = dialogues.filter( message__receiver=request.user, message__read=False).annotate( num_messages=Count('message', distinct=True)) unread_dialogue_count_dict = { dialogue.id: dialogue.num_messages for dialogue in unread_dialogues } dialogues = dialogues[:100] dialogues_list = [] for dialogue in dialogues: contact = request.user == dialogue.owner and dialogue.guest or dialogue.owner product = dialogue.product order = dialogue.order unread_message_number = unread_dialogue_count_dict.get(dialogue.id, 0) contact_dict = { 'user_id': contact.id, 'name': contact.basic_info()['name'], 'photo': contact.basic_info()['photo'], } product_dict = { 'product_id': product.id, 'name': product.name, 'image': product.get_main_image(), 'for_rental': product.for_rental, 'for_sale': product.for_sale, 'currency': product.currency, } order_dict = {} if order: order_dict = { 'order_id': order.id, 'status': order.get_status_display(), 'start': order.start_datetime.strftime('%Y-%m-%d %H:%M:%S'), 'end': order.end_datetime.strftime('%Y-%m-%d %H:%M:%S'), } dialogue_dict = { 'dialogue_id': dialogue.id, 'contact': contact_dict, 'product': product_dict, 'order': order_dict, 'unread': unread_message_number, 'date_update': dialogue.date_updated.strftime('%Y-%m-%d %H:%M:%S') } dialogues_list.append(dialogue_dict) result = { 'dialogues': dialogues_list, } return CoastalJsonResponse(result)
def discount_calculator(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) form = DiscountCalculatorFrom(request.POST) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=response.STATUS_400) rental_price = form.cleaned_data['rental_price'] rental_unit = form.cleaned_data['rental_unit'] discount_weekly = form.cleaned_data.get('discount_weekly') discount_monthly = form.cleaned_data.get('discount_monthly') price = get_product_discount(rental_price, rental_unit, discount_weekly, discount_monthly) data = { 'weekly_price': format(price[0], ','), 'monthly_price': format(price[1], ','), } return CoastalJsonResponse(data)
def make_offer(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) data = request.POST.copy() if 'product_id' in data: data['product'] = data.get('product_id') if 'offer_price' in data: data['price'] = data.get('offer_price') form = SaleOfferForm(data) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=response.STATUS_400) product = form.cleaned_data.get('product') if product.status != 'published': return CoastalJsonResponse(form.errors, status=response.STATUS_1301) sale_offer = form.save(commit=False) sale_offer.status = 'request' sale_offer.owner = product.owner sale_offer.guest = request.user sale_offer.currency = product.currency sale_offer.currency_rate = get_exchange_rate(sale_offer.currency) sale_offer.price_usd = math.ceil(sale_offer.price / sale_offer.currency_rate) sale_offer.timezone = product.timezone sale_offer.save() sale_offer.number = 'SO%s' % (100000 + sale_offer.id) sale_offer.save() result = { "sale_offer_id": sale_offer.id, "status": sale_offer.get_status_display(), } expire_offer_request.apply_async( (sale_offer.id, ), countdown=api_defs.EXPIRATION_TIME * 60 * 60) try: publish_new_offer(sale_offer) except (NoEndpoint, DisabledEndpoint): pass return CoastalJsonResponse(result)
def flag_junk(request): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) try: product = Product.objects.get(id=request.POST.get('product_ids')) except Product.DoesNotExist: return CoastalJsonResponse(status=response.STATUS_404) except ValueError: return CoastalJsonResponse(status=response.STATUS_404) if request.POST.get('flag') == '1': if Report.objects.filter(product=product, user=request.user): Report.objects.filter(product=product, user=request.user).update( status=0, datetime=datetime.now()) else: Report.objects.create(product=product, user=request.user, status=0, datetime=datetime.now()) return CoastalJsonResponse()
def calc_total_price(request): data = request.GET.copy() if 'product_id' in data: data['product'] = data.get('product_id') form = RentalBookForm(data) if not form.is_valid(): return CoastalJsonResponse(form.errors, status=400) start_datetime = form.cleaned_data['start_datetime'] end_datetime = form.cleaned_data['end_datetime'] rental_unit = form.cleaned_data['rental_unit'] product = form.cleaned_data['product'] guest_count = form.cleaned_data['guest_count'] total_amount = calc_price(product, rental_unit, start_datetime, end_datetime, guest_count)[1] data = [{ 'amount': total_amount, 'currency': product.currency, 'amount_display': price_display(total_amount, product.currency), }] return CoastalJsonResponse(data)
def toggle_favorite(request, pid): if request.method != 'POST': return CoastalJsonResponse(status=response.STATUS_405) user = request.user favorite_item = FavoriteItem.objects.filter(favorite__user=user, product_id=pid) if not favorite_item: favorite, _ = Favorites.objects.get_or_create(user=user) FavoriteItem.objects.create(product_id=pid, favorite=favorite) data = { 'product_id': pid, 'is_liked': True, } else: favorite_item.delete() data = { 'product_id': pid, 'is_liked': False, } return CoastalJsonResponse(data)
def recommend_product_list(request): recommend_products = Product.objects.filter(status='published').order_by( '-rank', '-score', '-rental_usd_price', '-sale_usd_price')[0:20] page = request.GET.get('page', 1) bind_product_image(recommend_products) data = [] item = defs.PER_PAGE_ITEM paginator = Paginator(recommend_products, item) try: recommend_products = paginator.page(page) except PageNotAnInteger: recommend_products = paginator.page(1) except EmptyPage: recommend_products = paginator.page(paginator.num_pages) if int(page) >= paginator.num_pages: next_page = 0 else: next_page = int(page) + 1 for product in recommend_products: product_data = model_to_dict(product, fields=[ 'id', 'for_rental', 'for_sale', 'rental_price', 'sale_price' ]) product_data.update({ 'beds': product.beds or 0, 'max_guests': product.max_guests or 0, 'length': product.length or 0, 'category': product.category_id, 'rental_unit': product.get_rental_unit_display(), 'rental_price_display': product.get_rental_price_display(), 'sale_price_display': product.get_sale_price_display(), }) if product.images: product_data['images'] = [i.image.url for i in product.images] else: product_data['images'] = [] if product.point: product_data.update({ 'lon': product.point[0], 'lat': product.point[1], }) data.append(product_data) result = {'recommend_products': data, 'next_page': next_page} return CoastalJsonResponse(result)