update
This commit is contained in:
parent
b44fb270fa
commit
5dee96ec09
@ -49,6 +49,7 @@ from .models import (
|
|||||||
SaleOrder,
|
SaleOrder,
|
||||||
CarMake,
|
CarMake,
|
||||||
Customer,
|
Customer,
|
||||||
|
Organization,
|
||||||
DealerSettings
|
DealerSettings
|
||||||
)
|
)
|
||||||
from django_ledger import models as ledger_models
|
from django_ledger import models as ledger_models
|
||||||
@ -242,7 +243,7 @@ class CustomerForm(forms.ModelForm):
|
|||||||
# image = forms.ImageField(required=False)
|
# image = forms.ImageField(required=False)
|
||||||
|
|
||||||
|
|
||||||
class OrganizationForm(CustomerForm):
|
class OrganizationForm(forms.ModelForm):
|
||||||
"""
|
"""
|
||||||
Represents a form for collecting and handling organization-specific details.
|
Represents a form for collecting and handling organization-specific details.
|
||||||
|
|
||||||
@ -257,8 +258,10 @@ class OrganizationForm(CustomerForm):
|
|||||||
:ivar logo: Optional field to upload the logo of the organization.
|
:ivar logo: Optional field to upload the logo of the organization.
|
||||||
:type logo: forms.ImageField
|
:type logo: forms.ImageField
|
||||||
"""
|
"""
|
||||||
contact_person = forms.CharField(required=False)
|
phone_number = SaudiPhoneNumberField(label=_('Phone Number'),required=True)
|
||||||
logo = forms.ImageField(required=False)
|
class Meta:
|
||||||
|
model = Organization
|
||||||
|
fields = ["name","arabic_name","email","phone_number","crn","vrn","address","logo"]
|
||||||
|
|
||||||
|
|
||||||
class CarForm(
|
class CarForm(
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-05-07 09:33
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'),
|
||||||
|
('inventory', '0007_customer_customer_type'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='customer',
|
||||||
|
name='customer_type',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='organization',
|
||||||
|
name='customer_model',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='django_ledger.customermodel'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='organization',
|
||||||
|
name='user',
|
||||||
|
field=models.OneToOneField(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='organization_profile', to=settings.AUTH_USER_MODEL),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
19
inventory/migrations/0009_organization_email.py
Normal file
19
inventory/migrations/0009_organization_email.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-05-07 09:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0008_remove_customer_customer_type_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='organization',
|
||||||
|
name='email',
|
||||||
|
field=models.EmailField(default='t@tenhal.sa', max_length=254, verbose_name='Email'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
18
inventory/migrations/0010_organization_active.py
Normal file
18
inventory/migrations/0010_organization_active.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-05-07 09:46
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0009_organization_email'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='organization',
|
||||||
|
name='active',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='Active'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1069,10 +1069,6 @@ class Customer(models.Model):
|
|||||||
image = models.ImageField(
|
image = models.ImageField(
|
||||||
upload_to="customers/", blank=True, null=True, verbose_name=_("Image")
|
upload_to="customers/", blank=True, null=True, verbose_name=_("Image")
|
||||||
)
|
)
|
||||||
customer_type = models.CharField(
|
|
||||||
choices=[("customer", _("Customer")),("organization", _("Organization"))], default="customer", max_length=15, verbose_name=_("Customer Type"),
|
|
||||||
null=True,blank=True
|
|
||||||
)
|
|
||||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||||
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
||||||
|
|
||||||
@ -1101,7 +1097,6 @@ class Customer(models.Model):
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
customer.additional_info.update({"customer_info": customer_dict})
|
customer.additional_info.update({"customer_info": customer_dict})
|
||||||
customer.additional_info.update({"type": "customer"})
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
customer.save()
|
customer.save()
|
||||||
@ -1123,7 +1118,6 @@ class Customer(models.Model):
|
|||||||
customer.email = self.email
|
customer.email = self.email
|
||||||
try:
|
try:
|
||||||
customer.additional_info.update({"customer_info": customer_dict})
|
customer.additional_info.update({"customer_info": customer_dict})
|
||||||
customer.additional_info.update({"type": "customer"})
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
customer.save()
|
customer.save()
|
||||||
@ -1139,17 +1133,29 @@ class Customer(models.Model):
|
|||||||
user.set_password("Tenhal@123")
|
user.set_password("Tenhal@123")
|
||||||
user.save()
|
user.save()
|
||||||
return user
|
return user
|
||||||
|
def deactivate_account(self):
|
||||||
|
self.active = False
|
||||||
|
self.customer_model.active = False
|
||||||
|
self.user.is_active = False
|
||||||
|
self.customer_model.save()
|
||||||
|
self.user.save()
|
||||||
|
self.save()
|
||||||
|
|
||||||
class Organization(models.Model, LocalizedNameMixin):
|
class Organization(models.Model, LocalizedNameMixin):
|
||||||
dealer = models.ForeignKey(
|
dealer = models.ForeignKey(
|
||||||
Dealer, on_delete=models.CASCADE, related_name="organizations"
|
Dealer, on_delete=models.CASCADE, related_name="organizations"
|
||||||
)
|
)
|
||||||
|
customer_model = models.ForeignKey(
|
||||||
|
CustomerModel, on_delete=models.SET_NULL, null=True
|
||||||
|
)
|
||||||
|
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='organization_profile')
|
||||||
name = models.CharField(max_length=255, verbose_name=_("Name"))
|
name = models.CharField(max_length=255, verbose_name=_("Name"))
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
crn = models.CharField(
|
crn = models.CharField(
|
||||||
max_length=15, verbose_name=_("Commercial Registration Number")
|
max_length=15, verbose_name=_("Commercial Registration Number")
|
||||||
)
|
)
|
||||||
vrn = models.CharField(max_length=15, verbose_name=_("VAT Registration Number"))
|
vrn = models.CharField(max_length=15, verbose_name=_("VAT Registration Number"))
|
||||||
|
email = models.EmailField(verbose_name=_("Email"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
@ -1157,6 +1163,7 @@ class Organization(models.Model, LocalizedNameMixin):
|
|||||||
logo = models.ImageField(
|
logo = models.ImageField(
|
||||||
upload_to="logos", blank=True, null=True, verbose_name=_("Logo")
|
upload_to="logos", blank=True, null=True, verbose_name=_("Logo")
|
||||||
)
|
)
|
||||||
|
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
||||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||||
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
||||||
|
|
||||||
@ -1166,7 +1173,61 @@ class Organization(models.Model, LocalizedNameMixin):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
def create_customer_model(self):
|
||||||
|
customer_dict = to_dict(self)
|
||||||
|
customer = self.dealer.entity.create_customer(
|
||||||
|
commit=False,
|
||||||
|
customer_model_kwargs={
|
||||||
|
"customer_name": self.name,
|
||||||
|
"address_1": self.address,
|
||||||
|
"phone": self.phone_number,
|
||||||
|
"email": self.email,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
customer.additional_info.update({"customer_info": customer_dict})
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
customer.save()
|
||||||
|
return customer
|
||||||
|
|
||||||
|
def update_user_model(self):
|
||||||
|
user = self.user
|
||||||
|
user.first_name = self.name
|
||||||
|
user.email = self.email
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
def update_customer_model(self):
|
||||||
|
customer_dict = to_dict(self)
|
||||||
|
customer = self.customer_model
|
||||||
|
customer.customer_name = self.name
|
||||||
|
customer.address_1 = self.address
|
||||||
|
customer.phone = self.phone_number
|
||||||
|
customer.email = self.email
|
||||||
|
try:
|
||||||
|
customer.additional_info.update({"customer_info": customer_dict})
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
customer.save()
|
||||||
|
return customer
|
||||||
|
|
||||||
|
def create_user_model(self):
|
||||||
|
user = User.objects.create_user(
|
||||||
|
username=self.email,
|
||||||
|
email=self.email,
|
||||||
|
first_name=self.name,
|
||||||
|
)
|
||||||
|
user.set_password("Tenhal@123")
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
|
||||||
|
def deactivate_account(self):
|
||||||
|
self.active = False
|
||||||
|
self.user.is_active = False
|
||||||
|
self.customer_model.active = False
|
||||||
|
self.user.save()
|
||||||
|
self.customer_model.save()
|
||||||
|
self.save()
|
||||||
|
|
||||||
class Representative(models.Model, LocalizedNameMixin):
|
class Representative(models.Model, LocalizedNameMixin):
|
||||||
dealer = models.ForeignKey(
|
dealer = models.ForeignKey(
|
||||||
|
|||||||
@ -374,7 +374,7 @@ path(
|
|||||||
"organizations/", views.OrganizationListView.as_view(), name="organization_list"
|
"organizations/", views.OrganizationListView.as_view(), name="organization_list"
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"organizations/<uuid:pk>/",
|
"organizations/<int:pk>/",
|
||||||
views.OrganizationDetailView.as_view(),
|
views.OrganizationDetailView.as_view(),
|
||||||
name="organization_detail",
|
name="organization_detail",
|
||||||
),
|
),
|
||||||
@ -384,12 +384,12 @@ path(
|
|||||||
name="organization_create",
|
name="organization_create",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"organizations/<uuid:pk>/update/",
|
"organizations/<int:pk>/update/",
|
||||||
views.OrganizationUpdateView,
|
views.OrganizationUpdateView.as_view(),
|
||||||
name="organization_update",
|
name="organization_update",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"organizations/<uuid:pk>/delete/",
|
"organizations/<int:pk>/delete/",
|
||||||
views.OrganizationDeleteView,
|
views.OrganizationDeleteView,
|
||||||
name="organization_delete",
|
name="organization_delete",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1895,7 +1895,7 @@ class CustomerListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
customers = dealer.customers.all()
|
customers = dealer.customers.filter(active=True)
|
||||||
return apply_search_filters(customers, query)
|
return apply_search_filters(customers, query)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
@ -2017,6 +2017,18 @@ def add_activity_to_customer(request, pk):
|
|||||||
|
|
||||||
|
|
||||||
class CustomerCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
class CustomerCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||||
|
"""
|
||||||
|
# Handles the creation of a new customer within the system. This view ensures that proper permissions
|
||||||
|
# and request methods are utilized. It provides feedback to the user about the success or failure of
|
||||||
|
# the customer creation process. When the form is submitted and valid, it checks for duplicate
|
||||||
|
# customers based on the email provided before proceeding with the customer creation.
|
||||||
|
|
||||||
|
# :param request: The HTTP request object containing metadata about the request initiated by the user.
|
||||||
|
# :type request: HttpRequest
|
||||||
|
# :return: The rendered form page or a redirect to the customer list page upon successful creation.
|
||||||
|
# :rtype: HttpResponse
|
||||||
|
# :raises PermissionDenied: If the user does not have the required permissions to access the view.
|
||||||
|
# """
|
||||||
model = models.Customer
|
model = models.Customer
|
||||||
form_class = forms.CustomerForm
|
form_class = forms.CustomerForm
|
||||||
permission_required = ["django_ledger.add_customermodel"]
|
permission_required = ["django_ledger.add_customermodel"]
|
||||||
@ -2035,85 +2047,8 @@ class CustomerCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView
|
|||||||
|
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
# @login_required
|
|
||||||
# @permission_required("django_ledger.add_customermodel", raise_exception=True)
|
|
||||||
# def CustomerCreateView(request):
|
|
||||||
# """
|
|
||||||
# Handles the creation of a new customer within the system. This view ensures that proper permissions
|
|
||||||
# and request methods are utilized. It provides feedback to the user about the success or failure of
|
|
||||||
# the customer creation process. When the form is submitted and valid, it checks for duplicate
|
|
||||||
# customers based on the email provided before proceeding with the customer creation.
|
|
||||||
|
|
||||||
# :param request: The HTTP request object containing metadata about the request initiated by the user.
|
|
||||||
# :type request: HttpRequest
|
|
||||||
# :return: The rendered form page or a redirect to the customer list page upon successful creation.
|
|
||||||
# :rtype: HttpResponse
|
|
||||||
# :raises PermissionDenied: If the user does not have the required permissions to access the view.
|
|
||||||
# """
|
|
||||||
# form = forms.CustomerForm()
|
|
||||||
# if request.method == "POST":
|
|
||||||
# form = forms.CustomerForm(request.POST)
|
|
||||||
# dealer = get_user_type(request)
|
|
||||||
|
|
||||||
# if form.is_valid():
|
|
||||||
# if (
|
|
||||||
# dealer.entity.get_customers()
|
|
||||||
# .filter(email=form.cleaned_data["email"])
|
|
||||||
# .exists()
|
|
||||||
# ):
|
|
||||||
# messages.error(request, _("Customer with this email already exists"))
|
|
||||||
# else:
|
|
||||||
# customer_name = (
|
|
||||||
# f"{form.cleaned_data['first_name']} "
|
|
||||||
# f"{form.cleaned_data['last_name']}"
|
|
||||||
# )
|
|
||||||
# customer_dict = {
|
|
||||||
# x: request.POST[x]
|
|
||||||
# for x in request.POST
|
|
||||||
# if x != "csrfmiddlewaretoken"
|
|
||||||
# }
|
|
||||||
# try:
|
|
||||||
# customer = dealer.entity.create_customer(
|
|
||||||
# commit=False,
|
|
||||||
# customer_model_kwargs={
|
|
||||||
# "customer_name": customer_name,
|
|
||||||
# "address_1": form.cleaned_data["address"],
|
|
||||||
# "phone": form.cleaned_data["phone_number"],
|
|
||||||
# "email": form.cleaned_data["email"],
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
# customer.additional_info.update({"customer_info": customer_dict})
|
|
||||||
# customer.additional_info.update({"type": "customer"})
|
|
||||||
# customer.save()
|
|
||||||
|
|
||||||
# messages.success(request, _("Customer created successfully"))
|
|
||||||
# return redirect("customer_list")
|
|
||||||
|
|
||||||
# except Exception as e:
|
|
||||||
# messages.error(request, _(f"An error occurred: {str(e)}"))
|
|
||||||
# else:
|
|
||||||
# messages.error(request, _("Please correct the errors below"))
|
|
||||||
|
|
||||||
# return render(request, "customers/customer_form.html", {"form": form})
|
|
||||||
|
|
||||||
|
|
||||||
class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||||
model = models.Customer
|
"""
|
||||||
form_class = forms.CustomerForm
|
|
||||||
permission_required = ["django_ledger.change_customermodel"]
|
|
||||||
template_name = "customers/customer_form.html"
|
|
||||||
success_url = reverse_lazy("customer_list")
|
|
||||||
success_message = "Customer updated successfully"
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.instance.update_user_model()
|
|
||||||
form.instance.update_customer_model()
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
# @login_required
|
|
||||||
# @permission_required("django_ledger.change_customermodel", raise_exception=True)
|
|
||||||
# def CustomerUpdateView(request, pk):
|
|
||||||
# """
|
|
||||||
# Updates the details of an existing customer in the database. This view is
|
# Updates the details of an existing customer in the database. This view is
|
||||||
# accessible only to logged-in users with the appropriate permissions. It
|
# accessible only to logged-in users with the appropriate permissions. It
|
||||||
# handles both GET (form rendering with pre-filled customer data) and POST
|
# handles both GET (form rendering with pre-filled customer data) and POST
|
||||||
@ -2135,44 +2070,17 @@ class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView
|
|||||||
# returns the rendered form template with the validation errors.
|
# returns the rendered form template with the validation errors.
|
||||||
# :rtype: HttpResponse
|
# :rtype: HttpResponse
|
||||||
# """
|
# """
|
||||||
# customer = get_object_or_404(CustomerModel, pk=pk)
|
model = models.Customer
|
||||||
# if request.method == "POST":
|
form_class = forms.CustomerForm
|
||||||
# # form = forms.CustomerForm(request.POST, instance=customer)
|
permission_required = ["django_ledger.change_customermodel"]
|
||||||
# customer_dict = {
|
template_name = "customers/customer_form.html"
|
||||||
# x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
success_url = reverse_lazy("customer_list")
|
||||||
# }
|
success_message = "Customer updated successfully"
|
||||||
# dealer = get_user_type(request)
|
|
||||||
# customer_name = customer_dict["first_name"] + " " + customer_dict["last_name"]
|
|
||||||
|
|
||||||
# instance = dealer.entity.get_customers().get(pk=pk)
|
def form_valid(self, form):
|
||||||
# instance.customer_name = customer_name
|
form.instance.update_user_model()
|
||||||
# instance.address_1 = customer_dict["address"]
|
form.instance.update_customer_model()
|
||||||
# instance.phone = customer_dict["phone_number"]
|
return super().form_valid(form)
|
||||||
# instance.email = customer_dict["email"]
|
|
||||||
|
|
||||||
# customer_dict["pk"] = str(instance.pk)
|
|
||||||
# instance.additional_info.update({"customer_info": customer_dict})
|
|
||||||
# try:
|
|
||||||
# user = User.objects.filter(
|
|
||||||
# pk=int(instance.additional_info["user_info"]["id"])
|
|
||||||
# ).first()
|
|
||||||
# if user:
|
|
||||||
# user.username = customer_dict["email"]
|
|
||||||
# user.email = customer_dict["email"]
|
|
||||||
# user.save()
|
|
||||||
# except Exception as e:
|
|
||||||
# raise Exception(e)
|
|
||||||
|
|
||||||
# instance.save()
|
|
||||||
# messages.success(request, _("Customer updated successfully"))
|
|
||||||
# return redirect("customer_list")
|
|
||||||
# else:
|
|
||||||
# form = forms.CustomerForm(
|
|
||||||
# initial=customer.additional_info["customer_info"]
|
|
||||||
# if "customer_info" in customer.additional_info
|
|
||||||
# else {}
|
|
||||||
# )
|
|
||||||
# return render(request, "customers/customer_form.html", {"form": form})
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -2193,15 +2101,8 @@ def delete_customer(request, pk):
|
|||||||
:rtype: HttpResponseRedirect
|
:rtype: HttpResponseRedirect
|
||||||
"""
|
"""
|
||||||
customer = get_object_or_404(models.Customer, pk=pk)
|
customer = get_object_or_404(models.Customer, pk=pk)
|
||||||
customer_model = customer.customer_model
|
customer.deactivate_account()
|
||||||
user = customer.user
|
messages.success(request, _("Customer deactivated successfully"))
|
||||||
customer.active = False
|
|
||||||
customer_model.active = False
|
|
||||||
user.is_active = False
|
|
||||||
customer.save()
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
messages.success(request, _("Customer deleted successfully"))
|
|
||||||
return redirect("customer_list")
|
return redirect("customer_list")
|
||||||
|
|
||||||
|
|
||||||
@ -2371,8 +2272,9 @@ def delete_vendor(request, pk):
|
|||||||
:rtype: HttpResponseRedirect
|
:rtype: HttpResponseRedirect
|
||||||
"""
|
"""
|
||||||
vendor = get_object_or_404(models.Vendor, pk=pk)
|
vendor = get_object_or_404(models.Vendor, pk=pk)
|
||||||
# vendor.active = False
|
vendor.active = False
|
||||||
vendor.delete()
|
vendor.vendor_model.active = False
|
||||||
|
vendor.save()
|
||||||
messages.success(request, _("Vendor deleted successfully"))
|
messages.success(request, _("Vendor deleted successfully"))
|
||||||
return redirect("vendor_list")
|
return redirect("vendor_list")
|
||||||
|
|
||||||
@ -2832,7 +2734,7 @@ class OrganizationListView(LoginRequiredMixin, ListView):
|
|||||||
:ivar paginate_by: The number of organizations displayed per page.
|
:ivar paginate_by: The number of organizations displayed per page.
|
||||||
:type paginate_by: int
|
:type paginate_by: int
|
||||||
"""
|
"""
|
||||||
model = CustomerModel
|
model = models.Organization
|
||||||
template_name = "organizations/organization_list.html"
|
template_name = "organizations/organization_list.html"
|
||||||
context_object_name = "organizations"
|
context_object_name = "organizations"
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
@ -2840,9 +2742,7 @@ class OrganizationListView(LoginRequiredMixin, ListView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
organization = dealer.entity.get_customers().filter(
|
organization = dealer.organizations.filter(active=True)
|
||||||
additional_info__type="organization", active=True
|
|
||||||
)
|
|
||||||
|
|
||||||
return apply_search_filters(organization, query)
|
return apply_search_filters(organization, query)
|
||||||
|
|
||||||
@ -2865,32 +2765,13 @@ class OrganizationDetailView(LoginRequiredMixin, DetailView):
|
|||||||
template for accessing the organization's data.
|
template for accessing the organization's data.
|
||||||
:type context_object_name: str
|
:type context_object_name: str
|
||||||
"""
|
"""
|
||||||
model = CustomerModel
|
model = models.Organization
|
||||||
template_name = "organizations/organization_detail.html"
|
template_name = "organizations/organization_detail.html"
|
||||||
context_object_name = "organization"
|
context_object_name = "organization"
|
||||||
|
|
||||||
|
|
||||||
class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||||
model = models.Organization
|
"""
|
||||||
form_class = forms.OrganizationForm
|
|
||||||
permission_required = ["django_ledger.add_customermodel"]
|
|
||||||
template_name = "customers/organization_form.html"
|
|
||||||
success_url = reverse_lazy("organization_list")
|
|
||||||
success_message = "Customer created successfully"
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
dealer = get_user_type(self.request)
|
|
||||||
form.instance.dealer = dealer
|
|
||||||
user = form.instance.create_user_model()
|
|
||||||
customer = form.instance.create_customer_model()
|
|
||||||
form.instance.customer_type = 'organization'
|
|
||||||
form.instance.user = user
|
|
||||||
form.instance.customer_model = customer
|
|
||||||
|
|
||||||
return super().form_valid(form)
|
|
||||||
# @login_required
|
|
||||||
# def OrganizationCreateView(request):
|
|
||||||
# """
|
|
||||||
# Handles the creation of a new organization via a web form. This view allows the
|
# Handles the creation of a new organization via a web form. This view allows the
|
||||||
# authenticated user to submit data for creating an organization. If a POST request
|
# authenticated user to submit data for creating an organization. If a POST request
|
||||||
# is received, it validates the data, checks for duplicate organizations, and
|
# is received, it validates the data, checks for duplicate organizations, and
|
||||||
@ -2904,110 +2785,52 @@ class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, Create
|
|||||||
# redirecting the user after a successful creation.
|
# redirecting the user after a successful creation.
|
||||||
# :rtype: HttpResponse
|
# :rtype: HttpResponse
|
||||||
# """
|
# """
|
||||||
# if request.method == "POST":
|
model = models.Organization
|
||||||
# form = forms.OrganizationForm(request.POST)
|
form_class = forms.OrganizationForm
|
||||||
# if CustomerModel.objects.filter(email=request.POST["email"]).exists():
|
permission_required = ["django_ledger.add_customermodel"]
|
||||||
# messages.error(
|
template_name = "organizations/organization_form.html"
|
||||||
# request, _("An organization with this email already exists.")
|
success_url = reverse_lazy("organization_list")
|
||||||
# )
|
success_message = "Organization created successfully"
|
||||||
# return redirect("organization_create")
|
|
||||||
|
|
||||||
# organization_dict = {
|
def form_valid(self, form):
|
||||||
# x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
dealer = get_user_type(self.request)
|
||||||
# }
|
form.instance.dealer = dealer
|
||||||
# dealer = get_user_type(request)
|
user = form.instance.create_user_model()
|
||||||
# name = organization_dict["first_name"] + " " + organization_dict["last_name"]
|
customer = form.instance.create_customer_model()
|
||||||
# customer = dealer.entity.create_customer(
|
form.instance.user = user
|
||||||
# commit=False,
|
form.instance.customer_model = customer
|
||||||
# customer_model_kwargs={
|
|
||||||
# "customer_name": name,
|
|
||||||
# "address_1": organization_dict["address"],
|
|
||||||
# "phone": organization_dict["phone_number"],
|
|
||||||
# "email": organization_dict["email"],
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
# image = request.FILES.get("logo")
|
|
||||||
# if image:
|
|
||||||
# file_name = default_storage.save("images/{}".format(image.name), image)
|
|
||||||
# file_url = default_storage.url(file_name)
|
|
||||||
|
|
||||||
# organization_dict["logo"] = file_url
|
return super().form_valid(form)
|
||||||
# organization_dict["pk"] = str(customer.pk)
|
|
||||||
# customer.additional_info.update({"customer_info": organization_dict})
|
|
||||||
# customer.additional_info.update({"type": "organization"})
|
|
||||||
# customer.save()
|
|
||||||
# messages.success(request, _("Organization created successfully"))
|
|
||||||
# return redirect("organization_list")
|
|
||||||
# else:
|
|
||||||
# form = forms.OrganizationForm()
|
|
||||||
# return render(request, "organizations/organization_form.html", {"form": form})
|
|
||||||
|
|
||||||
|
class OrganizationUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
|
||||||
@login_required
|
|
||||||
def OrganizationUpdateView(request, pk):
|
|
||||||
"""
|
"""
|
||||||
Handles the update of an organization instance. This view fetches the organization
|
# Handles the update of an organization instance. This view fetches the organization
|
||||||
based on the provided primary key (pk) and renders a form for editing the
|
# based on the provided primary key (pk) and renders a form for editing the
|
||||||
organization attributes. When a POST request is made, this view validates and
|
# organization attributes. When a POST request is made, this view validates and
|
||||||
processes the form data, updates the organization instance, and saves the changes.
|
# processes the form data, updates the organization instance, and saves the changes.
|
||||||
If the request method is not POST, it initializes the form with existing organization
|
# If the request method is not POST, it initializes the form with existing organization
|
||||||
data for rendering.
|
# data for rendering.
|
||||||
|
|
||||||
:param request: The HTTP request object. Must be authenticated via login.
|
# :param request: The HTTP request object. Must be authenticated via login.
|
||||||
:type request: HttpRequest
|
# :type request: HttpRequest
|
||||||
:param pk: The primary key of the organization to be updated.
|
# :param pk: The primary key of the organization to be updated.
|
||||||
:type pk: int
|
# :type pk: int
|
||||||
:return: An HTTP response object. Either renders the organization form or redirects
|
# :return: An HTTP response object. Either renders the organization form or redirects
|
||||||
to the organization list upon successful update.
|
# to the organization list upon successful update.
|
||||||
:rtype: HttpResponse
|
# :rtype: HttpResponse
|
||||||
"""
|
# """
|
||||||
organization = get_object_or_404(CustomerModel, pk=pk)
|
model = models.Organization
|
||||||
if request.method == "POST":
|
form_class = forms.OrganizationForm
|
||||||
form = forms.OrganizationForm(request.POST)
|
permission_required = ["django_ledger.change_customermodel"]
|
||||||
|
template_name = "organizations/organization_form.html"
|
||||||
|
success_url = reverse_lazy("organization_list")
|
||||||
|
success_message = "Organization updated successfully"
|
||||||
|
|
||||||
organization_dict = {
|
def form_valid(self, form):
|
||||||
x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
form.instance.update_user_model()
|
||||||
}
|
form.instance.update_customer_model()
|
||||||
dealer = get_user_type(request)
|
return super().form_valid(form)
|
||||||
|
|
||||||
instance = dealer.entity.get_customers().get(
|
|
||||||
pk=organization.additional_info["customer_info"]["pk"]
|
|
||||||
)
|
|
||||||
name = organization_dict["first_name"] + " " + organization_dict["last_name"]
|
|
||||||
instance.customer_name = name
|
|
||||||
instance.address_1 = organization_dict["address"]
|
|
||||||
instance.phone = organization_dict["phone_number"]
|
|
||||||
instance.email = organization_dict["email"]
|
|
||||||
|
|
||||||
image = request.FILES.get("logo")
|
|
||||||
if image:
|
|
||||||
file_name = default_storage.save("images/{}".format(image.name), image)
|
|
||||||
file_url = default_storage.url(file_name)
|
|
||||||
organization_dict["logo"] = file_url
|
|
||||||
else:
|
|
||||||
organization_dict["logo"] = organization.additional_info["customer_info"][
|
|
||||||
"logo"
|
|
||||||
]
|
|
||||||
|
|
||||||
organization_dict["pk"] = str(instance.pk)
|
|
||||||
instance.additional_info["customer_info"] = organization_dict
|
|
||||||
instance.additional_info["type"] = "organization"
|
|
||||||
instance.save()
|
|
||||||
messages.success(request, _("Organization created successfully"))
|
|
||||||
return redirect("organization_list")
|
|
||||||
else:
|
|
||||||
form = forms.OrganizationForm(
|
|
||||||
initial=organization.additional_info["customer_info"] or {}
|
|
||||||
)
|
|
||||||
# form.fields.pop("logo", None)
|
|
||||||
return render(request, "organizations/organization_form.html", {"form": form})
|
|
||||||
|
|
||||||
|
|
||||||
# class OrganizationDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
|
|
||||||
# model = models.Organization
|
|
||||||
# template_name = "organizations/organization_confirm_delete.html"
|
|
||||||
# success_url = reverse_lazy("organization_list")
|
|
||||||
# success_message = "Organization deleted successfully."
|
|
||||||
@login_required
|
@login_required
|
||||||
def OrganizationDeleteView(request, pk):
|
def OrganizationDeleteView(request, pk):
|
||||||
"""
|
"""
|
||||||
@ -3023,14 +2846,9 @@ def OrganizationDeleteView(request, pk):
|
|||||||
:return: An HTTP response redirecting to the organization list view.
|
:return: An HTTP response redirecting to the organization list view.
|
||||||
:rtype: HttpResponseRedirect
|
:rtype: HttpResponseRedirect
|
||||||
"""
|
"""
|
||||||
organization = get_object_or_404(CustomerModel, pk=pk)
|
organization = get_object_or_404(models.Organization, pk=pk)
|
||||||
try:
|
organization.deactivate_account()
|
||||||
User.objects.get(email=organization.email).delete()
|
messages.success(request, _("Organization Deactivated successfully"))
|
||||||
organization.delete()
|
|
||||||
messages.success(request, _("Organization deleted successfully"))
|
|
||||||
except Exception as e:
|
|
||||||
print("unable to delete user", e)
|
|
||||||
messages.error(request, _("Unable to delete organization"))
|
|
||||||
return redirect("organization_list")
|
return redirect("organization_list")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
<div class="row my-4">
|
<div class="row my-4">
|
||||||
<h2>{{ organization.get_local_name }}</h2>
|
<h2>{{ organization.get_local_name }}</h2>
|
||||||
<ul class="list-group mb-4">
|
<ul class="list-group mb-4">
|
||||||
<li class="list-group-item"><strong>{% trans "CRN" %}:</strong> {{ organization.additional_info.customer_info.crn }}</li>
|
<li class="list-group-item"><strong>{% trans "CRN" %}:</strong> {{ organization.crn }}</li>
|
||||||
<li class="list-group-item"><strong>{% trans "VRN" %}:</strong> {{ organization.additional_info.customer_info.vrn }}</li>
|
<li class="list-group-item"><strong>{% trans "VRN" %}:</strong> {{ organization.vrn }}</li>
|
||||||
<li class="list-group-item"><strong>{% trans "Phone" %}:</strong> {{ organization.additional_info.customer_info.phone_number }}</li>
|
<li class="list-group-item"><strong>{% trans "Phone" %}:</strong> {{ organization.phone_number }}</li>
|
||||||
<li class="list-group-item"><strong>{% trans "Address" %}:</strong> {{ organization.additional_info.customer_info.address }}</li>
|
<li class="list-group-item"><strong>{% trans "Address" %}:</strong> {{ organization.address }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a href="{% url 'organization_update' organization.pk %}" class="btn btn-sm btn-warning me-2">{% trans "Edit" %}</a>
|
<a href="{% url 'organization_update' organization.pk %}" class="btn btn-sm btn-warning me-2">{% trans "Edit" %}</a>
|
||||||
|
|||||||
@ -102,19 +102,19 @@
|
|||||||
<td class="name align-middle white-space-nowrap ps-0">
|
<td class="name align-middle white-space-nowrap ps-0">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div>
|
<div>
|
||||||
<a class="fs-8 fw-bold" href="{% url 'organization_detail' org.pk %}">{{ org.customer_name }}</a>
|
<a class="fs-8 fw-bold" href="{% url 'organization_detail' org.pk %}">{{ org.name }}</a>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2"></p><span class="badge badge-phoenix badge-phoenix-primary">{{ org.customer_name }}</span>
|
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2"></p><span class="badge badge-phoenix badge-phoenix-primary">{{ org.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.additional_info.customer_info.crn }}</td>
|
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.crn }}</td>
|
||||||
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.additional_info.customer_info.vrn }}</td>
|
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.vrn }}</td>
|
||||||
<td class="phone align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight">
|
<td class="phone align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight">
|
||||||
<a class="text-body-highlight" href="tel:{{ org.phone }}">{{ org.phone }}</a>
|
<a class="text-body-highlight" href="tel:{{ org.phone }}">{{ org.phone_number }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ org.address_1 }}</td>
|
<td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ org.address }}</td>
|
||||||
<td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ org.created|date }}</td>
|
<td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ org.created|date }}</td>
|
||||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
||||||
{% if perms.django_ledger.change_customermodel %}
|
{% if perms.django_ledger.change_customermodel %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user