diff --git a/.DS_Store b/.DS_Store index 2e450c13..cb86c58a 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/osinaweb/.DS_Store b/osinaweb/.DS_Store index c78a0b7c..e94e763c 100644 Binary files a/osinaweb/.DS_Store and b/osinaweb/.DS_Store differ diff --git a/osinaweb/addressbook/__init__.py b/osinaweb/addressbook/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/osinaweb/addressbook/__pycache__/__init__.cpython-310.pyc b/osinaweb/addressbook/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..69a70c7c Binary files /dev/null and b/osinaweb/addressbook/__pycache__/__init__.cpython-310.pyc differ diff --git a/osinaweb/addressbook/__pycache__/admin.cpython-310.pyc b/osinaweb/addressbook/__pycache__/admin.cpython-310.pyc new file mode 100644 index 00000000..276ee2d7 Binary files /dev/null and b/osinaweb/addressbook/__pycache__/admin.cpython-310.pyc differ diff --git a/osinaweb/addressbook/__pycache__/apps.cpython-310.pyc b/osinaweb/addressbook/__pycache__/apps.cpython-310.pyc new file mode 100644 index 00000000..ddf9287e Binary files /dev/null and b/osinaweb/addressbook/__pycache__/apps.cpython-310.pyc differ diff --git a/osinaweb/addressbook/__pycache__/models.cpython-310.pyc b/osinaweb/addressbook/__pycache__/models.cpython-310.pyc new file mode 100644 index 00000000..20d87192 Binary files /dev/null and b/osinaweb/addressbook/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/addressbook/admin.py b/osinaweb/addressbook/admin.py new file mode 100644 index 00000000..767749be --- /dev/null +++ b/osinaweb/addressbook/admin.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from .models import * + +# Register your models here. + +admin.site.register(Group) +admin.site.register(Country) +admin.site.register(AddressBook) +admin.site.register(Contact) +admin.site.register(SocialMedia) \ No newline at end of file diff --git a/osinaweb/addressbook/apps.py b/osinaweb/addressbook/apps.py new file mode 100644 index 00000000..ea33e78b --- /dev/null +++ b/osinaweb/addressbook/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AddressbookConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'addressbook' diff --git a/osinaweb/addressbook/migrations/0001_initial.py b/osinaweb/addressbook/migrations/0001_initial.py new file mode 100644 index 00000000..1b95bb9c --- /dev/null +++ b/osinaweb/addressbook/migrations/0001_initial.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.5 on 2024-02-23 18:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Group', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ], + ), + ] diff --git a/osinaweb/addressbook/migrations/0002_country_addressbook.py b/osinaweb/addressbook/migrations/0002_country_addressbook.py new file mode 100644 index 00000000..2cbab358 --- /dev/null +++ b/osinaweb/addressbook/migrations/0002_country_addressbook.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.5 on 2024-02-23 18:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('addressbook', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Country', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('code', models.CharField(max_length=5)), + ], + ), + migrations.CreateModel( + name='AddressBook', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=100)), + ('middle_name', models.CharField(blank=True, max_length=100, null=True)), + ('last_name', models.CharField(max_length=100)), + ('country', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='addressbook.country')), + ('group', models.ManyToManyField(blank=True, to='addressbook.group')), + ], + ), + ] diff --git a/osinaweb/addressbook/migrations/0003_contact.py b/osinaweb/addressbook/migrations/0003_contact.py new file mode 100644 index 00000000..7686da90 --- /dev/null +++ b/osinaweb/addressbook/migrations/0003_contact.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.5 on 2024-02-23 18:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('addressbook', '0002_country_addressbook'), + ] + + operations = [ + migrations.CreateModel( + name='Contact', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('Email', 'Email'), ('Mobile', 'Mobile'), ('Phone', 'Phone'), ('Whatsapp', 'Whatsapp')], max_length=20)), + ('contact', models.CharField(max_length=100)), + ('addressbook', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='addressbook.addressbook')), + ], + ), + ] diff --git a/osinaweb/addressbook/migrations/0004_socialmedia.py b/osinaweb/addressbook/migrations/0004_socialmedia.py new file mode 100644 index 00000000..1618a426 --- /dev/null +++ b/osinaweb/addressbook/migrations/0004_socialmedia.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.5 on 2024-02-23 18:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('addressbook', '0003_contact'), + ] + + operations = [ + migrations.CreateModel( + name='SocialMedia', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('Facebook', 'Facebook'), ('Instagram', 'Instagram'), ('X', 'X'), ('Tiktok', 'Tiktok'), ('Linkedin', 'Linkedin'), ('Youtube', 'Youtube')], max_length=20)), + ('username', models.CharField(blank=True, max_length=50)), + ('link', models.URLField(blank=True)), + ], + ), + ] diff --git a/osinaweb/addressbook/migrations/0005_socialmedia_addressbook.py b/osinaweb/addressbook/migrations/0005_socialmedia_addressbook.py new file mode 100644 index 00000000..4eb35837 --- /dev/null +++ b/osinaweb/addressbook/migrations/0005_socialmedia_addressbook.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2024-02-23 18:54 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('addressbook', '0004_socialmedia'), + ] + + operations = [ + migrations.AddField( + model_name='socialmedia', + name='addressbook', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='addressbook.addressbook'), + ), + ] diff --git a/osinaweb/addressbook/migrations/__init__.py b/osinaweb/addressbook/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/osinaweb/addressbook/migrations/__pycache__/0001_initial.cpython-310.pyc b/osinaweb/addressbook/migrations/__pycache__/0001_initial.cpython-310.pyc new file mode 100644 index 00000000..5725eb71 Binary files /dev/null and b/osinaweb/addressbook/migrations/__pycache__/0001_initial.cpython-310.pyc differ diff --git a/osinaweb/addressbook/migrations/__pycache__/0002_country_addressbook.cpython-310.pyc b/osinaweb/addressbook/migrations/__pycache__/0002_country_addressbook.cpython-310.pyc new file mode 100644 index 00000000..5f38c0b2 Binary files /dev/null and b/osinaweb/addressbook/migrations/__pycache__/0002_country_addressbook.cpython-310.pyc differ diff --git a/osinaweb/addressbook/migrations/__pycache__/0003_contact.cpython-310.pyc b/osinaweb/addressbook/migrations/__pycache__/0003_contact.cpython-310.pyc new file mode 100644 index 00000000..61b72f78 Binary files /dev/null and b/osinaweb/addressbook/migrations/__pycache__/0003_contact.cpython-310.pyc differ diff --git a/osinaweb/addressbook/migrations/__pycache__/0004_socialmedia.cpython-310.pyc b/osinaweb/addressbook/migrations/__pycache__/0004_socialmedia.cpython-310.pyc new file mode 100644 index 00000000..4dbba939 Binary files /dev/null and b/osinaweb/addressbook/migrations/__pycache__/0004_socialmedia.cpython-310.pyc differ diff --git a/osinaweb/addressbook/migrations/__pycache__/0005_socialmedia_addressbook.cpython-310.pyc b/osinaweb/addressbook/migrations/__pycache__/0005_socialmedia_addressbook.cpython-310.pyc new file mode 100644 index 00000000..e712caac Binary files /dev/null and b/osinaweb/addressbook/migrations/__pycache__/0005_socialmedia_addressbook.cpython-310.pyc differ diff --git a/osinaweb/addressbook/migrations/__pycache__/__init__.cpython-310.pyc b/osinaweb/addressbook/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0ea0bf12 Binary files /dev/null and b/osinaweb/addressbook/migrations/__pycache__/__init__.cpython-310.pyc differ diff --git a/osinaweb/addressbook/models.py b/osinaweb/addressbook/models.py new file mode 100644 index 00000000..e31a6052 --- /dev/null +++ b/osinaweb/addressbook/models.py @@ -0,0 +1,49 @@ +from django.db import models + +# Create your models here. + + +class Group(models.Model): + name = models.CharField(max_length=100) + def __str__(self): + return self.name + + +class Country(models.Model): + name = models.CharField(max_length=100) + code = models.CharField(max_length=5) + +class AddressBook(models.Model): + first_name = models.CharField(max_length=100) + middle_name = models.CharField(max_length=100, blank=True, null=True) + last_name = models.CharField(max_length=100) + country = models.ForeignKey(Country, null=True, on_delete=models.SET_NULL) + group = models.ManyToManyField(Group, blank=True) + + +class Contact(models.Model): + TYPE_CHOICES = ( + ('Email', 'Email'), + ('Mobile', 'Mobile'), + ('Phone', 'Phone'), + ('Whatsapp', 'Whatsapp'), + ) + type = models.CharField(max_length=20, choices=TYPE_CHOICES) + contact = models.CharField(max_length=100) + addressbook = models.ForeignKey(AddressBook, on_delete=models.CASCADE) + + +class SocialMedia(models.Model): + TYPE_CHOICES = ( + ('Facebook', 'Facebook'), + ('Instagram', 'Instagram'), + ('X', 'X'), + ('Tiktok', 'Tiktok'), + ('Linkedin', 'Linkedin'), + ('Youtube', 'Youtube'), + ) + type = models.CharField(max_length=20, choices=TYPE_CHOICES) + username = models.CharField(max_length=50, blank=True) + link = models.URLField(blank=True) + addressbook = models.ForeignKey(AddressBook, on_delete=models.CASCADE, null=True) + diff --git a/osinaweb/addressbook/tests.py b/osinaweb/addressbook/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/osinaweb/addressbook/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/osinaweb/addressbook/views.py b/osinaweb/addressbook/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/osinaweb/addressbook/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/osinaweb/billing/__init__.py b/osinaweb/billing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/osinaweb/billing/__pycache__/__init__.cpython-310.pyc b/osinaweb/billing/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..77224f8f Binary files /dev/null and b/osinaweb/billing/__pycache__/__init__.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/admin.cpython-310.pyc b/osinaweb/billing/__pycache__/admin.cpython-310.pyc new file mode 100644 index 00000000..a9eff35c Binary files /dev/null and b/osinaweb/billing/__pycache__/admin.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/apps.cpython-310.pyc b/osinaweb/billing/__pycache__/apps.cpython-310.pyc new file mode 100644 index 00000000..fd5eba6c Binary files /dev/null and b/osinaweb/billing/__pycache__/apps.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/models.cpython-310.pyc b/osinaweb/billing/__pycache__/models.cpython-310.pyc new file mode 100644 index 00000000..33bb824e Binary files /dev/null and b/osinaweb/billing/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/urls.cpython-310.pyc b/osinaweb/billing/__pycache__/urls.cpython-310.pyc new file mode 100644 index 00000000..0730172e Binary files /dev/null and b/osinaweb/billing/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/views.cpython-310.pyc b/osinaweb/billing/__pycache__/views.cpython-310.pyc new file mode 100644 index 00000000..7e82059e Binary files /dev/null and b/osinaweb/billing/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/billing/admin.py b/osinaweb/billing/admin.py new file mode 100644 index 00000000..f5b4f91c --- /dev/null +++ b/osinaweb/billing/admin.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from .models import * + + +# Register your models here. + +admin.site.register(RecurringCycle) +admin.site.register(Service) +admin.site.register(ServicePayment) +admin.site.register(PaymentType) +admin.site.register(Invoice) +admin.site.register(Receipt) +admin.site.register(Charge) \ No newline at end of file diff --git a/osinaweb/billing/apps.py b/osinaweb/billing/apps.py new file mode 100644 index 00000000..8cfa4e05 --- /dev/null +++ b/osinaweb/billing/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BillingConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'billing' diff --git a/osinaweb/billing/migrations/0001_initial.py b/osinaweb/billing/migrations/0001_initial.py new file mode 100644 index 00000000..0897df32 --- /dev/null +++ b/osinaweb/billing/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:17 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('osinacore', '0058_remove_point_total_time_hours_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='RecurringCycle', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('months', models.IntegerField()), + ], + ), + migrations.CreateModel( + name='Service', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=200)), + ('description', models.TextField(blank=True)), + ('amount', models.DecimalField(decimal_places=3, max_digits=5)), + ('recurring', models.BooleanField(default=False)), + ('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.customerprofile')), + ('project', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.project')), + ('type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.projecttype')), + ], + ), + ] diff --git a/osinaweb/billing/migrations/0002_service_active_service_cancelled_at_and_more.py b/osinaweb/billing/migrations/0002_service_active_service_cancelled_at_and_more.py new file mode 100644 index 00000000..8d40e96b --- /dev/null +++ b/osinaweb/billing/migrations/0002_service_active_service_cancelled_at_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='service', + name='active', + field=models.BooleanField(default=True, null=True), + ), + migrations.AddField( + model_name='service', + name='cancelled_at', + field=models.DateField(auto_now=True, null=True), + ), + migrations.AddField( + model_name='service', + name='created_at', + field=models.DateField(auto_now=True, null=True), + ), + migrations.AddField( + model_name='service', + name='due_at', + field=models.DateField(auto_now=True, null=True), + ), + ] diff --git a/osinaweb/billing/migrations/0003_payment_servicepayment.py b/osinaweb/billing/migrations/0003_payment_servicepayment.py new file mode 100644 index 00000000..55ccf341 --- /dev/null +++ b/osinaweb/billing/migrations/0003_payment_servicepayment.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:35 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0002_service_active_service_cancelled_at_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='ServicePayment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.DecimalField(decimal_places=3, max_digits=5)), + ('date_paid', models.DateField()), + ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billing.service')), + ('type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='billing.payment')), + ], + ), + ] diff --git a/osinaweb/billing/migrations/0004_rename_payment_paymenttype.py b/osinaweb/billing/migrations/0004_rename_payment_paymenttype.py new file mode 100644 index 00000000..ef9d8b3e --- /dev/null +++ b/osinaweb/billing/migrations/0004_rename_payment_paymenttype.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:35 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0003_payment_servicepayment'), + ] + + operations = [ + migrations.RenameModel( + old_name='Payment', + new_name='PaymentType', + ), + ] diff --git a/osinaweb/billing/migrations/0005_service_recurring_cycle.py b/osinaweb/billing/migrations/0005_service_recurring_cycle.py new file mode 100644 index 00000000..54052842 --- /dev/null +++ b/osinaweb/billing/migrations/0005_service_recurring_cycle.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0004_rename_payment_paymenttype'), + ] + + operations = [ + migrations.AddField( + model_name='service', + name='recurring_cycle', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='billing.recurringcycle'), + ), + ] diff --git a/osinaweb/billing/migrations/0006_alter_service_cancelled_at_alter_service_created_at_and_more.py b/osinaweb/billing/migrations/0006_alter_service_cancelled_at_alter_service_created_at_and_more.py new file mode 100644 index 00000000..e4678508 --- /dev/null +++ b/osinaweb/billing/migrations/0006_alter_service_cancelled_at_alter_service_created_at_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0005_service_recurring_cycle'), + ] + + operations = [ + migrations.AlterField( + model_name='service', + name='cancelled_at', + field=models.DateField(blank=True, null=True), + ), + migrations.AlterField( + model_name='service', + name='created_at', + field=models.DateField(null=True), + ), + migrations.AlterField( + model_name='service', + name='due_at', + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/osinaweb/billing/migrations/0007_alter_service_recurring_cycle.py b/osinaweb/billing/migrations/0007_alter_service_recurring_cycle.py new file mode 100644 index 00000000..6e1a3b3d --- /dev/null +++ b/osinaweb/billing/migrations/0007_alter_service_recurring_cycle.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0006_alter_service_cancelled_at_alter_service_created_at_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='service', + name='recurring_cycle', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='billing.recurringcycle'), + ), + ] diff --git a/osinaweb/billing/migrations/0008_alter_service_type.py b/osinaweb/billing/migrations/0008_alter_service_type.py new file mode 100644 index 00000000..13e89742 --- /dev/null +++ b/osinaweb/billing/migrations/0008_alter_service_type.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:43 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0058_remove_point_total_time_hours_and_more'), + ('billing', '0007_alter_service_recurring_cycle'), + ] + + operations = [ + migrations.AlterField( + model_name='service', + name='type', + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.projecttype'), + ), + ] diff --git a/osinaweb/billing/migrations/0009_remove_service_due_at_remove_servicepayment_service_and_more.py b/osinaweb/billing/migrations/0009_remove_service_due_at_remove_servicepayment_service_and_more.py new file mode 100644 index 00000000..e0cad0f8 --- /dev/null +++ b/osinaweb/billing/migrations/0009_remove_service_due_at_remove_servicepayment_service_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 4.2.5 on 2024-02-23 19:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0008_alter_service_type'), + ] + + operations = [ + migrations.RemoveField( + model_name='service', + name='due_at', + ), + migrations.RemoveField( + model_name='servicepayment', + name='service', + ), + migrations.CreateModel( + name='Charge', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('due_date', models.DateField()), + ('is_paid', models.BooleanField(default=False)), + ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='billing.service')), + ], + ), + migrations.AddField( + model_name='servicepayment', + name='charge', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='billing.charge'), + ), + ] diff --git a/osinaweb/billing/migrations/0010_charge_amount.py b/osinaweb/billing/migrations/0010_charge_amount.py new file mode 100644 index 00000000..265c8294 --- /dev/null +++ b/osinaweb/billing/migrations/0010_charge_amount.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-02-23 20:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0009_remove_service_due_at_remove_servicepayment_service_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='charge', + name='amount', + field=models.DecimalField(decimal_places=3, max_digits=5, null=True), + ), + ] diff --git a/osinaweb/billing/migrations/0011_invoice.py b/osinaweb/billing/migrations/0011_invoice.py new file mode 100644 index 00000000..1a91cc13 --- /dev/null +++ b/osinaweb/billing/migrations/0011_invoice.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.5 on 2024-02-24 19:22 + +from django.db import migrations, models +import django.db.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0010_charge_amount'), + ] + + operations = [ + migrations.CreateModel( + name='Invoice', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('invoice_number', models.CharField(max_length=100)), + ('date_created', models.DateField(verbose_name=django.db.models.fields.DateField)), + ('charge', models.ManyToManyField(to='billing.charge')), + ], + ), + ] diff --git a/osinaweb/billing/migrations/0012_remove_servicepayment_charge_receipt_and_more.py b/osinaweb/billing/migrations/0012_remove_servicepayment_charge_receipt_and_more.py new file mode 100644 index 00000000..798b25a9 --- /dev/null +++ b/osinaweb/billing/migrations/0012_remove_servicepayment_charge_receipt_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.5 on 2024-02-24 19:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0011_invoice'), + ] + + operations = [ + migrations.RemoveField( + model_name='servicepayment', + name='charge', + ), + migrations.CreateModel( + name='Receipt', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('receipt_number', models.CharField(max_length=100)), + ('date_generated', models.DateField()), + ('payment', models.ManyToManyField(to='billing.servicepayment')), + ], + ), + migrations.AddField( + model_name='servicepayment', + name='charge', + field=models.ManyToManyField(null=True, to='billing.charge'), + ), + ] diff --git a/osinaweb/billing/migrations/0013_alter_invoice_date_created.py b/osinaweb/billing/migrations/0013_alter_invoice_date_created.py new file mode 100644 index 00000000..efbac552 --- /dev/null +++ b/osinaweb/billing/migrations/0013_alter_invoice_date_created.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-02-24 19:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0012_remove_servicepayment_charge_receipt_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='invoice', + name='date_created', + field=models.DateField(), + ), + ] diff --git a/osinaweb/billing/migrations/0014_servicepayment_comment.py b/osinaweb/billing/migrations/0014_servicepayment_comment.py new file mode 100644 index 00000000..db3948e5 --- /dev/null +++ b/osinaweb/billing/migrations/0014_servicepayment_comment.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-02-24 19:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0013_alter_invoice_date_created'), + ] + + operations = [ + migrations.AddField( + model_name='servicepayment', + name='comment', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/osinaweb/billing/migrations/__init__.py b/osinaweb/billing/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/osinaweb/billing/migrations/__pycache__/0001_initial.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0001_initial.cpython-310.pyc new file mode 100644 index 00000000..a74fa369 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0001_initial.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0002_service_active_service_cancelled_at_and_more.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0002_service_active_service_cancelled_at_and_more.cpython-310.pyc new file mode 100644 index 00000000..d645e833 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0002_service_active_service_cancelled_at_and_more.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0003_payment_servicepayment.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0003_payment_servicepayment.cpython-310.pyc new file mode 100644 index 00000000..32e8e2bd Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0003_payment_servicepayment.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0004_rename_payment_paymenttype.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0004_rename_payment_paymenttype.cpython-310.pyc new file mode 100644 index 00000000..bdc8475d Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0004_rename_payment_paymenttype.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0005_service_recurring_cycle.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0005_service_recurring_cycle.cpython-310.pyc new file mode 100644 index 00000000..984b44d8 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0005_service_recurring_cycle.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0006_alter_service_cancelled_at_alter_service_created_at_and_more.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0006_alter_service_cancelled_at_alter_service_created_at_and_more.cpython-310.pyc new file mode 100644 index 00000000..20ba2f54 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0006_alter_service_cancelled_at_alter_service_created_at_and_more.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0007_alter_service_recurring_cycle.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0007_alter_service_recurring_cycle.cpython-310.pyc new file mode 100644 index 00000000..ee5769ee Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0007_alter_service_recurring_cycle.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0008_alter_service_type.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0008_alter_service_type.cpython-310.pyc new file mode 100644 index 00000000..7334e90c Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0008_alter_service_type.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0009_remove_service_due_at_remove_servicepayment_service_and_more.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0009_remove_service_due_at_remove_servicepayment_service_and_more.cpython-310.pyc new file mode 100644 index 00000000..1fdfbf61 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0009_remove_service_due_at_remove_servicepayment_service_and_more.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0010_charge_amount.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0010_charge_amount.cpython-310.pyc new file mode 100644 index 00000000..22e9a651 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0010_charge_amount.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0011_invoice.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0011_invoice.cpython-310.pyc new file mode 100644 index 00000000..b6394d83 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0011_invoice.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0012_remove_servicepayment_charge_receipt_and_more.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0012_remove_servicepayment_charge_receipt_and_more.cpython-310.pyc new file mode 100644 index 00000000..0c265f01 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0012_remove_servicepayment_charge_receipt_and_more.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0013_alter_invoice_date_created.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0013_alter_invoice_date_created.cpython-310.pyc new file mode 100644 index 00000000..0bb1bd71 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0013_alter_invoice_date_created.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0014_servicepayment_comment.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0014_servicepayment_comment.cpython-310.pyc new file mode 100644 index 00000000..b1d44bdb Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0014_servicepayment_comment.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/__init__.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..fa655978 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/__init__.cpython-310.pyc differ diff --git a/osinaweb/billing/models.py b/osinaweb/billing/models.py new file mode 100644 index 00000000..78c80e16 --- /dev/null +++ b/osinaweb/billing/models.py @@ -0,0 +1,66 @@ +from django.db import models +from osinacore.models import * + +# Create your models here. + +class RecurringCycle(models.Model): + months = models.IntegerField() + def __str__(self): + return f"{self.months} months" + + +class Service(models.Model): + title = models.CharField(max_length=200) + description = models.TextField(blank=True) + customer = models.ForeignKey(CustomerProfile, on_delete=models.CASCADE) + project = models.ForeignKey(Project, blank=True, on_delete=models.CASCADE) + type = models.ForeignKey(ProjectType, on_delete=models.CASCADE, blank=True) + amount = models.DecimalField(decimal_places=3, max_digits = 5) + recurring = models.BooleanField(default=False) + recurring_cycle = models.ForeignKey(RecurringCycle, on_delete=models.SET_NULL, null=True, blank=True) + created_at = models.DateField(null=True) + cancelled_at = models.DateField(blank=True, null=True) + active = models.BooleanField(default=True, null=True) + def __str__(self): + return self.title + + +class Charge(models.Model): + service = models.ForeignKey(Service, on_delete=models.CASCADE) + amount = models.DecimalField(decimal_places=3, max_digits = 5, null=True) + due_date = models.DateField() + is_paid = models.BooleanField(default=False) + def __str__(self): + return f"{self.service}'s charge due {self.due_date}" + + +class PaymentType(models.Model): + name = models.CharField(max_length=100) + def __str__(self): + return self.name + + +class ServicePayment(models.Model): + charge = models.ManyToManyField(Charge, null=True) + amount = models.DecimalField(decimal_places=3, max_digits = 5) + date_paid = models.DateField() + type = models.ForeignKey(PaymentType, null=True, on_delete=models.SET_NULL) + comment = models.TextField(null=True, blank=True) + def __str__(self): + return f"Payment for {self.charge}" + + +class Invoice(models.Model): + invoice_number = models.CharField(max_length=100) + charge = models.ManyToManyField(Charge) + date_created = models.DateField() + def __str__(self): + return self.invoice_number + + +class Receipt(models.Model): + receipt_number = models.CharField(max_length=100) + payment = models.ManyToManyField(ServicePayment) + date_generated = models.DateField() + def __str__(self): + return self.receipt_number \ No newline at end of file diff --git a/osinaweb/billing/tasks.py b/osinaweb/billing/tasks.py new file mode 100644 index 00000000..12aab861 --- /dev/null +++ b/osinaweb/billing/tasks.py @@ -0,0 +1,25 @@ +# tasks.py +from celery import shared_task +from django.utils import timezone +from datetime import timedelta +from .models import * + +@shared_task +def create_charges_for_recurring_services(): + today = timezone.now().date() + active_recurring_services = Service.objects.filter(active=True, recurring=True) + + for service in active_recurring_services: + # Get the last charge for the service + last_charge = service.charge_set.order_by('-due_date').first() + + if last_charge and last_charge.due_date <= today: + # Calculate the new due date for the charge based on the recurring cycle + new_due_date = today + timedelta(days=service.recurring_cycle.months * 30) + + # Create a new charge for the service + Charge.objects.create( + service=service, + amount=service.amount, + due_date=new_due_date + ) diff --git a/osinaweb/billing/tests.py b/osinaweb/billing/tests.py new file mode 100644 index 00000000..d09224c4 --- /dev/null +++ b/osinaweb/billing/tests.py @@ -0,0 +1,26 @@ +from django.test import TestCase +from django.utils import timezone +from datetime import timedelta +from .models import * +# Create your tests here. + + +@shared_task +def create_charges_for_recurring_services(): + today = timezone.now().date() + active_recurring_services = Service.objects.filter(active=True, recurring=True) + + for service in active_recurring_services: + # Get the last charge for the service + last_charge = service.charge_set.order_by('-due_date').first() + + if last_charge and last_charge.due_date <= today: + # Calculate the new due date for the charge based on the recurring cycle + new_due_date = today + timedelta(days=service.recurring_cycle.number_of_months * 30) + + # Create a new charge for the service + Charge.objects.create( + service=service, + amount=service.amount, + due_date=new_due_date + ) diff --git a/osinaweb/billing/urls.py b/osinaweb/billing/urls.py new file mode 100644 index 00000000..1d9f7d1e --- /dev/null +++ b/osinaweb/billing/urls.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from django.urls import path, include +from django.conf.urls import handler404 +from django.conf.urls.static import static +from django.conf import settings +from billing import views + + +urlpatterns = [ + + path('check', views.create_charges_for_recurring_services, name='check'), + +] diff --git a/osinaweb/billing/views.py b/osinaweb/billing/views.py new file mode 100644 index 00000000..2b68868d --- /dev/null +++ b/osinaweb/billing/views.py @@ -0,0 +1,29 @@ +from django.shortcuts import render +from django.utils import timezone +from datetime import timedelta +from .models import * +from django.http import JsonResponse + +# Create your views here. + +# Create your tests here. + +def create_charges_for_recurring_services(request): + today = timezone.now().date() + active_recurring_services = Service.objects.filter(active=True, recurring=True) + + for service in active_recurring_services: + # Get the last charge for the service + last_charge = service.charge_set.order_by('-due_date').first() + + if last_charge and last_charge.due_date <= today: + # Calculate the new due date for the charge based on the recurring cycle + new_due_date = today + timedelta(days=service.recurring_cycle.number_of_months * 30) + + # Create a new charge for the service + Charge.objects.create( + service=service, + amount=service.amount, + due_date=new_due_date + ) + return JsonResponse({'status': 'success'}) \ No newline at end of file diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index e174d7db..674f150b 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc b/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc new file mode 100644 index 00000000..e8c0a9a4 Binary files /dev/null and b/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc index 9547110e..da66c5d1 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/urls.py b/osinaweb/osinacore/urls.py new file mode 100644 index 00000000..d113a59c --- /dev/null +++ b/osinaweb/osinacore/urls.py @@ -0,0 +1,161 @@ +"""osinaweb URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" + +from django.urls import path +from osinacore import views +from django.conf.urls.static import static +from django.conf import settings + +urlpatterns = [ + path('login', views.signin, name='signin'), + path('logout/', views.signout, name='signout'), + path('', views.home, name='home'), + path('my-projects/', views.my_projects, name='my-projects'), + path('my-tasks/', views.my_tasks, name='my-tasks'), + path('my-notes/', views.my_notes, name='my-notes'), + path('customers/', views.customers, name='customers'), + path('addcustomer/', views.add_customer, name='addcustomer'), + path('add-business/', views.addbusiness, name='addbusiness'), + path('businesses//', views.businessdetails, name='businessdetails'), + path('businesses/', views.businesses, name='businesses'), + path('addstaff/', views.addstaff, name='adduser'), + path('staffs/', views.staffs, name='users'), + path('staffpositions/', views.staff_positions, name='staffpositions'), + path('createproject/', views.create_project, name='createproject'), + path('createepic//', views.create_epic, name='createepic'), + path('createtask/', views.create_task, name='createtask'), + path('createtask//', views.createtask_project, name='createtaskproject'), + path('createuserstorytask//', views.create_user_story_task, name='createuserstorytask'), + path('createtaskepic/', views.createtask_epic, name='createtaskepic'), + path('projecttypes/', views.project_types, name='projecttypes'), + path('businesstypes/', views.business_types, name='businesstypes'), + path('references/', views.references, name='references'), + path('tags/', views.tags, name='tags'), + path('dailyreports/', views.daily_reports, name='dailyreports'), + path('add-dailyreport/', views.add_daily_report, name='adddailyreport'), + + + + + #Detail pages urls + path('businesses//', views.businessdetails, name='businessdetails'), + path('customers//', views.customerdetails, name='customerdetails'), + path('staffs//', views.staffdetails, name='userdetails'), + path('tasks//', views.detailed_task, name='detailed-task'), + path('projectdetails//', views.detailed_project, name='detailed-project'), + + + + + + #Fetch urls + path('get_tasks//', views.get_tasks, name='get_tasks'), + path('open_tasks_for_project//', views.open_tasks_for_project, name='open_tasks_for_project'), + + + #Modals urls + path('add-status/', views.add_status_modal, name='addstatus'), + path('add-note/', views.add_note_modal, name='addnote'), + path('add-project-note//', views.add_project_note_modal, name='addprojectnote'), + path('add-file/', views.add_file_modal, name='addfile'), + path('add-user-story//', views.add_user_story_modal, name='adduserstory'), + path('add-credentials/', views.add_credentials_modal, name='addcredentials'), + path('update-status//', views.update_status_modal, name='updatestatus'), + path('add-point//', views.add_point_modal, name='addpoint'), + path('show-points//', views.show_points_modal, name='showpoints'), + path('add-time/', views.add_time_modal, name='addtime'), + path('timeline/', views.timeline_modal, name='timeline'), + path('add-projecttype/', views.add_projecttype_modal, name='addprojecttype'), + path('add-businesstype/', views.add_businesstype_modal, name='addbusinesstype'), + path('add-reference/', views.add_reference_modal, name='addreference'), + path('add-tag/', views.add_tag_modal, name='addtag'), + path('add-businesscustomer/', views.add_business_modal, name='addbusinesscustomer'), + path('add-staffposition/', views.staff_position_modal, name='addstaffposition'), + path('statusmobilemodal/', views.status_mobile_modal, name='statusmobilemodal'), + path('userrecentativities/', views.user_recent_activities_modal, name='userrecentativities'), + + + #Delete Modals + path('deletecustomermodal/', views.delete_customer_modal, name='deletecustomermodal'), + path('deletebusinessmodal/', views.delete_business_modal, name='deletebusinessmodal'), + path('deletestaffmodal/', views.delete_staff_modal, name='deletestaffmodal'), + path('deleteprojectmodal/', views.delete_project_modal, name='deleteprojectmodal'), + path('deletetaskmodal/', views.delete_task_modal, name='deletetaskmodal'), + path('deletenotemodal/', views.delete_note_modal, name='deletenotemodal'), + path('deleteprojectnotemodal//', views.delete_project_note_modal, name='deleteprojectnotemodal'), + + path('deletepointmodal///', views.delete_point_modal, name='deletepointmodal'), + path('deletetaskpointmodal///', views.delete_task_point_modal, name='deletetaskpointmodal'), + + + #Save Urls + path('save_note/', views.save_note, name='save_note'), + path('save_project_note/', views.save_project_note, name='save_project_note'), + 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_business_modal/', views.save_business_modal, name='save_business_modal'), + path('save_customer/', views.save_customer, name='save_customer'), + path('save_staff/', views.save_staff, name='save_staff'), + path('save_status/', views.save_status, name='save_status'), + path('save_projecttype/', views.save_projecttype, name='save_projecttype'), + path('save_businesstype/', views.save_businesstype, name='save_businesstype'), + path('save_reference/', views.save_reference, name='save_reference'), + path('save_tag/', views.save_tag, name='save_tag'), + path('save_point/', views.save_point, name='save_point'), + path('save_staffposition/', views.save_staffposition, name='save_staffposition'), + path('save_dailyreport/', views.save_dailyreport, name='save_dailyreport'), + + + #Edit Pages + path('edit-project//', views.edit_project, name='editproject'), + path('edit-epic/', views.edit_epic, name='editepic'), + path('edit-task/', views.edit_task, name='edittask'), + path('edit-customer//', views.edit_customer, name='editcustomer'), + path('edit-business//', views.edit_business, name='editbusiness'), + path('edit-staff//', views.edit_staff, name='editstaff'), + path('edit-projecttype/', views.edit_project_type, name='editprojecttype'), + path('edit-businesstype/', views.edit_business_type, name='editbusinesstype'), + path('edit-reference/', views.edit_reference, name='editreference'), + path('edit-tag/', views.edit_tag, name='edittag'), + path('edits-taffposition/', views.edit_staff_position, name='editstaffposition'), + path('mark_point_working_on///', views.mark_point_working_on, name='mark_point_working_on'), + path('mark_point_working_on_task_page///', views.mark_point_working_on_task_page, name='mark_point_working_on_task_page'), + path('mark_point_completed///', views.mark_point_completed, name='mark_point_completed'), + path('mark_point_completed_task_page///', views.mark_point_completed_task_page, name='mark_point_completed_task_page'), + path('mark_point_paused///', views.mark_point_paused, name='mark_point_paused'), + + + + #Fetch Urls + path('getupdatedlaststatus/', views.get_updated_last_status, name='getupdatedlaststatus'), + path('getupdatedactivities/', views.get_latest_activities, name='getupdatedactivities'), + + # TO FETCH THE EPICS OF THE SELECTED PROJECT WHEN EDITING A TASK + path('fetch_epics/', views.fetch_epics, name='fetch_epics'), + + + path('get_point_total_time//', views.get_point_total_time, name='get_point_total_time'), + + + + #CUSTOMER DASHBOARD + path('customerdashboard/', views.customer_index, name='customerdashboard'), + path('customerinvoices/', views.customer_invoices, name='customerinvoices'), +] + +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc index 59bd7568..8e5fa613 100644 Binary files a/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc and b/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc index b4224b0f..61e21259 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/settings.py b/osinaweb/osinaweb/settings.py index 7d924100..56de931c 100644 --- a/osinaweb/osinaweb/settings.py +++ b/osinaweb/osinaweb/settings.py @@ -37,6 +37,8 @@ LOGIN_URL = 'signin' INSTALLED_APPS = [ 'osinacore', + 'addressbook', + 'billing', 'colorfield', 'django.contrib.admin', 'django.contrib.auth', diff --git a/osinaweb/osinaweb/urls.py b/osinaweb/osinaweb/urls.py index 5a4a0724..796d3fff 100644 --- a/osinaweb/osinaweb/urls.py +++ b/osinaweb/osinaweb/urls.py @@ -14,155 +14,16 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path -from osinacore import views -from django.contrib.auth.decorators import login_required +from django.urls import path, include from django.conf.urls.static import static from django.conf import settings urlpatterns = [ # Pages urls + path('', include('osinacore.urls')), + path('', include('billing.urls')), path('admin/', admin.site.urls), - path('login', views.signin, name='signin'), - path('logout/', views.signout, name='signout'), - path('', login_required(views.home), name='home'), - path('my-projects/', login_required(views.my_projects), name='my-projects'), - path('my-tasks/', login_required(views.my_tasks), name='my-tasks'), - path('my-notes/', login_required(views.my_notes), name='my-notes'), - path('customers/', views.customers, name='customers'), - path('addcustomer/', views.add_customer, name='addcustomer'), - path('add-business/', views.addbusiness, name='addbusiness'), - path('businesses//', views.businessdetails, name='businessdetails'), - path('businesses/', views.businesses, name='businesses'), - path('addstaff/', views.addstaff, name='adduser'), - path('staffs/', views.staffs, name='users'), - path('staffpositions/', views.staff_positions, name='staffpositions'), - path('createproject/', views.create_project, name='createproject'), - path('createepic//', views.create_epic, name='createepic'), - path('createtask/', views.create_task, name='createtask'), - path('createtask//', views.createtask_project, name='createtaskproject'), - path('createuserstorytask//', views.create_user_story_task, name='createuserstorytask'), - path('createtaskepic/', views.createtask_epic, name='createtaskepic'), - path('projecttypes/', views.project_types, name='projecttypes'), - path('businesstypes/', views.business_types, name='businesstypes'), - path('references/', views.references, name='references'), - path('tags/', views.tags, name='tags'), - path('dailyreports/', views.daily_reports, name='dailyreports'), - path('add-dailyreport/', views.add_daily_report, name='adddailyreport'), - - - - - #Detail pages urls - path('businesses//', views.businessdetails, name='businessdetails'), - path('customers//', views.customerdetails, name='customerdetails'), - path('staffs//', views.staffdetails, name='userdetails'), - path('tasks//', views.detailed_task, name='detailed-task'), - path('projectdetails//', views.detailed_project, name='detailed-project'), - - - - - - #Fetch urls - path('get_tasks//', views.get_tasks, name='get_tasks'), - path('open_tasks_for_project//', views.open_tasks_for_project, name='open_tasks_for_project'), - - - #Modals urls - path('add-status/', views.add_status_modal, name='addstatus'), - path('add-note/', views.add_note_modal, name='addnote'), - path('add-project-note//', views.add_project_note_modal, name='addprojectnote'), - path('add-file/', views.add_file_modal, name='addfile'), - path('add-user-story//', views.add_user_story_modal, name='adduserstory'), - path('add-credentials/', views.add_credentials_modal, name='addcredentials'), - path('update-status//', views.update_status_modal, name='updatestatus'), - path('add-point//', views.add_point_modal, name='addpoint'), - path('show-points//', views.show_points_modal, name='showpoints'), - path('add-time/', views.add_time_modal, name='addtime'), - path('timeline/', views.timeline_modal, name='timeline'), - path('add-projecttype/', views.add_projecttype_modal, name='addprojecttype'), - path('add-businesstype/', views.add_businesstype_modal, name='addbusinesstype'), - path('add-reference/', views.add_reference_modal, name='addreference'), - path('add-tag/', views.add_tag_modal, name='addtag'), - path('add-businesscustomer/', views.add_business_modal, name='addbusinesscustomer'), - path('add-staffposition/', views.staff_position_modal, name='addstaffposition'), - path('statusmobilemodal/', views.status_mobile_modal, name='statusmobilemodal'), - path('userrecentativities/', views.user_recent_activities_modal, name='userrecentativities'), - - - #Delete Modals - path('deletecustomermodal/', views.delete_customer_modal, name='deletecustomermodal'), - path('deletebusinessmodal/', views.delete_business_modal, name='deletebusinessmodal'), - path('deletestaffmodal/', views.delete_staff_modal, name='deletestaffmodal'), - path('deleteprojectmodal/', views.delete_project_modal, name='deleteprojectmodal'), - path('deletetaskmodal/', views.delete_task_modal, name='deletetaskmodal'), - path('deletenotemodal/', views.delete_note_modal, name='deletenotemodal'), - path('deleteprojectnotemodal//', views.delete_project_note_modal, name='deleteprojectnotemodal'), - - path('deletepointmodal///', views.delete_point_modal, name='deletepointmodal'), - path('deletetaskpointmodal///', views.delete_task_point_modal, name='deletetaskpointmodal'), - - - #Save Urls - path('save_note/', views.save_note, name='save_note'), - path('save_project_note/', views.save_project_note, name='save_project_note'), - 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_business_modal/', views.save_business_modal, name='save_business_modal'), - path('save_customer/', views.save_customer, name='save_customer'), - path('save_staff/', views.save_staff, name='save_staff'), - path('save_status/', views.save_status, name='save_status'), - path('save_projecttype/', views.save_projecttype, name='save_projecttype'), - path('save_businesstype/', views.save_businesstype, name='save_businesstype'), - path('save_reference/', views.save_reference, name='save_reference'), - path('save_tag/', views.save_tag, name='save_tag'), - path('save_point/', views.save_point, name='save_point'), - path('save_staffposition/', views.save_staffposition, name='save_staffposition'), - path('save_dailyreport/', views.save_dailyreport, name='save_dailyreport'), - - - #Edit Pages - path('edit-project//', views.edit_project, name='editproject'), - path('edit-epic/', views.edit_epic, name='editepic'), - path('edit-task/', views.edit_task, name='edittask'), - path('edit-customer//', views.edit_customer, name='editcustomer'), - path('edit-business//', views.edit_business, name='editbusiness'), - path('edit-staff//', views.edit_staff, name='editstaff'), - path('edit-projecttype/', views.edit_project_type, name='editprojecttype'), - path('edit-businesstype/', views.edit_business_type, name='editbusinesstype'), - path('edit-reference/', views.edit_reference, name='editreference'), - path('edit-tag/', views.edit_tag, name='edittag'), - path('edits-taffposition/', views.edit_staff_position, name='editstaffposition'), - path('mark_point_working_on///', views.mark_point_working_on, name='mark_point_working_on'), - path('mark_point_working_on_task_page///', views.mark_point_working_on_task_page, name='mark_point_working_on_task_page'), - path('mark_point_completed///', views.mark_point_completed, name='mark_point_completed'), - path('mark_point_completed_task_page///', views.mark_point_completed_task_page, name='mark_point_completed_task_page'), - path('mark_point_paused///', views.mark_point_paused, name='mark_point_paused'), - - - #Fetch Urls - path('getupdatedlaststatus/', views.get_updated_last_status, name='getupdatedlaststatus'), - path('getupdatedactivities/', views.get_latest_activities, name='getupdatedactivities'), - - # TO FETCH THE EPICS OF THE SELECTED PROJECT WHEN EDITING A TASK - path('fetch_epics/', views.fetch_epics, name='fetch_epics'), - - - path('get_point_total_time//', views.get_point_total_time, name='get_point_total_time'), - - - - - - - - #CUSTOMER DASHBOARD - path('customerdashboard/', views.customer_index, name='customerdashboard'), - path('customerinvoices/', views.customer_invoices, name='customerinvoices'), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/osinaweb/templates/index.html b/osinaweb/templates/index.html index 3abaa971..c364b383 100644 --- a/osinaweb/templates/index.html +++ b/osinaweb/templates/index.html @@ -308,7 +308,7 @@
{% if task.status == 'Open' %}
+ class="w-full flex justify-center items-center text-white text-center bg-blue-500 rounded-t-md py-5 px-3">

{{task.name}}

{% endif %}