94 lines
3.7 KiB
Python
94 lines
3.7 KiB
Python
from django.db import models
|
||
from django.contrib.auth.models import User
|
||
|
||
class Company(models.Model):
|
||
name = models.CharField(max_length=255)
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
updated_at = models.DateTimeField(auto_now=True)
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
class Membership(models.Model):
|
||
ROLE_CHOICES = [
|
||
('owner', 'Owner'),
|
||
('admin', 'Admin'),
|
||
('member', 'Member'),
|
||
]
|
||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||
company = models.ForeignKey(Company, on_delete=models.CASCADE)
|
||
role = models.CharField(max_length=20, choices=ROLE_CHOICES)
|
||
|
||
def __str__(self):
|
||
return f"{self.user.username} - {self.company.name} ({self.role})"
|
||
|
||
class Tender(models.Model):
|
||
STATUS_CHOICES = [
|
||
('opportunity-discovery', 'Opportunity Discovery'),
|
||
('qualification', 'Qualification / Go–No Go'),
|
||
('tender-registration', 'Tender Registration'),
|
||
('bid-planning', 'Bid Planning'),
|
||
('team-task-assignment', 'Team & Task Assignment'),
|
||
('document-collection-drafting', 'Document Collection & Drafting'),
|
||
('internal-review-compliance-check', 'Internal Review & Compliance Check'),
|
||
('approvals-sign-off', 'Approvals & Sign‑off'),
|
||
('submission-confirmation', 'Submission & Confirmation'),
|
||
('post-bid-review-analytics', 'Post‑Bid Review & Analytics'),
|
||
]
|
||
company = models.ForeignKey(Company, on_delete=models.CASCADE)
|
||
title = models.CharField(max_length=255)
|
||
description = models.TextField()
|
||
deadline = models.DateTimeField()
|
||
status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='opportunity-discovery')
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
updated_at = models.DateTimeField(auto_now=True)
|
||
|
||
def __str__(self):
|
||
return self.title
|
||
|
||
class Bid(models.Model):
|
||
tender = models.ForeignKey(Tender, on_delete=models.CASCADE)
|
||
company = models.ForeignKey(Company, on_delete=models.CASCADE)
|
||
amount = models.DecimalField(max_digits=10, decimal_places=2)
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
updated_at = models.DateTimeField(auto_now=True)
|
||
|
||
def __str__(self):
|
||
return f"Bid for {self.tender.title} by {self.company.name}"
|
||
|
||
class Document(models.Model):
|
||
tender = models.ForeignKey(Tender, on_delete=models.CASCADE, null=True, blank=True)
|
||
bid = models.ForeignKey(Bid, on_delete=models.CASCADE, null=True, blank=True)
|
||
uploaded_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
|
||
file = models.FileField(upload_to='documents/')
|
||
description = models.TextField(blank=True)
|
||
uploaded_at = models.DateTimeField(auto_now_add=True)
|
||
|
||
def __str__(self):
|
||
return self.file.name
|
||
|
||
class Note(models.Model):
|
||
tender = models.ForeignKey(Tender, on_delete=models.CASCADE)
|
||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||
note = models.TextField()
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
|
||
def __str__(self):
|
||
return f"Note on {self.tender.title} by {self.user.username}"
|
||
|
||
class Approval(models.Model):
|
||
STATUS_CHOICES = [
|
||
('pending', 'Pending'),
|
||
('approved', 'Approved'),
|
||
('rejected', 'Rejected'),
|
||
]
|
||
bid = models.ForeignKey(Bid, on_delete=models.CASCADE)
|
||
approver = models.ForeignKey(User, on_delete=models.CASCADE)
|
||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
|
||
comments = models.TextField(blank=True)
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
updated_at = models.DateTimeField(auto_now=True)
|
||
|
||
def __str__(self):
|
||
return f"Approval for {self.bid} by {self.approver.username}"
|