def form_valid(self, form): response = super(MemberConfirmDocumentView, self).form_valid(form) ''' orders = Order.objects.valid(self.request.user).filter(status__in=[ Order.STATUS_CHOICES.payment_completed, Order.STATUS_CHOICES.under_review, Order.STATUS_CHOICES.payment_verified ]) if orders: html_message = render_to_string('member/account/email/document_verified.html', {'profile': self.object, 'orders': orders}) send_notification_email.delay( _('[site] Customer Document Verification'), 'dummy', settings.EMAIL_NO_REPLY, [settings.EMAIL_CUSTOMER_SERVICE], html_message, ) ''' message = _('Document Verification {} {} {}') \ .format(self.object.full_name, self.object.email, self.request.build_absolute_uri(reverse('rabop:customer-detail', args=('default', self.object.id)))) send_notification_line.delay(message) return response
def form_valid(self, form): form.instance.owner = self.request.user form.instance.store = self.store response = super(CustomerQuestionCreateView, self).form_valid(form) ''' html_message = render_to_string('shop/{}/email/customer_question.html'.format('default'), {'question': self.object}) send_notification_email.delay( _('[site] Customer Question'), 'dummy', settings.EMAIL_NO_REPLY, [settings.EMAIL_CUSTOMER_SERVICE], html_message, ) ''' message = _('Customer Question') send_notification_line.delay(message) return response
def form_valid(self, form): testimonial = models.Testimonials.objects.select_related('owner', 'owner__profile').get(pk=self.kwargs['pk']) form.instance.testimonial = testimonial form.save() code = '해피1천' if testimonial.owner.profile.phone: count = models.Voucher.objects \ .select_related('product') \ .filter(product__code=code, status=models.Voucher.STATUS_CHOICES.purchased) \ .count() if count > 0: vouchers = models.Voucher.objects \ .select_related('product') \ .filter(product__code=code, status=models.Voucher.STATUS_CHOICES.purchased) \ .order_by('pk')[:1] # Mark as sold # NOTE: Cannot update a query once a slice has been taken. voucher_pk = list(map(lambda x: x.id, vouchers)) models.Voucher.objects.filter(pk__in=voucher_pk).update(status=models.Voucher.STATUS_CHOICES.sold) send_sms.delay(testimonial.owner.profile.phone, "[핀코인] [해피머니1천원] {} 발행일자 {}" .format(vouchers[0].code, vouchers[0].remarks)) form.instance.content = '{}\n\n해피머니 1천원: {}\n발행일자:{}'.format(form.instance.content, vouchers[0].code, vouchers[0].remarks) else: send_notification_line.delay(_('No giftcard')) return super(TestimonialsAnswerView, self).form_valid(form)
def post(self, request, store, format=None): serializer = IamportCallbackSerializer(data=request.data) if serializer.is_valid(): response = self.find(request.data['imp_uid']) if response \ and response['merchant_uid'] == request.data['merchant_uid'] \ and response['apply_num'] == request.data['apply_num'] \ and response['amount'] == int(request.data['paid_amount']): order = models.Order.objects \ .select_related('user', 'user__profile') \ .get(order_no=response['merchant_uid']) if order.user.profile.phone_verified_status == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and order.user.profile.full_name == order.fullname: if order.total_selling_price == Decimal( response['amount']): if send_vouchers(order): return Response(serializer.data, status=status.HTTP_200_OK) else: # failure order.status = models.Order.STATUS_CHOICES.payment_completed order.save() send_notification_line.delay( _('Failure: credit card 1')) return Response(serializer.data, status=status.HTTP_202_ACCEPTED) else: # invalid paid amount order.status = models.Order.STATUS_CHOICES.voided order.save() send_notification_line.delay( _('Failure: credit card 2')) else: # invalid user order.status = models.Order.STATUS_CHOICES.voided order.save() send_notification_line.delay(_('Failure: credit card 3')) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, store, format=None): serializer = BootpayCallbackSerializer(data=request.data) if serializer.is_valid(): response = self.find(request.data['receipt_id']) if response and response['status'] == 1 \ and response['order_id'] == request.data['order_id'] \ and response['price'] == int(request.data['price']): order = models.Order.objects \ .select_related('user', 'user__profile') \ .get(order_no=response['order_id']) if order.user.profile.phone_verified_status == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and order.user.profile.full_name == order.fullname: if order.total_selling_price == Decimal(response['price']): if send_vouchers(order): pass else: # failure order.status = models.Order.STATUS_CHOICES.payment_completed order.save() send_notification_line.delay( _('Failure: credit card 1')) else: # invalid paid amount order.status = models.Order.STATUS_CHOICES.voided order.save() send_notification_line.delay( _('Failure: credit card 2')) else: # invalid user order.status = models.Order.STATUS_CHOICES.voided order.save() send_notification_line.delay(_('Failure: credit card 3')) return HttpResponse('OK')
def post(self, request, format=None): serializer = OrderPaymentSerializer(data=request.data) notify = True if serializer.is_valid(): # KB 에스크로 입금처리 안함, KB 리브머니 입금처리 함 if not (int(request.data['account']) == OrderPayment.ACCOUNT_CHOICES.kb and "전자결제입금" in request.data['method']) \ and ((int(request.data['account']) == OrderPayment.ACCOUNT_CHOICES.kb and request.data['method'] in ['리브머니', '제휴CD이체']) or "입금" in request.data['method']): self.logger.debug('{} {} {} {} {} {}'.format( request.data['account'], request.data['received'], request.data['name'], request.data['method'], request.data['amount'], request.data['balance'])) op = OrderPayment() amount = Decimal(request.data['amount'].replace(",", "")) balance = Decimal(request.data['balance'].replace(",", "")) fullname = request.data['name'].strip() if int(request.data['account']) == OrderPayment.ACCOUNT_CHOICES.nh \ and re.match('\d{3}-[가-힣]*', fullname): fullname = fullname[4:] orders = Order.objects \ .select_related('user') \ .prefetch_related('products') \ .filter(is_removed=False, visible=Order.VISIBLE_CHOICES.visible, status=Order.STATUS_CHOICES.payment_pending, total_selling_price__lte=amount, fullname=fullname, ).order_by('-created') # Check duplicate user name users = set() for o in orders: users.add(o.user.pk) found = False if len(orders) and len(users) > 1: duplicates = 0 for order in orders: if order.total_selling_price == amount: found = True op.order = order duplicates += 1 if duplicates > 0: found = False elif len(orders) and len(users) == 1: found = True op.order = orders[0] # Pick the latest order if found: op.account = request.data['account'] op.amount = amount op.balance = balance op.received = make_aware(localtime().now()) op.save() # Change order status result = op.order.payments.all().aggregate( total=Sum('amount')) total = result['total'] if result['total'] else Decimal( '0.00') if total >= op.order.total_selling_price: if op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and op.order.user.profile.document_verified: op.order.status = Order.STATUS_CHOICES.payment_verified elif op.order.user.profile.phone_verified_status \ != Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and not op.order.user.profile.document_verified: op.order.status = Order.STATUS_CHOICES.under_review if op.order.user.profile.total_order_count == 0: notify = False else: op.order.status = Order.STATUS_CHOICES.payment_completed op.order.save() # mileage if overpaid if total > op.order.total_selling_price: mileage_log = MileageLog() mileage_log.user = op.order.user mileage_log.order = op.order mileage_log.mileage = total - op.order.total_selling_price mileage_log.memo = _('Overpaid') mileage_log.save() send = False has_safe_vouchers = False for order_product in op.order.products.all(): if order_product.name not in [ '문화상품권', '해피머니', '도서문화상품권', ]: has_safe_vouchers = True if total >= op.order.total_selling_price: if op.order.user.profile.total_order_count == 0 \ and op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified: if op.order.total_list_price < Decimal( shop_settings.SUSPICIOUS_AMOUNT20): # 주문 0회, 20만원 미만, 휴대폰인증 완료 send = True elif op.order.total_list_price < Decimal(shop_settings.SUSPICIOUS_AMOUNT30) \ and has_safe_vouchers: # 주문 0회, 30만원 미만, 휴대폰인증 완료, 카드상품권 포함 send = True elif op.order.user.profile.total_order_count > 0: order_history = Order.objects.filter( user=op.order.user, is_removed=False, status=Order.STATUS_CHOICES.shipped) \ .aggregate(Min('created'), Max('created')) if op.order.user.profile.total_order_count > 5 \ and op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and op.order.user.profile.document_verified \ and op.order.total_selling_price <= op.order.user.profile.max_price \ and order_history['created__min'] \ and now() - order_history['created__min'] > timedelta(days=14) \ and order_history['created__max'] \ and now() - order_history['created__max'] < timedelta(days=30): # 주문 5회 초과, 휴대폰인증 and 서류본인인증 완료, 최고 구매액 이하 # 첫 구매 14일 경과, 마지막 구매 30일 이내 send = True elif op.order.user.profile.total_order_count > 5 \ and (op.order.user.profile.phone_verified_status == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified or op.order.user.profile.document_verified) \ and has_safe_vouchers \ and op.order.total_selling_price <= op.order.user.profile.max_price \ and order_history['created__min'] \ and now() - order_history['created__min'] > timedelta(days=14) \ and order_history['created__max'] \ and now() - order_history['created__max'] < timedelta(days=30): # 주문 5회 초과, 휴대폰인증 or 서류본인인증, 최고 구매액 이하, 카드상품권 포함 # 첫 구매 14일 경과, 마지막 구매 30일 이내 send = True if op.order.total_list_price <= Decimal(shop_settings.SUSPICIOUS_AMOUNT10) \ and op.order.user.profile.document_verified: # 10만원 이하 서류본인인증 완료 send = True elif op.order.total_list_price < Decimal(shop_settings.SUSPICIOUS_AMOUNT20) \ and op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified: # 20만원 미만, 휴대폰인증 완료 send = True elif op.order.total_list_price <= Decimal(shop_settings.SUSPICIOUS_AMOUNT20) \ and op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and op.order.user.profile.document_verified: # 20만원 이하, 휴대폰인증 and 서류본인인증 완료 send = True elif op.order.total_list_price < Decimal(shop_settings.SUSPICIOUS_AMOUNT30) \ and op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and has_safe_vouchers: # 30만원 미만, 휴대폰인증 완료, 카드상품권 포함 send = True elif op.order.total_list_price <= Decimal(shop_settings.SUSPICIOUS_AMOUNT50) \ and op.order.user.profile.phone_verified_status \ == Profile.PHONE_VERIFIED_STATUS_CHOICES.verified \ and op.order.user.profile.document_verified \ and has_safe_vouchers: # 50만원 이하, 휴대폰인증 and 서류본인인증 완료, 카드상품권 포함 send = True if send and send_vouchers(op.order): return Response(serializer.data, status=status.HTTP_201_CREATED) if notify: message = '[{}]\n일시: {}\n이름: {}\n입출: {}\n금액: {}\n잔액: {}'.format( OrderPayment.ACCOUNT_CHOICES[int(request.data['account'])], request.data['received'], request.data['name'], request.data['method'], request.data['amount'], request.data['balance'], ) send_notification_line.delay(message) if serializer.is_valid(): return Response(serializer.data, status=status.HTTP_202_ACCEPTED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, format=None): serializer = IamportSmsCallbackSerializer(data=request.data) if serializer.is_valid(): response = self.find(request.data['imp_uid']) if response and response['certified']: print(request.data) print(response) try: profile = Profile.objects.select_related('user').get( user__pk=int(request.data['merchant_uid'])) log = PhoneVerificationLog() log.owner = profile.user log.transaction_id = response['pg_tid'] log.di = response['unique_in_site'] log.ci = response['unique_key'] log.fullname = response['name'] log.date_of_birth = datetime.fromtimestamp( int(response['birth'])).strftime('%Y%m%d') log.gender = 1 if response['gender'] == 'male' else 0 log.domestic = 1 if not response['foreigner'] else 0 log.telecom = response['carrier'] log.cellphone = response['phone'] log.save() # check duplicate user verifications logs = PhoneVerificationLog.objects \ .filter(ci=log.ci, owner__isnull=False, created__gte=make_aware(localtime().now() - timedelta(hours=48))) \ .exclude(owner=log.owner) banned = PhoneBanned.objects.filter( phone=log.cellphone).exists() if not logs: if not banned: profile.phone = log.cellphone if log.fullname == profile.full_name: profile.phone_verified_status = Profile.PHONE_VERIFIED_STATUS_CHOICES.verified profile.date_of_birth = datetime.strptime( log.date_of_birth, '%Y%m%d').date() profile.gender = log.gender profile.domestic = log.domestic profile.telecom = log.telecom profile.save() orders = Order.objects.valid( profile.user).filter(status__in=[ Order.STATUS_CHOICES.under_review, ]) if orders: message = _( 'Phone Verification {}').format( profile.full_name) send_notification_line.delay(message) return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(data=json.dumps({ 'code': 400, 'message': str( _('Your name does not match the phone owner.' )) }), status=status. HTTP_400_BAD_REQUEST) else: return Response(data=json.dumps({ 'code': 400, 'message': str(_('Your phone number is banned.')) }), status=status.HTTP_400_BAD_REQUEST) else: return Response(data=json.dumps({ 'code': 400, 'message': str(_('You have verified within 48 hours.')) }), status=status.HTTP_400_BAD_REQUEST) except (Profile.DoesNotExist, PhoneVerificationLog.DoesNotExist): return Response(data=json.dumps({ 'code': 400, 'message': str(_('Illegal access: no record')) }), status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, format=None): serializer = IamportSmsCallbackSerializer(data=request.data) if serializer.is_valid(): response = self.find(request.data['imp_uid']) if response and response['certified']: print(request.data) print(response) try: profile = Profile.objects.select_related('user').get(user__pk=int(request.data['merchant_uid'])) log = PhoneVerificationLog() log.owner = profile.user log.transaction_id = response['pg_tid'] log.di = response['unique_in_site'] log.ci = response['unique_key'] log.fullname = response['name'] log.date_of_birth = datetime.fromtimestamp(int(response['birth'])).strftime('%Y%m%d') log.gender = 1 if response['gender'] == 'male' else 0 log.domestic = 1 if not response['foreigner'] else 0 log.telecom = response['carrier'] log.cellphone = response['phone'] log.save() # check duplicate user verifications logs = PhoneVerificationLog.objects \ .filter(ci=log.ci, owner__isnull=False, created__gte=make_aware(localtime().now() - timedelta(hours=48))) \ .exclude(owner=log.owner) banned = PhoneBanned.objects.filter(phone=log.cellphone).exists() if not logs: # 1. 50세 이상 여자 90일 if now().date() - datetime.strptime(log.date_of_birth, '%Y%m%d').date() \ > timedelta(days=365 * 50) \ and log.gender == 0 \ and now() - profile.user.date_joined < timedelta(days=90): return Response(data=json.dumps({ 'code': 400, 'message': str( _( 'Person aged over 50 can verify your account during 90 days after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 2. 60세 이상 15일 if now().date() - datetime.strptime(log.date_of_birth, '%Y%m%d').date() \ > timedelta(days=365 * 60) \ and now() - profile.user.date_joined < timedelta(days=15): return Response(data=json.dumps({ 'code': 400, 'message': str( _('Person aged over 60 can verify your account during 15 days after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 3. 50세 이상 남자 72시간 if now().date() - datetime.strptime(log.date_of_birth, '%Y%m%d').date() \ > timedelta(days=365 * 50) \ and log.gender == 1 \ and now() - profile.user.date_joined < timedelta(hours=72): return Response(data=json.dumps({ 'code': 400, 'message': str( _('Person aged over 50 can verify your account during 72 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 4. 45세 이상 여자 72시간 if now().date() - datetime.strptime(log.date_of_birth, '%Y%m%d').date() \ > timedelta(days=365 * 45) \ and log.gender == 0 \ and now() - profile.user.date_joined < timedelta(hours=72): return Response(data=json.dumps({ 'code': 400, 'message': str( _( 'Person aged over 45 can verify your account during 72 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 5. 여자 알뜰폰 72시간 if 'MVNO' in log.telecom and log.gender == 0 \ and now() - profile.user.date_joined < timedelta(hours=72): return Response(data=json.dumps({ 'code': 400, 'message': str( _('MVNO user can verify your account during 72 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 6. 45세 이상 남자 알뜰폰 48시간 if 'MVNO' in log.telecom and log.gender == 1 \ and now().date() - datetime.strptime(log.date_of_birth, '%Y%m%d').date() \ > timedelta(days=365 * 45) \ and now() - profile.user.date_joined < timedelta(hours=48): return Response(data=json.dumps({ 'code': 400, 'message': str( _('MVNO user can verify your account during 48 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 7. 40세 이상 알뜰폰 24시간 if 'MVNO' in log.telecom \ and now().date() - datetime.strptime(log.date_of_birth, '%Y%m%d').date() \ > timedelta(days=365 * 40) \ and now() - profile.user.date_joined < timedelta(hours=24): return Response(data=json.dumps({ 'code': 400, 'message': str(_('MVNO user can verify your account during 24 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 8. 알뜰폰 영업시간 8시간 if 'MVNO' in log.telecom \ and now() - profile.user.date_joined < timedelta(hours=8) \ and datetime.strptime('08:00', '%H:%M').time() < localtime().time() \ < datetime.strptime('19:00', '%H:%M').time(): return Response(data=json.dumps({ 'code': 400, 'message': str( _('MVNO user can verify your account during 8 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) # 9. 여자 영업시간 8시간 if log.gender == 0 \ and now() - profile.user.date_joined < timedelta(hours=8) \ and datetime.strptime('08:00', '%H:%M').time() < localtime().time() \ < datetime.strptime('19:00', '%H:%M').time(): return Response(data=json.dumps({ 'code': 400, 'message': str( _( 'You can verify your account during 8 hours after joined.')) }), status=status.HTTP_400_BAD_REQUEST) if not banned: profile.phone = log.cellphone if log.fullname == profile.full_name: profile.phone_verified_status = Profile.PHONE_VERIFIED_STATUS_CHOICES.verified profile.date_of_birth = datetime.strptime(log.date_of_birth, '%Y%m%d').date() profile.gender = log.gender profile.domestic = log.domestic profile.telecom = log.telecom profile.save() orders = Order.objects.valid(profile.user).filter(status__in=[ Order.STATUS_CHOICES.under_review, ]) if orders: message = _('Phone Verification {}').format(profile.full_name) send_notification_line.delay(message) return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(data=json.dumps({ 'code': 400, 'message': str(_('Your name does not match the phone owner.')) }), status=status.HTTP_400_BAD_REQUEST) else: return Response(data=json.dumps({ 'code': 400, 'message': str(_('Your phone number is banned.')) }), status=status.HTTP_400_BAD_REQUEST) else: return Response(data=json.dumps({ 'code': 400, 'message': str(_('You have verified within 48 hours.')) }), status=status.HTTP_400_BAD_REQUEST) except (Profile.DoesNotExist, PhoneVerificationLog.DoesNotExist): return Response(data=json.dumps({ 'code': 400, 'message': str(_('Illegal access: no record')) }), status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)