from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth import login, authenticate, logout from django.contrib.auth.decorators import login_required from .forms import SignUpForm, CompanyForm, TenderForm, BidForm, DocumentForm, NoteForm, ApprovalForm from .models import Company, Membership, Tender, Bid, Document, Note, Approval from .decorators import group_required def home(request): return render(request, "core/index.html") @login_required def dashboard(request): memberships = Membership.objects.filter(user=request.user) companies = [m.company for m in memberships] context = { 'companies': companies } return render(request, "core/dashboard.html", context) def signup(request): if request.method == 'POST': form = SignUpForm(request.POST) if form.is_valid(): user = form.save() login(request, user) return redirect('dashboard') else: form = SignUpForm() return render(request, 'core/signup.html', {'form': form}) def logout_view(request): logout(request) return redirect('home') @login_required def create_company(request): if request.method == 'POST': form = CompanyForm(request.POST) if form.is_valid(): company = form.save() Membership.objects.create(user=request.user, company=company, role='owner') return redirect('dashboard') else: form = CompanyForm() return render(request, 'core/create_company.html', {'form': form}) @login_required def tender_list(request, company_id): company = get_object_or_404(Company, pk=company_id) tenders = Tender.objects.filter(company=company) context = { 'company': company, 'tenders': tenders } return render(request, 'core/tender_list.html', context) @login_required def tender_detail(request, tender_id): tender = get_object_or_404(Tender, pk=tender_id) bids = Bid.objects.filter(tender=tender) documents = Document.objects.filter(tender=tender) notes = Note.objects.filter(tender=tender) if request.method == 'POST': if 'submit_document' in request.POST: doc_form = DocumentForm(request.POST, request.FILES) if doc_form.is_valid(): document = doc_form.save(commit=False) document.tender = tender document.uploaded_by = request.user document.save() return redirect('tender_detail', tender_id=tender.id) elif 'submit_note' in request.POST: note_form = NoteForm(request.POST) if note_form.is_valid(): note = note_form.save(commit=False) note.tender = tender note.user = request.user note.save() return redirect('tender_detail', tender_id=tender.id) doc_form = DocumentForm() note_form = NoteForm() # Workflow logic current_status_index = [i for i, (value, display) in enumerate(Tender.STATUS_CHOICES) if value == tender.status][0] next_status = Tender.STATUS_CHOICES[current_status_index + 1] if current_status_index + 1 < len(Tender.STATUS_CHOICES) else None context = { 'tender': tender, 'bids': bids, 'documents': documents, 'notes': notes, 'doc_form': doc_form, 'note_form': note_form, 'next_status': next_status, } return render(request, 'core/tender_detail.html', context) @login_required @group_required(['Head of Bids', 'Bid Administrator']) def update_tender_status(request, tender_id, next_status): tender = get_object_or_404(Tender, pk=tender_id) # Find the index of the current status current_status_index = [i for i, (value, display) in enumerate(Tender.STATUS_CHOICES) if value == tender.status][0] # Find the index of the next status next_status_index = [i for i, (value, display) in enumerate(Tender.STATUS_CHOICES) if value == next_status][0] # Check if the next status is valid if next_status_index == current_status_index + 1: tender.status = next_status tender.save() return redirect('tender_detail', tender_id=tender.id) @login_required def create_tender(request, company_id): company = get_object_or_404(Company, pk=company_id) if request.method == 'POST': form = TenderForm(request.POST) if form.is_valid(): tender = form.save(commit=False) tender.company = company tender.save() return redirect('tender_list', company_id=company.id) else: form = TenderForm() context = { 'form': form, 'company': company } return render(request, 'core/create_tender.html', context) @login_required def update_tender(request, tender_id): tender = get_object_or_404(Tender, pk=tender_id) if request.method == 'POST': form = TenderForm(request.POST, instance=tender) if form.is_valid(): form.save() return redirect('tender_detail', tender_id=tender.id) else: form = TenderForm(instance=tender) context = { 'form': form, 'tender': tender } return render(request, 'core/update_tender.html', context) @login_required def delete_tender(request, tender_id): tender = get_object_or_404(Tender, pk=tender_id) if request.method == 'POST': company_id = tender.company.id tender.delete() return redirect('tender_list', company_id=company_id) context = { 'tender': tender } return render(request, 'core/delete_tender.html', context) @login_required def create_bid(request, tender_id): tender = get_object_or_404(Tender, pk=tender_id) membership = Membership.objects.filter(user=request.user).first() if not membership: # Handle case where user has no company return redirect('dashboard') # Or show an error company = membership.company if request.method == 'POST': form = BidForm(request.POST) if form.is_valid(): bid = form.save(commit=False) bid.tender = tender bid.company = company bid.save() return redirect('tender_detail', tender_id=tender.id) else: form = BidForm() context = { 'form': form, 'tender': tender } return render(request, 'core/create_bid.html', context) @login_required def update_bid(request, bid_id): bid = get_object_or_404(Bid, pk=bid_id) if request.method == 'POST': form = BidForm(request.POST, instance=bid) if form.is_valid(): form.save() return redirect('tender_detail', tender_id=bid.tender.id) else: form = BidForm(instance=bid) context = { 'form': form, 'bid': bid } return render(request, 'core/update_bid.html', context) @login_required def delete_bid(request, bid_id): bid = get_object_or_404(Bid, pk=bid_id) if request.method == 'POST': tender_id = bid.tender.id bid.delete() return redirect('tender_detail', tender_id=tender_id) context = { 'bid': bid } return render(request, 'core/delete_bid.html', context) @login_required def approve_bid(request, bid_id): bid = get_object_or_404(Bid, pk=bid_id) approval, created = Approval.objects.get_or_create(bid=bid, approver=request.user) if request.method == 'POST': form = ApprovalForm(request.POST, instance=approval) if form.is_valid(): form.save() return redirect('tender_detail', tender_id=bid.tender.id) else: form = ApprovalForm(instance=approval) context = { 'form': form, 'bid': bid } return render(request, 'core/approve_bid.html', context) @login_required def delete_document(request, document_id): document = get_object_or_404(Document, pk=document_id) if request.method == 'POST': tender_id = document.tender.id document.delete() return redirect('tender_detail', tender_id=tender_id) context = { 'document': document } return render(request, 'core/delete_document.html', context)