def post(self, request, *args, **kwargs): recomment_form = ProductRecommentForm(self.request.POST, self.request.FILES) if recomment_form.is_valid(): reviewpk = self.kwargs["reviewpk"] consumer = Consumer.objects.get(user=self.request.user) review = Product_Comment.objects.get(pk=reviewpk) product = review.product answer = recomment_form.save(commit=False) answer.author = self.request.user answer.comment = review answer.save() farmer_args = { "#{consumer_nickname}": self.request.user.nickname, "#{farmer_nickname}": review.product.farmer.user.nickname, "#{link1}": f"www.pickyfarm.com/farmer/mypage/reviews-qnas/review/{review.pk}/answer", } # 농가 카카오 알림톡 전송 send_kakao_message( review.consumer.user.phone_number, templateIdList["new_recomment_CF"], farmer_args, ) return redirect("core:popup_callback")
def order_complete(self, request, queryset): # order_Detail 돌면서 배송완료, 카카오알림톡 보내기 print(queryset) queryset_len = len(queryset) all_success = True fail_list = list() idx = 0 for order in list(queryset): idx += 1 if order.status != 'shipping': all_success = False fail_list.append(idx) continue order.status = "delivery_complete" user = order.order_group.consumer.user consumer_nickname = user.nickname phone_number = user.phone_number farmer = order.product.farmer farmer_pk = farmer.pk farmer_nickname = farmer.user.nickname order_pk = order.pk args = { "#{consumer_nickname}": consumer_nickname, "#{farmer_nickname}": farmer_nickname, "#{link_1}": f"www.pickyfarm.com/user/mypage/orders/{order_pk}/review/create", "#{link_2}": f"www.pickyfarm.com/farmer/farmer_detail/{farmer_pk}/" } send_kakao_message(phone_number, templateIdList["delivery_complete"], args) order.save() if all_success == True: self.message_user(request, f"{queryset_len}개의 주문이 배송 완료 처리 되었습니다", messages.SUCCESS) else: self.message_user(request, f"[배송중] 상태가 아닌 주문이 있습니다 : {fail_list}", messages.ERROR)
def vbank_progess(request): user = request.user if request.method == "POST": # [PROCESS 1] GET Parameter에 있는 pk 가져와서 Order_Group select / 구독 리스트 추출 order_group_pk = int(request.POST.get("order_group_pk")) order_group = Order_Group.objects.get(pk=order_group_pk) order_details = order_group.order_details.all() farmers = list(set(map(lambda u: u.product.farmer, order_details))) unsubscribed_farmers = list() subscribed_farmers = list() farmers_info = [] for farmer in farmers: farmers_info.append( payment_valid_farmer( farmer.pk, farmer.farm_name, farmer.user.nickname, farmer.user.phone_number, ) ) if Subscribe.objects.filter( consumer=order_group.consumer, farmer=farmer ).exists(): subscribed_farmers.append(farmer) else: unsubscribed_farmers.append(farmer) farmers_info = sorted(farmers_info, key=lambda x: x.farmer_pk) farmers_info_len = len(farmers_info) # [PROCESS 2] 클라이언트에서 보낸 total_price와 서버의 total price 비교 client_total_price = int(request.POST.get("total_price")) print(f"--------total_price : {client_total_price} ---------") try: if order_group.total_price != client_total_price: raise priceMatchError except priceMatchError: print(priceMatchError) order_group.status = "error_price_match" for detail in order_group.order_details: detail.status = "error_price_match" detail.save() order_group.save() return redirect( f'{reverse("orders:payment_fail")}?errorType=error_price_match&orderGroupPK={order_group_pk}' ) # [PROCESS 3] Order_Group에 속한 Order_detail을 모두 가져와서 재고량 확인 # 모든 주문 상품 재고량 확인 태그 valid = True # 재고가 부족한 상품명 리스트 invalid_products = list() # [PROCESS 4] 결제 전 최종 재고 확인 for detail in order_details: print("[재고 확인 상품 재고] " + (str)(detail.product.stock)) print("[재고 확인 주문양] " + (str)(detail.quantity)) if detail.product.stock - detail.quantity < 0: valid = False # 재고가 부족한 경우 부족한 상품 title 저장 -> 추후 결제 실패 페이지의 오류 메시지로 출력 invalid_products.append(detail.product.title) print(detail.product.title + "재고 부족") else: # 재고가 있는 경우 재고 차감 detail.product.sold(detail.quantity) detail.save() print(invalid_products) try: # 재고가 없어서 valid가 False인경우 Exception 발생 if valid is False: print(f"--------재고 부족 ---------") raise stockLackError except stockLackError: print(stockLackError) order_group.status = "error_stock" for detail in order_details: detail.status = "error_stock" detail.save() order_group.save() print("[valid 값]" + (str)(valid)) print("[invalid_products]" + (str)(invalid_products)) res_data = { "valid": valid, "error_type": "error_stock", "invalid_products": invalid_products, } return redirect( f'{reverse("orders:payment_fail")}?errorType=error_stock&orderGroupPK={order_group_pk}&errorMsg={(str)(invalid_products)}의 재고가 부족합니다' ) # [PROCESS 5] 재고 확인 성공인 경우 if valid is True: print(f"--------재고 확인 성공 ---------") # [PROCESS 6] 주문 정보 Order_Group에 등록 rev_name = request.POST.get("rev_name") rev_phone_number = request.POST.get("rev_phone_number") rev_address = request.POST.get("rev_address") rev_loc_at = request.POST.get("rev_loc_at") rev_message = request.POST.get("rev_message") to_farm_message = request.POST.get("to_farm_message") payment_type = request.POST.get("payment_type") order_group_name = request.POST.get("order_group_name") # 가상계좌 관련 정보 v_bank = request.POST.get("v_bank") v_bank_account = request.POST.get("v_bank_account") v_bank_account_holder = request.POST.get("v_bank_account_holder") v_bank_expire_date_str = request.POST.get("v_bank_expire_date") receipt_id = request.POST.get("receipt_id") print(f"--------vbank : {v_bank} account : {v_bank_account}---------") # 가상계좌 입금 마감 기한 datetime 변환 v_bank_expire_date = datetime.strptime( v_bank_expire_date_str, "%Y-%m-%d %H:%M:%S" ) v_bank_expire_date = timezone.make_aware(v_bank_expire_date) print(f"-----가상계좌 마감 기한 시간 변환 완료 : {v_bank_expire_date}---------") print( rev_name + rev_phone_number + rev_loc_at + rev_message + to_farm_message ) print(order_group) # 배송 정보 order_group에 업데이트 order_group.rev_name = rev_name order_group.rev_address = rev_address order_group.rev_phone_number = rev_phone_number order_group.rev_loc_at = rev_loc_at # order_group.rev_loc_detail=rev_loc_detail order_group.rev_message = rev_message order_group.to_farm_message = to_farm_message order_group.payment_type = payment_type order_group.v_bank = v_bank order_group.v_bank_account = v_bank_account order_group.v_bank_account_holder = v_bank_account_holder order_group.v_bank_expire_date = v_bank_expire_date order_group.receipt_number = receipt_id order_group.order_at = timezone.now() order_group.status = "wait_vbank" order_group.save() print( f"------order_group v_bank_expire_date {order_group.v_bank_expire_date}" ) # 카카오 알림톡 전송 args_kakao = { "#{order_title}": order_group_name, "#{v_bank}": v_bank, "#{v_bank_account}": v_bank_account, "#{v_bank_account_holder}": v_bank_account_holder, "#{total_price}": str(client_total_price) + "원", "#{v_bank_expire_date}": v_bank_expire_date_str, } # 소비자 결제 완료 카카오 알림톡 전송 send_kakao_message( user.phone_number, templateIdList["vbank_info"], args_kakao ) ctx = { "order_group": order_group, "order_details": order_details, "sub_farmers": subscribed_farmers, "unsub_farmers": unsubscribed_farmers, # "v_bank" : v_bank, # "v_bank_account" : v_bank_account, # "v_bank_account_holder" : v_bank_account_holder, # "v_bank_expire_date" : str(v_bank_expire_date), } nowDatetime = timezone.now().strftime("%Y-%m-%d %H:%M:%S") print(f"=== V_BANK_PROGRESS SUCCESS : {nowDatetime} ===") return render(request, "orders/payment_success.html", ctx)
def payment_valid(request): if request.method == "POST": REST_API_KEY = os.environ.get("BOOTPAY_REST_KEY") PRIVATE_KEY = os.environ.get("BOOTPAY_PRIVATE_KEY") receipt_id = request.POST.get("receipt_id") order_group_pk = int(request.POST.get("orderGroupPk")) order_group = Order_Group.objects.get(pk=order_group_pk) total_price = order_group.total_price order_details = Order_Detail.objects.filter(order_group=order_group) farmers = list(set(map(lambda u: u.product.farmer, order_details))) unsubscribed_farmers = list() subscribed_farmers = list() farmers_info = [] for farmer in farmers: farmers_info.append( payment_valid_farmer( farmer.pk, farmer.farm_name, farmer.user.nickname, farmer.user.phone_number, ) ) if Subscribe.objects.filter( consumer=order_group.consumer, farmer=farmer ).exists(): subscribed_farmers.append(farmer) else: unsubscribed_farmers.append(farmer) farmers_info = sorted(farmers_info, key=lambda x: x.farmer_pk) farmers_info_len = len(farmers_info) print(f"Farmer_INFO len : {farmers_info_len}") order_group.receipt_number = receipt_id bootpay = BootpayApi(application_id=REST_API_KEY, private_key=PRIVATE_KEY) result = bootpay.get_access_token() if result["status"] == 200: verify_result = bootpay.verify(receipt_id) if verify_result["status"] == 200: if ( verify_result["data"]["price"] == total_price and verify_result["data"]["status"] == 1 ): phone_number_consumer = order_group.consumer.user.phone_number for detail in order_details: product = detail.product # order_detail 재고 차감 product.sold(detail.quantity) # order_detail status - payment_complete로 변경 detail.status = "payment_complete" detail.payment_status = "incoming" # 정산상태 정산예정으로 변경 detail.product.save() detail.save() # kakao_msg_weight = (str)(product.weight) + product.weight_unit kakao_msg_quantity = (str)(detail.quantity) + "개" target_farmer_pk = product.farmer.pk target_farmer = farmer_search( farmers_info, target_farmer_pk, 0, farmers_info_len ) print("Farmer!!!" + target_farmer.farm_name) args_consumer = { "#{farm_name}": target_farmer.farm_name, "#{order_detail_number}": detail.order_management_number, "#{order_detail_title}": detail.product.title, "#{farmer_nickname}": target_farmer.farmer_nickname, "#{option_name}": detail.product.option_name, "#{quantity}": kakao_msg_quantity, "#{link_1}": f"www.pickyfarm.com/farmer/farmer_detail/{target_farmer_pk}", # 임시 "#{link_2}": "www.pickyfarm.com/user/mypage/orders", # 임시 } # 소비자 결제 완료 카카오 알림톡 전송 send_kakao_message( phone_number_consumer, templateIdList["payment_complete"], args_consumer, ) # order_management_number 인코딩 url_encoded_order_detail_number = ( url_encryption.encode_string_to_url( detail.order_management_number ) ) args_farmer = { "#{order_detail_title}": detail.product.title, "#{order_detail_number}": detail.order_management_number, "#{option_name}": detail.product.option_name, "#{quantity}": kakao_msg_quantity, "#{rev_name}": order_group.rev_name, "#{rev_phone_number}": phone_number_consumer, "#{rev_address}": order_group.rev_address, "#{rev_loc_at}": order_group.rev_loc_at, "#{rev_detail}": order_group.rev_message, "#{rev_message}": order_group.to_farm_message, "#{link_1}": f"www.pickyfarm.com/farmer/mypage/orders/check?odmn={url_encoded_order_detail_number}", # 임시 "#{link_2}": f"www.pickyfarm.com/farmer/mypage/orders/cancel?odmn={url_encoded_order_detail_number}", # 임시 "#{link_3}": f"www.pickyfarm.com/farmer/mypage/orders/invoice?odmn={url_encoded_order_detail_number}", # 임시 } print(f'주문확인 url : {args_farmer["#{link_1}"]}') send_kakao_message( target_farmer.farmer_phone_number, templateIdList["order_recept"], args_farmer, ) # order_group status - payment complete로 변경 order_group.status = "payment_complete" order_group.save() ctx = { "order_group": order_group, "data": verify_result, "order_details": order_details, "sub_farmers": subscribed_farmers, "unsub_farmers": unsubscribed_farmers, } nowDatetime = timezone.now().strftime("%Y-%m-%d %H:%M:%S") print(f"=== PAYMENT VALIDATION SUCCESS : {nowDatetime} ===") print(f"=== RECIPT ID : {receipt_id} ===") return render(request, "orders/payment_success.html", ctx) else: cancel_result = bootpay.cancel( receipt_id, total_price, request.user.nickname, "결제검증 실패로 인한 결제 취소" ) if cancel_result["status"] == 200: # order_group status - 에러 검증실패로 변경 order_group.status = "error_valid" order_group.save() # order_detail status - 에러 검증실패로 변경 for detail in order_details: detail.status = "error_valid" detail.save() ctx = {"cancel_result": cancel_result} return redirect( f'{reverse("orders:payment_fail")}?errorType=error_validk&orderGroupPK={order_group_pk}' ) else: order_group.status = "error_server" order_group.save() # order_detail status - 에러 서버로 변경 for detail in order_details: detail.status = "error_server" detail.save() ctx = { "cancel_result": "결제 검증에 실패하여 결제 취소를 시도하였으나 실패하였습니다. 고객센터에 문의해주세요" } return redirect( f'{reverse("orders:payment_fail")}?errorType=error_server&orderGroupPK={order_group_pk}' ) return HttpResponse("잘못된 접근입니다", status=400)
def send_kakao_with_payment_complete(order_group_pk, receipt_id): order_group = Order_Group.objects.get(pk=order_group_pk) order_details = order_group.order_details.all() farmers = list(set(map(lambda u: u.product.farmer, order_details))) phone_number_consumer = order_group.consumer.user.phone_number farmers_info = [] for farmer in farmers: farmers_info.append( payment_valid_farmer( farmer.pk, farmer.farm_name, farmer.user.nickname, farmer.user.phone_number, ) ) farmers_info = sorted(farmers_info, key=lambda x: x.farmer_pk) farmers_info_len = len(farmers_info) # print(f"Farmer_INFO len : {farmers_info_len}") order_group.receipt_number = receipt_id for detail in order_details: product = detail.product detail.status = "payment_complete" detail.payment_status = "incoming" # 정산상태 정산예정으로 변경 detail.save() kakao_msg_quantity = (str)(detail.quantity) + "개" target_farmer_pk = product.farmer.pk target_farmer = farmer_search( farmers_info, target_farmer_pk, 0, farmers_info_len ) # print("Farmer!!!" + target_farmer.farm_name) args_consumer = { "#{farm_name}": target_farmer.farm_name, "#{order_detail_number}": detail.order_management_number, "#{order_detail_title}": detail.product.title, "#{farmer_nickname}": target_farmer.farmer_nickname, "#{option_name}": detail.product.option_name, "#{quantity}": kakao_msg_quantity, "#{link_1}": f"www.pickyfarm.com/farmer/farmer_detail/{target_farmer_pk}", # 임시 "#{link_2}": "www.pickyfarm.com/user/mypage/orders", # 임시 } # 소비자 결제 완료 카카오 알림톡 전송 send_kakao_message( phone_number_consumer, templateIdList["payment_complete"], args_consumer, ) # order_management_number 인코딩 url_encoded_order_detail_number = url_encryption.encode_string_to_url( detail.order_management_number ) args_farmer = { "#{order_detail_title}": detail.product.title, "#{order_detail_number}": detail.order_management_number, "#{option_name}": detail.product.option_name, "#{quantity}": kakao_msg_quantity, "#{rev_name}": order_group.rev_name, "#{rev_phone_number}": phone_number_consumer, "#{rev_address}": order_group.rev_address, "#{rev_loc_at}": order_group.rev_loc_at, "#{rev_detail}": order_group.rev_message, "#{rev_message}": order_group.to_farm_message, "#{link_1}": f"www.pickyfarm.com/farmer/mypage/orders/check?odmn={url_encoded_order_detail_number}", # 임시 "#{link_2}": f"www.pickyfarm.com/farmer/mypage/orders/cancel?odmn={url_encoded_order_detail_number}", # 임시 "#{link_3}": f"www.pickyfarm.com/farmer/mypage/orders/invoice?odmn={url_encoded_order_detail_number}", # 임시 } print(f'주문확인 url : {args_farmer["#{link_1}"]}') send_kakao_message( target_farmer.farmer_phone_number, templateIdList["order_recept"], args_farmer, ) order_group.status = "payment_complete" order_group.save()
def create_change_or_refund(request, pk): user = request.user if request.method == "GET": user = request.user addresses = user.addresses.all ctx = {"addresses": addresses} return render(request, "users/mypage/user/product_refund_popup.html", ctx) elif request.method == "POST": order_detail = Order_Detail.objects.get(pk=pk) claim_type = request.POST.get("change_or_refund", None) print(claim_type) # order_detail status 변경 (환불/반품 접수) if claim_type == "refund": order_detail.status = "re_recept" elif claim_type == "exchange": order_detail.status = "ex_recept" else: return redirect(reverse("core:main")) order_detail.save() claim_reason = request.POST.get("reason_txt", None) print(claim_reason) image = request.FILES.get("product_image", None) print(image) rev_loc_at = request.POST.get("rev_loc_at", None) print(rev_loc_at) rev_address = request.POST.get("address", None) refundExchange = RefundExchange( claim_type=claim_type, claim_status="recept", order_detail=order_detail, reason=claim_reason, image=image, rev_address=rev_address, rev_loc_at=rev_loc_at, ) # 주문 일시 order_detail_create_at = order_detail.create_at.date().strftime("%Y.%m.%d") # Product product = order_detail.product # product kinds (무난이, 일반작물) product_kinds = product.kinds # 농장 이름 order_detail_farm_name = product.farmer.farm_name # product 이름 product_title = product.title # product가격 product_price = product.sell_price # product weight product_weight = (str)(product.weight) + (str)(product.weight_unit) # order_detail quantity order_detail_quantity = order_detail.quantity ctx = { "order_date": order_detail_create_at, "farm_name": order_detail_farm_name, "product_kinds": product_kinds, "product_title": product_title, "product_price": product_price, "product_weight": product_weight, "order_detail_quantity": order_detail_quantity, "refundExchange": refundExchange, } farmer_phone_number = order_detail.product.farmer.user.phone_number consumer_phone_number = order_detail.order_group.consumer.user.phone_number weight = order_detail.product.weight weight_unit = order_detail.product.weight_unit quantity = order_detail.quantity # kakao_msg_weight = (str)(weight) + weight_unit kakao_msg_quantity = (str)(quantity) + "개" order_management_number = order_detail.order_management_number url_encoded_order_management_number = url_encryption.encode_string_to_url( order_management_number ) product_title = order_detail.product.title farmer_args = { "#{order_detail_title}": product_title, "#{order_detail_number}": order_management_number, "#{option_name}": order_detail.product.option_name, "#{quantity}": kakao_msg_quantity, "#{consumer_nickname}": user.nickname, "#{reason}": claim_reason, } consumer_args = { "#{order_detail_title}": product_title, "#{order_detail_number}": order_management_number, "#{quantity}": kakao_msg_quantity, } if claim_type == "refund": refundExchange.refund_exchange_delivery_fee = product.refund_delivery_fee refundExchange.save() farmer_args[ "#{link}" ] = f"www.pickyfarm.com/farmer/mypage/orders/refund/request/check?odmn={url_encoded_order_management_number}" send_kakao_message( farmer_phone_number, templateIdList["refund_recept_for_farmer"], farmer_args, ) send_kakao_message( consumer_phone_number, templateIdList["refund_recept_for_consumer"], consumer_args, ) return render( request, "users/mypage/user/product_refund_complete.html", ctx ) elif claim_type == "exchange": refundExchange.refund_exchange_delivery_fee = product.exchange_delivery_fee refundExchange.save() farmer_args[ "#{link}" ] = f"www.pickyfarm.com/farmer/mypage/orders/exchange/request/check?odmn={url_encoded_order_management_number}" send_kakao_message( farmer_phone_number, templateIdList["exchange_recept_for_farmer"], farmer_args, ) send_kakao_message( consumer_phone_number, templateIdList["exchange_recept_for_consumer"], consumer_args, ) return render( request, "users/mypage/user/product_exchange_complete.html", ctx ) else: return redirect(reverse("core:main")) else: return redirect(reverse("core:main"))
def post(self, request, **kwargs): detail = self.get_context_data(**kwargs)["detail"] product_pk = detail.product.pk product_comment = ProductCommentForm(request.POST, request.FILES) consumer = Consumer.objects.get(pk=self.request.user.consumer.pk) product_comment_eixst = Product_Comment.objects.filter( order__pk=detail.pk).exists() print(f"[PRODUCT COMMENT POST] 사용자 : {consumer.user.account_name}") if product_comment.is_valid() and not product_comment_eixst: text = product_comment.cleaned_data.get("text") freshness = product_comment.cleaned_data.get("freshness") flavor = product_comment.cleaned_data.get("flavor") cost_performance = product_comment.cleaned_data.get( "cost_performance") product_comment = Product_Comment( order=detail, text=text, freshness=int(freshness), flavor=int(flavor), cost_performance=int(cost_performance), ) product_comment.consumer = consumer product_comment.product = detail.product product_comment.save() product_comment.product.reviews += 1 product_comment.get_rating_avg() # Product_Comment_Image product_comment_imgs = request.FILES.getlist("product_image") img_valid = True if len(product_comment_imgs ) == 1 and product_comment_imgs[0] == "": img_valid = False if img_valid == True: for img in product_comment_imgs: images = Product_Comment_Image.objects.create( product_comment=product_comment, image=img) images.save() # freshness if product_comment.freshness == 1: detail.product.freshness_1 += 1 elif product_comment.freshness == 3: detail.product.freshness_3 += 1 else: detail.product.freshness_5 += 1 # flavor if product_comment.flavor == 1: detail.product.flavor_1 += 1 elif product_comment.flavor == 3: detail.product.flavor_3 += 1 else: detail.product.flavor_5 += 1 # cost_performance if product_comment.cost_performance == 1: detail.product.cost_performance_1 += 1 elif product_comment.cost_performance == 3: detail.product.cost_performance_3 += 1 else: detail.product.cost_performance_5 += 1 # total rating calculate detail.product.calculate_total_rating_sum(product_comment.avg) detail.product.calculate_total_rating_avg() detail.product.product_group.calculate_total_rating_avg() # specific rating calculate detail.product.calculate_specific_rating(int(freshness), int(flavor), int(cost_performance)) print("[PRODUCT COMMENT POST] Post view 마지막") # send kakao message to farmer message_args = { "#{link}": f"www.pickyfarm.com/farmer/mypage/reviews-qnas/review/{product_comment.pk}/answer", "#{product_title}": f"{detail.product.title}", } send_kakao_message( detail.product.farmer.user.phone_number, templateIdList["new_product_review"], message_args, ) return redirect("core:popup_callback") return redirect("core:main")