diff --git a/.DS_Store b/.DS_Store index 684dd60e..72284900 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/osinaweb/.DS_Store b/osinaweb/.DS_Store index f2c79ec6..ffeaec15 100644 Binary files a/osinaweb/.DS_Store and b/osinaweb/.DS_Store differ diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 53532138..e1deaf01 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/__pycache__/forms.cpython-310.pyc b/osinaweb/osinacore/__pycache__/forms.cpython-310.pyc index 549af602..e3e7e983 100644 Binary files a/osinaweb/osinacore/__pycache__/forms.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/forms.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc index 1127e532..dafa1b1a 100644 Binary files a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc index 453de335..24f8e941 100644 Binary files a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/osinacore/forms.py b/osinaweb/osinacore/forms.py index e2f9167d..86958069 100644 --- a/osinaweb/osinacore/forms.py +++ b/osinaweb/osinacore/forms.py @@ -1,7 +1,13 @@ from django import forms +from .models import * class CustomLoginForm(forms.Form): username = forms.CharField(label='Username', max_length=150) password = forms.CharField(label='Password', widget=forms.PasswordInput) + +class SignUpForm(forms.ModelForm): + class Meta: + model = CustomerProfile + fields = ['first_name', 'last_name', 'email', 'password', 'mobile_number', 'status', 'reference', 'personal_website', 'business'] diff --git a/osinaweb/osinacore/migrations/0021_alter_customerprofile_business_and_more.py b/osinaweb/osinacore/migrations/0021_alter_customerprofile_business_and_more.py new file mode 100644 index 00000000..1f38cd4b --- /dev/null +++ b/osinaweb/osinacore/migrations/0021_alter_customerprofile_business_and_more.py @@ -0,0 +1,66 @@ +# Generated by Django 4.2.5 on 2023-09-16 11:04 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('osinacore', '0020_task'), + ] + + operations = [ + migrations.AlterField( + model_name='customerprofile', + name='business', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.business'), + ), + migrations.AlterField( + model_name='customerprofile', + name='email', + field=models.EmailField(blank=True, max_length=254, unique=True), + ), + migrations.AlterField( + model_name='customerprofile', + name='first_name', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AlterField( + model_name='customerprofile', + name='last_name', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AlterField( + model_name='customerprofile', + name='mobile_number', + field=models.CharField(blank=True, max_length=50), + ), + migrations.AlterField( + model_name='customerprofile', + name='password', + field=models.CharField(blank=True, max_length=128), + ), + migrations.AlterField( + model_name='customerprofile', + name='personal_website', + field=models.URLField(blank=True, null=True), + ), + migrations.AlterField( + model_name='customerprofile', + name='reference', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.reference'), + ), + migrations.AlterField( + model_name='customerprofile', + name='status', + field=models.CharField(blank=True, choices=[('Active', 'Active'), ('Suspended', 'Suspended'), ('Terminated', 'Terminated')], max_length=200), + ), + migrations.AlterField( + model_name='customerprofile', + name='user', + field=models.OneToOneField(blank=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/osinaweb/osinacore/migrations/0022_customerprofile_customer_id.py b/osinaweb/osinacore/migrations/0022_customerprofile_customer_id.py new file mode 100644 index 00000000..1d748af9 --- /dev/null +++ b/osinaweb/osinacore/migrations/0022_customerprofile_customer_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2023-09-17 18:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0021_alter_customerprofile_business_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='customerprofile', + name='customer_id', + field=models.CharField(blank=True, max_length=20, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0023_task_assigned_to.py b/osinaweb/osinacore/migrations/0023_task_assigned_to.py new file mode 100644 index 00000000..9d20057c --- /dev/null +++ b/osinaweb/osinacore/migrations/0023_task_assigned_to.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2023-09-17 18:56 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0022_customerprofile_customer_id'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='assigned_to', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.staffprofile'), + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0021_alter_customerprofile_business_and_more.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0021_alter_customerprofile_business_and_more.cpython-310.pyc new file mode 100644 index 00000000..a5a5b850 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0021_alter_customerprofile_business_and_more.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0022_customerprofile_customer_id.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0022_customerprofile_customer_id.cpython-310.pyc new file mode 100644 index 00000000..54871730 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0022_customerprofile_customer_id.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0023_task_assigned_to.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0023_task_assigned_to.cpython-310.pyc new file mode 100644 index 00000000..65e492cd Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0023_task_assigned_to.cpython-310.pyc differ diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index 08bdc19a..f1cf7b41 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -8,6 +8,9 @@ from datetime import datetime class Reference(models.Model): name = models.CharField(max_length=50) date = models.DateField(blank=True) + def __str__(self): + return self.name + class Business(models.Model): @@ -34,27 +37,41 @@ class Business(models.Model): logo = models.ImageField() class Meta: verbose_name_plural = u'Businesses' + def __str__(self): + return self.name class CustomerProfile(models.Model): - user = models.OneToOneField(User, on_delete=models.CASCADE) - first_name = models.CharField(max_length=50) - last_name = models.CharField(max_length=50) - email = models.EmailField(unique=True) - mobile_number = models.CharField(max_length=50) - password = models.CharField(max_length=128) - personal_website = models.URLField(null=True) + user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True) + first_name = models.CharField(max_length=50, blank=True) + last_name = models.CharField(max_length=50, blank=True) + email = models.EmailField(unique=True,blank=True) + mobile_number = models.CharField(max_length=50, blank=True) + password = models.CharField(max_length=128, blank=True) + personal_website = models.URLField(null=True, blank=True) STATUS_CHOICES = ( ('Active', 'Active'), ('Suspended', 'Suspended'), ('Terminated', 'Terminated'), ) - status = models.CharField(max_length=200, choices=STATUS_CHOICES) - reference = models.ForeignKey(Reference, on_delete=models.CASCADE, null=True) - business = models.ForeignKey(Business, on_delete=models.CASCADE, null=True) + status = models.CharField(max_length=200, choices=STATUS_CHOICES, blank=True) + reference = models.ForeignKey(Reference, on_delete=models.CASCADE, null=True, blank=True) + business = models.ForeignKey(Business, on_delete=models.CASCADE, null=True, blank=True) + customer_id = models.CharField(max_length=20, null=True, blank=True) def __str__(self): return self.user.username + def save(self, *args, **kwargs): + if not self.customer_id: + # Get the last two digits of the current year + current_year = str(datetime.now().year)[-2:] + # Find the maximum project ID in the database and increment it + max_id = CustomerProfile.objects.aggregate(models.Max('customer_id'))['customer_id__max'] + new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001' + self.customer_id = current_year + new_id # Add 'p' prefix + super(CustomerProfile, self).save(*args, **kwargs) + + @@ -174,5 +191,4 @@ class Task(models.Model): description = models.TextField() start_date = models.CharField(max_length=200) end_date = models.CharField(max_length=200) - - \ No newline at end of file + assigned_to = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True) \ No newline at end of file diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index ff2b91e5..5f71adad 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -85,8 +85,10 @@ def my_tasks(request, *args, **kwargs): @login_required def customers(request, *args, **kwargs): + customers = CustomerProfile.objects.all().order_by('-id') context = { + 'customers' : customers, } return render(request, 'customers.html', context) @@ -161,21 +163,30 @@ def createtask_epic(request): @login_required def add_customer(request): - context = { + businesses = Business.objects.all().order_by('-id') + references = Reference.objects.all().order_by('-id') + context = { + 'businesses' : businesses, + 'references' :references } return render(request, 'add-customer.html', context) @login_required -def customerdetails(request): - context = { +def customerdetails(request, customer_id): + customer = get_object_or_404(CustomerProfile, customer_id=customer_id) + context = { + 'customer' : customer, } return render(request, 'customer-details.html', context) + @login_required def addbusiness(request): - context = { + + context = { + } return render(request, 'add-business.html', context) @@ -191,6 +202,7 @@ def businessdetails(request): + # Modals views def add_note_modal(request, *args, **kwargs): @@ -412,4 +424,70 @@ def save_task(request): # Redirect to the detailed project page redirect_url = reverse('detailed-project', args=[project.project_id]) - return redirect(redirect_url) \ No newline at end of file + return redirect(redirect_url) + + + +@login_required +def save_business(request): + if request.method == 'POST': + name = request.POST.get('name') + email= request.POST.get('email') + financial_number = request.POST.get('financial_number') + phone_number = request.POST.get('phone_number') + vat = request.POST.get('vat') + commercial_registration = request.POST.get('commercial_registration') + website = request.POST.get('website') + business_type = request.POST.get('business_type') + logo = request.POST.get('logo') + + business = Business( + name = name, + email = email, + financial_number = financial_number, + vat = vat, + commercial_registration = commercial_registration, + website = website, + business_type = business_type, + logo = logo, + phone_number = phone_number, + ) + business.save() + + + + return render(request, 'add-business.html') + + +def save_customer(request): + if request.method == 'POST': + form = SignUpForm(request.POST) + if form.is_valid(): + email = form.cleaned_data['email'] + first_name = form.cleaned_data['first_name'].replace(" ", "") # Remove spaces + last_name = form.cleaned_data['last_name'].replace(" ", "") # Remove spaces + + username = f"{first_name.lower()}{last_name.lower()}" + original_username = username + counter = 1 # Initialize a counter to add numbers + + while User.objects.filter(username=username).exists(): + # If the username already exists, append the counter to it + username = f"{original_username.lower()}{counter}" + counter += 1 + + user = User.objects.create_user( + username=username, + email=email, + password=form.cleaned_data['password'] + ) + user.first_name = form.cleaned_data['first_name'] + user.last_name = form.cleaned_data['last_name'] + user.save() + + customer_profile = form.save(commit=False) + customer_profile.user = user + customer_profile.save() + + return redirect('customers') + diff --git a/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc index f54119c6..c61ce4f3 100644 Binary files a/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc and b/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/urls.py b/osinaweb/osinaweb/urls.py index 0beaf0d1..09e4ff39 100644 --- a/osinaweb/osinaweb/urls.py +++ b/osinaweb/osinaweb/urls.py @@ -28,10 +28,10 @@ urlpatterns = [ path('my-tasks/', login_required(views.my_tasks), name='my-tasks'), path('customers/', views.customers, name='customers'), path('addcustomer/', views.add_customer, name='addcustomer'), - path('customerdetails/', views.customerdetails, name='customerdetails'), + path('customerdetails//', views.customerdetails, name='customerdetails'), path('addbusiness/', views.addbusiness, name='addbusiness'), path('businessdetails/', views.businessdetails, name='businessdetails'), - path('detailedproject//', views.detailed_project, name='detailed-project'), + path('projectdetails//', views.detailed_project, name='detailed-project'), path('createproject/', views.create_project, name='createproject'), path('createepic//', views.create_epic, name='createepic'), path('createtask/', views.create_task, name='createtask'), @@ -56,4 +56,6 @@ urlpatterns = [ path('save_project/', views.save_project, name='save_project'), path('save_epic/', views.save_epic, name='save_epic'), path('save_task/', views.save_task, name='save_task'), + path('save_business/', views.save_business, name='save_business'), + path('save_customer/', views.save_customer, name='save_customer'), ] diff --git a/osinaweb/templates/add-business.html b/osinaweb/templates/add-business.html index 10d65a1d..b4b3a18c 100644 --- a/osinaweb/templates/add-business.html +++ b/osinaweb/templates/add-business.html @@ -9,75 +9,95 @@

Add Business

-
-
- - -
-
- - Upload - Business - Logo - - -
-
+ + {% csrf_token %} + + +
+
+ + Upload Business + Logo + - - - - - - - -
- -
+
- - - - - - - - - -
- -
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + +
+
diff --git a/osinaweb/templates/add-customer.html b/osinaweb/templates/add-customer.html index 9f11fd1f..1d959630 100644 --- a/osinaweb/templates/add-customer.html +++ b/osinaweb/templates/add-customer.html @@ -9,46 +9,40 @@

Add Customer

-
+ + {% csrf_token %}
- - - - - - - - - - -
-
- - Upload Business - Logo - - -
-
- - - - - - - - -
- - -
- - - - - - - - - - -
- -
- -
+
+ + +
@@ -158,9 +84,11 @@ }); +
-
diff --git a/osinaweb/templates/customer-details.html b/osinaweb/templates/customer-details.html index aa435048..878907fc 100644 --- a/osinaweb/templates/customer-details.html +++ b/osinaweb/templates/customer-details.html @@ -57,9 +57,24 @@
-
-

Emile Elliye

+ {% if customer.status == 'Active' %} +
+

{{customer.first_name}} {{customer.last_name}}

+

{{customer.customer_id}}

+ {% endif %} + {% if customer.status == 'Suspended' %} +
+

{{customer.first_name}} {{customer.last_name}}

+

{{customer.customer_id}}

+
+ {% endif %} + {% if customer.status == 'Terminated' %} +
+

{{customer.first_name}} {{customer.last_name}}

+

{{customer.customer_id}}

+
+ {% endif %}
+ + {% if customer.business %}

Business:

@@ -129,13 +166,13 @@
-

Ositcom

+

{{customer.business.name}}

-

Associations

+

{{customer.business.business_type}}

-

2567776

+

{{customer.business.financial_number}}

- +
+ {% endif %} +
@@ -273,40 +307,6 @@
- -
-
-
-
-
- user profile -
-
-

Nataly

-

11:30 AM

-
-
-
- -
-
- - -
-

Closed - Create the Osina home page

-
- - -
- - -
-
-
diff --git a/osinaweb/templates/customers.html b/osinaweb/templates/customers.html index 3b691365..12cab0f5 100644 --- a/osinaweb/templates/customers.html +++ b/osinaweb/templates/customers.html @@ -107,191 +107,41 @@
+ {% for customer in customers %}
-

Nataly

+

{{customer.first_name}}

-

Abi Wajeh

+

{{customer.last_name}}

-

nataly.aw

+

{{customer.user.username}}

+ {% if customer.status == 'Active' %}
-

Active

-
-
-

Business

-
-
- -
- -
-
-
- -
-
- -
-
-
- - -
-
-

Rachel

-
-
-

Hanna

-
-
-

-

+

{{customer.status}}

+ {% endif %} + {% if customer.status == 'Terminated' %}
-

Terminated

-
-
-

-

-
-
- -
- -
-
-
- -
-
- -
-
-
- - -
-
-

Aya

-
-
-

Rifai

-
-
-

aya.rf

+

{{customer.status}}

+ {% endif %} + {% if customer.status == 'Suspended' %}
-

Suspended

-
-
-

-

-
-
- -
- -
-
-
- -
-
- -
-
-
- - -
-
-

Emile

-
-
-

Elliye

-
-
-

salim.e

-
-
-

Active

-
-
-

Business

-
-
- -
- -
-
-
- -
-
- -
-
-
- - -
-
-

Emilio

+

{{customer.status}}

+ {% endif %}
-

Emilio

-
-
-

-

-
-
-

Terminated

-
-
-

Cars and Classics

-
-
- -
- -
-
-
- -
-
- -
-
-
- - -
-
-

Arze

-
-
-

Elliye

-
-
-

Arze.e

-
-
-

Active

-
-
-

-

+

{{customer.business}}

+ {% endfor %} - - @@ -454,40 +273,7 @@ - -
-
-
-
-
- user profile -
-
-

Nataly

-

11:30 AM

-
-
-
- -
-
- - -
-

Closed - Create the Osina home page

-
- - -
- - -
-
-
+ diff --git a/osinaweb/templates/project-details.html b/osinaweb/templates/project-details.html index 9e4120ab..c08da322 100644 --- a/osinaweb/templates/project-details.html +++ b/osinaweb/templates/project-details.html @@ -370,6 +370,8 @@

Related Tasks:

+ + {% for task in tasks %}
@@ -462,6 +464,7 @@
+ {% endfor %}