Skip to content

Commit

Permalink
Restructured project to work with new community aspect (#513)
Browse files Browse the repository at this point in the history
* restructured project into more categories

---------

Signed-off-by: Trey <[email protected]>
  • Loading branch information
TreyWW authored Oct 12, 2024
1 parent 415c76a commit 618a646
Show file tree
Hide file tree
Showing 402 changed files with 2,037 additions and 2,102 deletions.
50 changes: 0 additions & 50 deletions WHERE_ARE_THINGS.md

This file was deleted.

28 changes: 15 additions & 13 deletions backend/admin.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
from typing import Iterable, Any

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from backend.models import (
Client,
Invoice,
InvoiceURL,
InvoiceItem,
from backend.core.api.public import APIAuthToken
from backend.core.models import (
PasswordSecret,
AuditLog,
LoginLog,
Expand All @@ -19,23 +14,30 @@
TeamInvitation,
TeamMemberPermission,
User,
InvoiceProduct,
FeatureFlags,
VerificationCodes,
QuotaLimit,
QuotaOverrides,
QuotaUsage,
QuotaIncreaseRequest,
Receipt,
ReceiptDownloadToken,
EmailSendStatus,
InvoiceReminder,
InvoiceRecurringProfile,
FileStorageFile,
MultiFileUpload,
)

from backend.api.public.models import APIAuthToken
from backend.finance.models import (
Invoice,
InvoiceURL,
InvoiceItem,
InvoiceReminder,
InvoiceRecurringProfile,
InvoiceProduct,
Receipt,
ReceiptDownloadToken,
)

from backend.clients.models import Client

from settings.settings import BILLING_ENABLED

# from django.contrib.auth.models imp/ort User
Expand Down
23 changes: 0 additions & 23 deletions backend/api/urls.py

This file was deleted.

2 changes: 0 additions & 2 deletions backend/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ class BackendConfig(AppConfig):
name = "backend"

def ready(self):
import backend.signals

pass
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from django.views.decorators.http import require_http_methods

from backend.decorators import web_require_scopes
from backend.service.clients.delete import delete_client, DeleteClientServiceResponse
from backend.types.requests import WebRequest
from backend.core.service.clients.delete import delete_client, DeleteClientServiceResponse
from backend.core.types.requests import WebRequest


@require_http_methods(["DELETE"])
Expand Down
8 changes: 4 additions & 4 deletions backend/api/clients/fetch.py → backend/clients/api/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from django.views.decorators.http import require_http_methods

from backend.decorators import web_require_scopes
from backend.models import Client
from backend.service.clients.get import fetch_clients, FetchClientServiceResponse
from backend.types.htmx import HtmxHttpRequest
from backend.types.requests import WebRequest
from backend.clients.models import Client
from backend.core.service.clients.get import fetch_clients, FetchClientServiceResponse
from backend.core.types.htmx import HtmxHttpRequest
from backend.core.types.requests import WebRequest


@require_http_methods(["GET"])
Expand Down
3 changes: 1 addition & 2 deletions backend/api/clients/urls.py → backend/clients/api/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.urls import path
from . import fetch, delete

from backend.clients.api import fetch, delete

urlpatterns = [
path(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.dispatch import receiver
from django.db.models.signals import post_save

from backend.models import Client, DefaultValues
from backend.clients.models import Client, DefaultValues

logger = logging.getLogger(__name__)

Expand Down
107 changes: 107 additions & 0 deletions backend/clients/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from __future__ import annotations

from datetime import date, timedelta
from django.db import models
from backend.core.data.default_email_templates import (
recurring_invoices_invoice_created_default_email_template,
recurring_invoices_invoice_overdue_default_email_template,
recurring_invoices_invoice_cancelled_default_email_template,
)
from backend.core.models import OwnerBase, User, UserSettings, _private_storage


class Client(OwnerBase):
active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
phone_number = models.CharField(max_length=100, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
email_verified = models.BooleanField(default=False)
company = models.CharField(max_length=100, blank=True, null=True)
contact_method = models.CharField(max_length=100, blank=True, null=True)
is_representative = models.BooleanField(default=False)

address = models.TextField(max_length=100, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
country = models.CharField(max_length=100, blank=True, null=True)

def __str__(self):
return self.name

def has_access(self, user: User) -> bool:
if not user.is_authenticated:
return False

if user.logged_in_as_team:
return self.organization == user.logged_in_as_team
else:
return self.user == user


class DefaultValues(OwnerBase):
class InvoiceDueDateType(models.TextChoices):
days_after = "days_after" # days after issue
date_following = "date_following" # date of following month
date_current = "date_current" # date of current month

class InvoiceDateType(models.TextChoices):
day_of_month = "day_of_month"
days_after = "days_after"

client = models.OneToOneField(Client, on_delete=models.CASCADE, related_name="default_values", null=True, blank=True)

currency = models.CharField(
max_length=3,
default="GBP",
choices=[(code, info["name"]) for code, info in UserSettings.CURRENCIES.items()],
)

invoice_due_date_value = models.PositiveSmallIntegerField(default=7, null=False, blank=False)
invoice_due_date_type = models.CharField(max_length=20, choices=InvoiceDueDateType.choices, default=InvoiceDueDateType.days_after)

invoice_date_value = models.PositiveSmallIntegerField(default=15, null=False, blank=False)
invoice_date_type = models.CharField(max_length=20, choices=InvoiceDateType.choices, default=InvoiceDateType.day_of_month)

invoice_from_name = models.CharField(max_length=100, null=True, blank=True)
invoice_from_company = models.CharField(max_length=100, null=True, blank=True)
invoice_from_address = models.CharField(max_length=100, null=True, blank=True)
invoice_from_city = models.CharField(max_length=100, null=True, blank=True)
invoice_from_county = models.CharField(max_length=100, null=True, blank=True)
invoice_from_country = models.CharField(max_length=100, null=True, blank=True)
invoice_from_email = models.CharField(max_length=100, null=True, blank=True)

invoice_account_number = models.CharField(max_length=100, null=True, blank=True)
invoice_sort_code = models.CharField(max_length=100, null=True, blank=True)
invoice_account_holder_name = models.CharField(max_length=100, null=True, blank=True)

email_template_recurring_invoices_invoice_created = models.TextField(default=recurring_invoices_invoice_created_default_email_template)
email_template_recurring_invoices_invoice_overdue = models.TextField(default=recurring_invoices_invoice_overdue_default_email_template)
email_template_recurring_invoices_invoice_cancelled = models.TextField(
default=recurring_invoices_invoice_cancelled_default_email_template
)

def get_issue_and_due_dates(self, issue_date: date | str | None = None) -> tuple[str, str]:
due: date
issue: date

if isinstance(issue_date, str):
issue = date.fromisoformat(issue_date) or date.today()
else:
issue = issue_date or date.today()

match self.invoice_due_date_type:
case self.InvoiceDueDateType.days_after:
due = issue + timedelta(days=self.invoice_due_date_value)
case self.InvoiceDueDateType.date_following:
due = date(issue.year, issue.month + 1, self.invoice_due_date_value)
case self.InvoiceDueDateType.date_current:
due = date(issue.year, issue.month, self.invoice_due_date_value)
case _:
raise ValueError("Invalid invoice due date type")
return date.isoformat(issue), date.isoformat(due)

default_invoice_logo = models.ImageField(
upload_to="invoice_logos/",
storage=_private_storage,
blank=True,
null=True,
)
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from django.shortcuts import render, redirect

from backend.decorators import web_require_scopes
from backend.service.clients.create import create_client, CreateClientServiceResponse
from backend.types.requests import WebRequest
from backend.core.service.clients.create import create_client, CreateClientServiceResponse
from backend.core.types.requests import WebRequest


@web_require_scopes("clients:write", False, False, "clients:dashboard")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.shortcuts import render

from backend.decorators import web_require_scopes
from backend.types.htmx import HtmxHttpRequest
from backend.core.types.htmx import HtmxHttpRequest


@web_require_scopes("clients:read", False, False, "dashboard")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from typing import Literal

from django.contrib import messages
from django.core.exceptions import ValidationError
from django.http.response import HttpResponse
from django.shortcuts import render, redirect
from django.views.decorators.http import require_http_methods

from backend.decorators import web_require_scopes
from backend.service.clients.delete import delete_client, DeleteClientServiceResponse
from backend.service.clients.validate import validate_client
from backend.models import Client
from backend.types.requests import WebRequest
from backend.core.service.clients.delete import delete_client, DeleteClientServiceResponse
from backend.core.service.clients.validate import validate_client
from backend.core.types.requests import WebRequest
from backend.clients.models import Client


@require_http_methods(["GET"])
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion backend/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import calendar

from backend.service.base.breadcrumbs import get_breadcrumbs
from backend.core.service.base.breadcrumbs import get_breadcrumbs

from settings.helpers import get_var

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from django.http import HttpResponse
from django.shortcuts import render

from backend.types.requests import WebRequest
from backend.service.base.breadcrumbs import get_breadcrumbs
from backend.core.types.requests import WebRequest
from backend.core.service.base.breadcrumbs import get_breadcrumbs


def update_breadcrumbs_endpoint(request: WebRequest):
Expand Down
20 changes: 9 additions & 11 deletions backend/api/base/modal.py → backend/core/api/base/modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@
from django.http import HttpResponseBadRequest
from django.shortcuts import render

from backend.api.public.permissions import SCOPE_DESCRIPTIONS
from backend.api.public.models import APIAuthToken
from backend.models import Client, Receipt, User, InvoiceURL
from backend.models import Invoice
from backend.models import QuotaLimit
from backend.models import Organization
from backend.models import UserSettings
from backend.types.htmx import HtmxHttpRequest
from backend.types.requests import WebRequest
from backend.utils.feature_flags import get_feature_status
from backend.service.defaults.get import get_account_defaults
from backend.core.api.public import APIAuthToken
from backend.core.api.public.permissions import SCOPE_DESCRIPTIONS

from backend.clients.models import Client
from backend.finance.models import InvoiceURL, Invoice, Receipt
from backend.models import QuotaLimit, Organization, UserSettings
from backend.core.types.requests import WebRequest
from backend.core.utils.feature_flags import get_feature_status
from backend.core.service.defaults.get import get_account_defaults


# from backend.utils.quota_limit_ops import quota_usage_check_under
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.shortcuts import render

from backend.models import Notification
from backend.types.htmx import HtmxHttpRequest
from backend.core.types.htmx import HtmxHttpRequest


def get_notification_html(request: HtmxHttpRequest):
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from backend.decorators import web_require_scopes
from backend.models import EmailSendStatus
from backend.types.htmx import HtmxHttpRequest
from backend.core.types.htmx import HtmxHttpRequest


@web_require_scopes("emails:read", True, True)
Expand Down
Loading

0 comments on commit 618a646

Please sign in to comment.