Files
Refactored-App/backend/apps/operations/models.py
2026-04-01 03:20:54 +02:00

170 lines
8.4 KiB
Python

from django.db import models
from apps.core.models import LegacyTrackedModel
class Invoice(LegacyTrackedModel):
business = models.ForeignKey("core.Business", null=True, blank=True, on_delete=models.SET_NULL)
vendor = models.ForeignKey("core.Vendor", on_delete=models.PROTECT)
vendor_not_configured = models.BooleanField(default=False)
vendor_config_note = models.TextField(blank=True)
invoice_number = models.CharField(max_length=120, blank=True)
invoice_date = models.DateField(null=True, blank=True)
order_date = models.DateField(null=True, blank=True)
entered_at = models.DateTimeField(null=True, blank=True)
payment_status = models.CharField(max_length=32, default="unpaid")
paid_date = models.DateField(null=True, blank=True)
due_date = models.DateField(null=True, blank=True)
subtotal = models.DecimalField(max_digits=12, decimal_places=2, default=0)
discount_pct = models.DecimalField(max_digits=8, decimal_places=2, default=0)
discount_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0)
total_after_discount = models.DecimalField(max_digits=12, decimal_places=2, default=0)
vat_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0)
gross_total = models.DecimalField(max_digits=12, decimal_places=2, default=0)
currency = models.CharField(max_length=8, default="CZK")
goods_received_status = models.CharField(max_length=32, default="not_received")
goods_date = models.DateField(null=True, blank=True)
notes = models.TextField(blank=True)
is_editable = models.BooleanField(default=True)
inventory_updated = models.BooleanField(default=False)
rate_czk_eur = models.DecimalField(max_digits=12, decimal_places=4, default=0)
rate_czk_usd = models.DecimalField(max_digits=12, decimal_places=4, default=0)
vat_exempt = models.BooleanField(default=False)
class InvoiceLineItem(LegacyTrackedModel):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name="line_items")
product = models.ForeignKey("core.Product", on_delete=models.PROTECT)
quantity = models.DecimalField(max_digits=12, decimal_places=3)
unit_price = models.DecimalField(max_digits=12, decimal_places=2)
total_price = models.DecimalField(max_digits=12, decimal_places=2)
vat_rate = models.DecimalField(max_digits=8, decimal_places=2, default=0)
vat_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0)
line_order = models.PositiveIntegerField(default=0)
class InvoiceCategory(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name="category_links")
category = models.ForeignKey("core.Category", on_delete=models.CASCADE)
class Meta:
unique_together = ("invoice", "category")
class InventoryBalance(models.Model):
product = models.OneToOneField("core.Product", on_delete=models.CASCADE, related_name="inventory_balance")
quantity_on_hand = models.DecimalField(max_digits=12, decimal_places=3, default=0)
uom = models.CharField(max_length=32, default="pcs")
last_updated_at = models.DateTimeField(null=True, blank=True)
class InventoryMovement(LegacyTrackedModel):
product = models.ForeignKey("core.Product", on_delete=models.CASCADE, related_name="inventory_movements")
sellable_product = models.ForeignKey(
"core.Product",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="sellable_inventory_movements",
)
movement_ts = models.DateTimeField(null=True, blank=True)
movement_date = models.DateField()
movement_type = models.CharField(max_length=32)
quantity_delta = models.DecimalField(max_digits=12, decimal_places=3)
uom = models.CharField(max_length=32, default="pcs")
source_type = models.CharField(max_length=32)
source_ref = models.CharField(max_length=255, blank=True)
class InventoryBulkMapping(LegacyTrackedModel):
bulk_product = models.ForeignKey("core.Product", on_delete=models.CASCADE, related_name="bulk_mappings")
sellable_product = models.ForeignKey("core.Product", on_delete=models.CASCADE, related_name="sellable_mappings")
decrement_amount = models.DecimalField(max_digits=12, decimal_places=3, default=1)
decrement_uom = models.CharField(max_length=32, blank=True)
chip_name = models.CharField(max_length=120, blank=True)
class Meta:
unique_together = ("bulk_product", "sellable_product")
class StockCount(LegacyTrackedModel):
business = models.ForeignKey("core.Business", null=True, blank=True, on_delete=models.SET_NULL)
counted_by = models.CharField(max_length=255, blank=True)
count_date = models.DateField()
notes = models.TextField(blank=True)
status = models.CharField(max_length=32, default="in_progress")
completed_at = models.DateTimeField(null=True, blank=True)
class StockCountLine(LegacyTrackedModel):
stock_count = models.ForeignKey(StockCount, on_delete=models.CASCADE, related_name="lines")
product = models.ForeignKey("core.Product", on_delete=models.PROTECT)
full_units = models.DecimalField(max_digits=12, decimal_places=3, default=0)
partial_units = models.DecimalField(max_digits=12, decimal_places=3, default=0)
total_quantity = models.DecimalField(max_digits=12, decimal_places=3, default=0)
previous_quantity = models.DecimalField(max_digits=12, decimal_places=3, default=0)
class Event(LegacyTrackedModel):
business = models.ForeignKey("core.Business", on_delete=models.CASCADE, related_name="events")
title = models.CharField(max_length=255)
description = models.TextField(blank=True)
event_type = models.CharField(max_length=32, default="other")
start_datetime = models.DateTimeField()
end_datetime = models.DateTimeField()
all_day = models.BooleanField(default=False)
location = models.CharField(max_length=255, blank=True)
color = models.CharField(max_length=32, blank=True)
recurrence_type = models.CharField(max_length=32, default="none")
recurrence_end_date = models.DateField(null=True, blank=True)
created_by = models.ForeignKey("accounts.User", null=True, blank=True, on_delete=models.SET_NULL)
is_active = models.BooleanField(default=True)
class ShiftRole(LegacyTrackedModel):
business = models.ForeignKey("core.Business", on_delete=models.CASCADE, related_name="shift_roles")
name = models.CharField(max_length=255)
color = models.CharField(max_length=32, blank=True)
sort_order = models.PositiveIntegerField(default=0)
is_active = models.BooleanField(default=True)
class ShiftTemplate(LegacyTrackedModel):
business = models.ForeignKey("core.Business", on_delete=models.CASCADE, related_name="shift_templates")
name = models.CharField(max_length=255)
start_datetime = models.DateTimeField()
end_datetime = models.DateTimeField()
min_staff = models.PositiveIntegerField(default=1)
max_staff = models.PositiveIntegerField(default=3)
color = models.CharField(max_length=32, blank=True)
recurrence_type = models.CharField(max_length=32, default="none")
recurrence_end_date = models.DateField(null=True, blank=True)
created_by = models.ForeignKey("accounts.User", null=True, blank=True, on_delete=models.SET_NULL)
shift_role = models.ForeignKey(ShiftRole, null=True, blank=True, on_delete=models.SET_NULL)
is_active = models.BooleanField(default=True)
class ShiftAssignment(LegacyTrackedModel):
shift_template = models.ForeignKey(ShiftTemplate, on_delete=models.CASCADE, related_name="assignments")
user = models.ForeignKey("accounts.User", on_delete=models.CASCADE, related_name="shift_assignments")
occurrence_date = models.DateField()
start_override = models.DateTimeField(null=True, blank=True)
end_override = models.DateTimeField(null=True, blank=True)
status = models.CharField(max_length=32, default="assigned")
notes = models.TextField(blank=True)
notification_sent_at = models.DateTimeField(null=True, blank=True)
class Meta:
unique_together = ("shift_template", "user", "occurrence_date")
class WorkerAvailability(LegacyTrackedModel):
user = models.ForeignKey("accounts.User", on_delete=models.CASCADE, related_name="availabilities")
business = models.ForeignKey("core.Business", on_delete=models.CASCADE, related_name="availabilities")
date = models.DateField()
status = models.CharField(max_length=32, default="available")
note = models.TextField(blank=True)
class Meta:
unique_together = ("user", "date")