small fixes
This commit is contained in:
parent
2727588f58
commit
417475ad54
@ -7,16 +7,16 @@ from django_ledger.models import EstimateModel, BillModel, AccountModel, LedgerM
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **kwargs):
|
||||
Permission.objects.get_or_create(
|
||||
name="Can view crm",
|
||||
codename="can_view_crm",
|
||||
content_type=ContentType.objects.get_for_model(Lead),
|
||||
)
|
||||
Permission.objects.get_or_create(
|
||||
name="Can reassign lead",
|
||||
codename="can_reassign_lead",
|
||||
content_type=ContentType.objects.get_for_model(Lead),
|
||||
)
|
||||
# Permission.objects.get_or_create(
|
||||
# name="Can view crm",
|
||||
# codename="can_view_crm",
|
||||
# content_type=ContentType.objects.get_for_model(Lead),
|
||||
# )
|
||||
# Permission.objects.get_or_create(
|
||||
# name="Can reassign lead",
|
||||
# codename="can_reassign_lead",
|
||||
# content_type=ContentType.objects.get_for_model(Lead),
|
||||
# )
|
||||
Permission.objects.get_or_create(
|
||||
name="Can view sales",
|
||||
codename="can_view_sales",
|
||||
|
||||
@ -2134,6 +2134,10 @@ class Lead(models.Model):
|
||||
slug = RandomCharField(length=8, unique=True)
|
||||
|
||||
class Meta:
|
||||
permissions = [
|
||||
("can_view_crm", _("Can view CRM")),
|
||||
("can_reassign_lead", _("Can reassign lead")),
|
||||
]
|
||||
verbose_name = _("Lead")
|
||||
verbose_name_plural = _("Leads")
|
||||
indexes = [
|
||||
|
||||
@ -10259,31 +10259,52 @@ def submit_plan(request, dealer_slug):
|
||||
|
||||
# @login_required
|
||||
def payment_callback(request, dealer_slug):
|
||||
from django.db import transaction
|
||||
|
||||
payment_id = request.GET.get("id")
|
||||
payment_status = request.GET.get("status")
|
||||
message = request.GET.get("message", "")
|
||||
|
||||
if not payment_id:
|
||||
logger.error("Missing payment ID in callback")
|
||||
return render(request, "payment_failed.html", {"message": "Invalid request"})
|
||||
|
||||
logger.info(
|
||||
f"Received payment callback for dealer_slug: {dealer_slug}, payment_id: {payment_id}, status: {payment_status}"
|
||||
)
|
||||
|
||||
history = models.PaymentHistory.objects.filter(transaction_id=payment_id).first()
|
||||
if not history:
|
||||
logger.error(f"No PaymentHistory found for transaction_id: {payment_id}")
|
||||
return render(
|
||||
request, "payment_failed.html", {"message": "Invalid transaction"}
|
||||
with transaction.atomic():
|
||||
history = (
|
||||
models.PaymentHistory.objects
|
||||
.select_for_update()
|
||||
.filter(transaction_id=payment_id)
|
||||
.first()
|
||||
)
|
||||
|
||||
if history.status == "paid":
|
||||
logger.info("Payment already processed. Redirecting to home.")
|
||||
return redirect("home")
|
||||
if not history:
|
||||
logger.error(f"No PaymentHistory found for transaction_id: {payment_id}")
|
||||
return render(
|
||||
request, "payment_failed.html", {"message": "Invalid transaction"}
|
||||
)
|
||||
|
||||
if history.status == "paid":
|
||||
logger.info("Payment already processed. Redirecting to home.")
|
||||
return redirect("home")
|
||||
|
||||
if history.status == "processing":
|
||||
logger.warning(f"Payment {payment_id} is already being processed. Skipping.")
|
||||
return redirect("home")
|
||||
|
||||
if history.status == "failed" and payment_status != "paid":
|
||||
logger.warning(f"Payment {payment_id} already failed. Ignoring.")
|
||||
return render(request, "payment_failed.html", {"message": message or "Payment failed"})
|
||||
|
||||
history.status = "processing"
|
||||
history.save(update_fields=["status"])
|
||||
|
||||
if payment_status == "paid":
|
||||
logger.info(
|
||||
f"Payment successful for transaction ID {payment_id}. Creating order..."
|
||||
)
|
||||
logger.info(f"Payment successful for transaction ID {payment_id}. Creating order...")
|
||||
|
||||
# Get metadata from PaymentHistory (passed during handle_payment)
|
||||
metadata = history.user_data
|
||||
if isinstance(metadata, str):
|
||||
try:
|
||||
@ -10291,116 +10312,101 @@ def payment_callback(request, dealer_slug):
|
||||
except json.JSONDecodeError:
|
||||
logger.error(f"Failed to decode metadata JSON: {metadata}")
|
||||
metadata = {}
|
||||
|
||||
plan_pricing_id = metadata.get("plan_pricing_id")
|
||||
dealer_slug_from_meta = metadata.get("dealer_slug")
|
||||
|
||||
if not plan_pricing_id or dealer_slug_from_meta != dealer_slug:
|
||||
logger.error("Invalid metadata in payment callback")
|
||||
history.status = "failed"
|
||||
history.save()
|
||||
return render(
|
||||
request, "payment_failed.html", {"message": "Invalid payment data"}
|
||||
)
|
||||
|
||||
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
|
||||
pp = get_object_or_404(PlanPricing, pk=plan_pricing_id)
|
||||
|
||||
# ✅ CREATE ORDER HERE
|
||||
try:
|
||||
order = Order.objects.create(
|
||||
user=dealer.user,
|
||||
plan=pp.plan,
|
||||
pricing=pp.pricing,
|
||||
amount=pp.price,
|
||||
currency="SAR", # Fixed typo: was "SA"
|
||||
tax=15,
|
||||
status=Order.STATUS.NEW, # Use constant if available
|
||||
)
|
||||
logger.info(f"Order {order.id} created for user {dealer.user}")
|
||||
except Exception as e:
|
||||
logger.exception(f"Failed to create order: {e}")
|
||||
history.status = "failed"
|
||||
history.save()
|
||||
return render(
|
||||
request, "payment_failed.html", {"message": "Order creation failed"}
|
||||
)
|
||||
|
||||
# Create or get BillingInfo
|
||||
billing_info, created = BillingInfo.objects.get_or_create(
|
||||
user=dealer.user,
|
||||
defaults={
|
||||
"tax_number": dealer.vrn,
|
||||
"name": dealer.arabic_name,
|
||||
"street": dealer.address,
|
||||
"zipcode": dealer.entity.zip_code or " ",
|
||||
"city": dealer.entity.city or " ",
|
||||
"country": dealer.entity.country or " ",
|
||||
},
|
||||
)
|
||||
if created:
|
||||
logger.info(f"Created new billing info for user {dealer.user}.")
|
||||
else:
|
||||
logger.debug(f"Billing info already exists for user {dealer.user}.")
|
||||
|
||||
# Create or update UserPlan
|
||||
if not hasattr(order.user, "userplan"):
|
||||
UserPlan.objects.create(
|
||||
user=order.user,
|
||||
plan=order.plan,
|
||||
# expire=datetime.now().date() + timedelta(days=order.get_plan_pricing().pricing.period)
|
||||
)
|
||||
logger.info(
|
||||
f"Created new UserPlan for user {order.user} with plan {order.plan}."
|
||||
)
|
||||
else:
|
||||
# Optional: upgrade existing plan
|
||||
# user_plan = order.user.userplan
|
||||
# user_plan.plan = order.plan
|
||||
# user_plan.save()
|
||||
logger.info(f"UserPlan already exists for user {order.user}.")
|
||||
history.save(update_fields=["status"])
|
||||
return render(request, "payment_failed.html", {"message": "Invalid payment data"})
|
||||
|
||||
try:
|
||||
# Complete the order (this may generate invoice, etc.)
|
||||
order.complete_order()
|
||||
history.status = "paid"
|
||||
history.order = order # Link payment to order
|
||||
history.save()
|
||||
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
|
||||
pp = get_object_or_404(PlanPricing, pk=plan_pricing_id)
|
||||
|
||||
with transaction.atomic():
|
||||
history.refresh_from_db()
|
||||
if history.status == "paid":
|
||||
logger.info("Payment was already completed by another request. Skipping.")
|
||||
return redirect("home")
|
||||
|
||||
order = Order.objects.create(
|
||||
user=dealer.user,
|
||||
plan=pp.plan,
|
||||
pricing=pp.pricing,
|
||||
amount=pp.price,
|
||||
currency="SAR",
|
||||
tax=15,
|
||||
status=Order.STATUS.NEW,
|
||||
)
|
||||
logger.info(f"Order {order.id} created for user {dealer.user}")
|
||||
|
||||
billing_info, created = BillingInfo.objects.get_or_create(
|
||||
user=dealer.user,
|
||||
defaults={
|
||||
"tax_number": dealer.vrn,
|
||||
"name": dealer.arabic_name,
|
||||
"street": dealer.address,
|
||||
"zipcode": dealer.entity.zip_code or " ",
|
||||
"city": dealer.entity.city or " ",
|
||||
"country": dealer.entity.country or " ",
|
||||
},
|
||||
)
|
||||
|
||||
# Create UserPlan if missing
|
||||
if not hasattr(order.user, "userplan"):
|
||||
UserPlan.objects.create(
|
||||
user=order.user,
|
||||
plan=order.plan,
|
||||
)
|
||||
logger.info(f"Created new UserPlan for user {order.user} with plan {order.plan}.")
|
||||
else:
|
||||
logger.info(f"UserPlan already exists for user {order.user}.")
|
||||
|
||||
order.complete_order()
|
||||
|
||||
history.status = "paid"
|
||||
history.order = order
|
||||
history.save(update_fields=["status", "order"])
|
||||
|
||||
invoice = order.get_invoices().first()
|
||||
|
||||
logger.info(f"Order {order.id} completed. Rendering success page.")
|
||||
logger.info(f"Order {order.id} completed successfully.")
|
||||
return render(
|
||||
request, "payment_success.html", {"order": order, "invoice": invoice}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"Error completing order {order.id}: {e}")
|
||||
logger.exception(f"Error processing paid payment {payment_id}: {e}")
|
||||
# Mark as failed
|
||||
history.status = "failed"
|
||||
history.save()
|
||||
return render(
|
||||
request, "payment_failed.html", {"message": "Plan activation error"}
|
||||
)
|
||||
history.save(update_fields=["status"])
|
||||
return render(request, "payment_failed.html", {"message": "Payment processing error"})
|
||||
|
||||
finally:
|
||||
# Activate dealer & staff if needed
|
||||
if dealer := getattr(order.user, "dealer", None):
|
||||
if not dealer.user.is_active:
|
||||
dealer.user.is_active = True
|
||||
dealer.user.save()
|
||||
for staff in dealer.get_staff():
|
||||
if not staff.user.is_active:
|
||||
staff.activate_account()
|
||||
try:
|
||||
if dealer := getattr(order.user, "dealer", None):
|
||||
if not dealer.user.is_active:
|
||||
dealer.user.is_active = True
|
||||
dealer.user.save()
|
||||
for staff in dealer.get_staff():
|
||||
if not staff.user.is_active:
|
||||
staff.activate_account()
|
||||
except Exception as ex:
|
||||
logger.warning(f"Failed to activate dealer/staff: {ex}")
|
||||
|
||||
elif payment_status == "failed":
|
||||
logger.warning(
|
||||
f"Payment failed for transaction ID {payment_id}. Message: {message}"
|
||||
)
|
||||
logger.warning(f"Payment failed for transaction ID {payment_id}. Message: {message}")
|
||||
history.status = "failed"
|
||||
history.save()
|
||||
history.save(update_fields=["status"])
|
||||
return render(request, "payment_failed.html", {"message": message})
|
||||
|
||||
return render(request, "payment_failed.html", {"message": "Unknown payment status"})
|
||||
|
||||
else:
|
||||
logger.warning(f"Unknown payment status: {payment_status}")
|
||||
history.status = "failed"
|
||||
history.save(update_fields=["status"])
|
||||
return render(request, "payment_failed.html", {"message": "Unknown payment status"})
|
||||
|
||||
# @login_required
|
||||
# @permission_required("inventory.change_dealer", raise_exception=True)
|
||||
@ -11555,16 +11561,16 @@ def upload_cars(request, dealer_slug, pk=None):
|
||||
try:
|
||||
if item:
|
||||
# data = [x.strip() for x in item.item_model.name.split("||")]
|
||||
make = models.CarMake.objects.get(pk=item.addition_info.get("make"))
|
||||
model = models.CarModel.objects.get(pk=item.addition_info.get("model"))
|
||||
trim = models.CarTrim.objects.get(pk=item.addition_info.get("trim"))
|
||||
serie = models.CarSerie.objects.get(pk=item.addition_info.get("serie"))
|
||||
year = item.addition_info.get("year")
|
||||
make = models.CarMake.objects.get(pk=item.additional_info.get("make"))
|
||||
model = models.CarModel.objects.get(pk=item.additional_info.get("model"))
|
||||
trim = models.CarTrim.objects.get(pk=item.additional_info.get("trim"))
|
||||
serie = models.CarSerie.objects.get(pk=item.additional_info.get("serie"))
|
||||
year = item.additional_info.get("year")
|
||||
exterior = models.ExteriorColors.objects.get(
|
||||
pk=item.addition_info.get("exterior")
|
||||
pk=item.additional_info.get("exterior")
|
||||
)
|
||||
interior = models.InteriorColors.objects.get(
|
||||
pk=item.addition_info.get("interior")
|
||||
pk=item.additional_info.get("interior")
|
||||
)
|
||||
receiving_date = timezone.now()
|
||||
vendor_model = item.bill_model.vendor
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user