beneficiary list and create one
This commit is contained in:
parent
bc890cc49b
commit
ea88d92dc3
|
@ -18,12 +18,13 @@
|
|||
<i class="bi bi-tag"></i>
|
||||
{% trans 'properties' %}
|
||||
</a>
|
||||
{% if user %}
|
||||
{% if subscripted or user.is_admin %}
|
||||
<a href="{% url 'lot:subscription' object.id %}" type="button" class="btn btn-green-admin">
|
||||
<i class="bi bi-tag"></i>
|
||||
{% trans 'Subscription' %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if is_circuit_manager %}
|
||||
{% if donor %}
|
||||
<a href="{% url 'lot:del_donor' object.id %}" type="button" class="btn btn-green-admin">
|
||||
<i class="bi bi-tag"></i>
|
||||
|
@ -36,6 +37,13 @@
|
|||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if is_shop %}
|
||||
<a href="{% url 'lot:beneficiary' object.id %}" type="button" class="btn btn-green-admin">
|
||||
<i class="bi bi-tag"></i>
|
||||
{% trans 'Beneficiary' %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
import json
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic.edit import FormView
|
||||
from django.shortcuts import Http404
|
||||
from django.db.models import Q
|
||||
|
||||
from dashboard.mixins import InventaryMixin, DetailsMixin
|
||||
from evidence.models import SystemProperty
|
||||
from evidence.xapian import search
|
||||
from device.models import Device
|
||||
from lot.models import Lot, Donor
|
||||
from lot.models import Lot, LotSubscription, Donor
|
||||
|
||||
|
||||
class UnassignedDevicesView(InventaryMixin):
|
||||
|
@ -42,15 +40,23 @@ class LotDashboardView(InventaryMixin, DetailsMixin):
|
|||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
lot = context.get('object')
|
||||
donor = Donor.objects.filter(
|
||||
subscriptions = LotSubscription.objects.filter(
|
||||
lot=lot,
|
||||
user=self.request.user
|
||||
)
|
||||
is_shop = subscriptions.filter(type=LotSubscription.Type.SHOP).first()
|
||||
is_circuit_manager = subscriptions.filter(
|
||||
type=LotSubscription.Type.CIRCUIT_MANAGER
|
||||
).first()
|
||||
|
||||
if donor:
|
||||
context["donor"] = donor
|
||||
donor = Donor.objects.filter(lot=lot).first()
|
||||
|
||||
context.update({
|
||||
'lot': lot,
|
||||
'subscripted': subscriptions.first(),
|
||||
'is_circuit_manager': is_circuit_manager,
|
||||
'is_shop': is_shop,
|
||||
'donor': donor,
|
||||
})
|
||||
return context
|
||||
|
||||
|
|
42
lot/forms.py
42
lot/forms.py
|
@ -2,7 +2,12 @@ from django.utils.translation import gettext_lazy as _
|
|||
from django.core.exceptions import ValidationError
|
||||
from django import forms
|
||||
from user.models import User
|
||||
from lot.models import Lot, LotSubscription, Donor
|
||||
from lot.models import (
|
||||
Lot,
|
||||
LotSubscription,
|
||||
Beneficiary,
|
||||
Donor,
|
||||
)
|
||||
|
||||
|
||||
class LotsForm(forms.Form):
|
||||
|
@ -31,6 +36,41 @@ class LotsForm(forms.Form):
|
|||
return
|
||||
|
||||
|
||||
class BeneficiaryForm(forms.Form):
|
||||
beneficiary = forms.CharField()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.shop = kwargs.pop("shop")
|
||||
self.lot_pk = kwargs.pop("lot_pk")
|
||||
self.devices = kwargs.pop("devices", [])
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
self._beneficiary = self.cleaned_data.get("beneficiary")
|
||||
return self._beneficiary
|
||||
|
||||
def save(self, commit=True):
|
||||
if not commit:
|
||||
return
|
||||
|
||||
Beneficiary.objects.create(
|
||||
email=self._beneficiary,
|
||||
lot_id=self.lot_pk,
|
||||
shop=self.shop
|
||||
)
|
||||
|
||||
for dev in self.devices:
|
||||
for ben in self._beneficiary:
|
||||
ben.add(dev.id)
|
||||
return
|
||||
|
||||
def remove(self):
|
||||
for dev in self.devices:
|
||||
for ben in self._beneficiary:
|
||||
ben.remove(dev.id)
|
||||
return
|
||||
|
||||
|
||||
class LotSubscriptionForm(forms.Form):
|
||||
user = forms.CharField()
|
||||
type = forms.ChoiceField(
|
||||
|
|
72
lot/migrations/0010_beneficiary_devicebeneficiary.py
Normal file
72
lot/migrations/0010_beneficiary_devicebeneficiary.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Generated by Django 5.0.6 on 2025-03-13 11:57
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("lot", "0009_donor_lotsubscription_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Beneficiary",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
(
|
||||
"sign_conditions",
|
||||
models.BooleanField(default=False, verbose_name="Conditions"),
|
||||
),
|
||||
(
|
||||
"email",
|
||||
models.EmailField(max_length=255, verbose_name="Email address"),
|
||||
),
|
||||
(
|
||||
"lot",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="lot.lot"
|
||||
),
|
||||
),
|
||||
(
|
||||
"shop",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="lot.lotsubscription",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="DeviceBeneficiary",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("device_id", models.CharField(max_length=256)),
|
||||
(
|
||||
"beneficiary",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="lot.beneficiary",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -95,3 +95,19 @@ class Donor(models.Model):
|
|||
_('Email address'),
|
||||
max_length=255,
|
||||
)
|
||||
|
||||
|
||||
class Beneficiary(models.Model):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
sign_conditions = models.BooleanField(_("Conditions"), default=False)
|
||||
lot = models.ForeignKey(Lot, on_delete=models.CASCADE)
|
||||
shop = models.ForeignKey(LotSubscription, on_delete=models.CASCADE)
|
||||
email = models.EmailField(
|
||||
_('Email address'),
|
||||
max_length=255,
|
||||
)
|
||||
|
||||
|
||||
class DeviceBeneficiary(models.Model):
|
||||
beneficiary = models.ForeignKey("Beneficiary", on_delete=models.CASCADE)
|
||||
device_id = models.CharField(max_length=STR_EXTEND_SIZE, blank=False, null=False)
|
||||
|
|
73
lot/templates/beneficiaries.html
Normal file
73
lot/templates/beneficiaries.html
Normal file
|
@ -0,0 +1,73 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ subtitle }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if beneficiaries %}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table table-hover table-bordered align-middel">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Beneficiary' %}</th>
|
||||
<th scope="col">{% trans 'Shop' %}</th>
|
||||
<th scope="col">{% trans 'Sign conditions' %}</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for s in beneficiaries %}
|
||||
<tr>
|
||||
<td class="font-monospace">{{ s.email }}</td>
|
||||
<td class="font-monospace">{{ s.shop.user.email }}</td>
|
||||
<td class="font-monospace">{{ s.sign_conditions }}</td>
|
||||
<td class="font-monospace">
|
||||
<a href="{# url 'lot:unsubscription' lot.id s.id #}">
|
||||
{% trans 'Delete' %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="mt-4">
|
||||
<button class="btn btn-green-admin" type="button" data-bs-toggle="collapse" data-bs-target="#add_beneficiarie">
|
||||
{% trans 'Add Beneficiarie' %}
|
||||
</button>
|
||||
|
||||
<div class="collapse mt-3" id="add_beneficiarie">
|
||||
<div class="card card-body">
|
||||
{% trans 'Add an email of beneficiary' %}.
|
||||
</div>
|
||||
{% load django_bootstrap5 %}
|
||||
<form role="form" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
|
||||
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
|
||||
<div class="message">
|
||||
{% for field, error in form.errors.items %}
|
||||
{{ error }}<br />
|
||||
{% endfor %}
|
||||
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% bootstrap_form form %}
|
||||
<div class="form-actions-no-box">
|
||||
<a class="btn btn-grey" href="{% url 'dashboard:lot' lot.id %}">{% translate "Cancel" %}</a>
|
||||
<input class="btn btn-green-admin" type="submit" name="submit" value="{{ action }}" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -20,4 +20,5 @@ urlpatterns = [
|
|||
path("<int:pk>/donor/del", views.DelDonorView.as_view(), name="del_donor"),
|
||||
path("<int:pk>/donor/<uuid:id>", views.DonorView.as_view(), name="web_donor"),
|
||||
path("<int:pk>/donor/<uuid:id>/accept", views.AcceptDonorView.as_view(), name="accept_donor"),
|
||||
path("<int:pk>/beneficiary", views.BeneficiaryView.as_view(), name="beneficiary"),
|
||||
]
|
||||
|
|
74
lot/views.py
74
lot/views.py
|
@ -13,8 +13,16 @@ from django.views.generic.edit import (
|
|||
from dashboard.mixins import DashboardView
|
||||
from evidence.models import SystemProperty
|
||||
from device.models import Device
|
||||
from lot.models import Lot, LotTag, LotProperty, LotSubscription, Donor
|
||||
from lot.forms import LotsForm, LotSubscriptionForm, AddDonorForm
|
||||
from lot.forms import LotsForm, LotSubscriptionForm, AddDonorForm, BeneficiaryForm
|
||||
from lot.models import (
|
||||
Lot,
|
||||
LotTag,
|
||||
LotProperty,
|
||||
LotSubscription,
|
||||
Beneficiary,
|
||||
Donor
|
||||
)
|
||||
|
||||
|
||||
class NewLotView(DashboardView, CreateView):
|
||||
template_name = "new_lot.html"
|
||||
|
@ -289,9 +297,11 @@ class SubscriptLotView(DashboardView, FormView):
|
|||
self.pk = self.kwargs.get('pk')
|
||||
context = super().get_context_data(**kwargs)
|
||||
self.get_lot()
|
||||
subscriptors = []
|
||||
if self.request.user.is_admin:
|
||||
subscriptors = LotSubscription.objects.filter(lot=self.lot)
|
||||
user_subscripted = subscriptors.filter(user=self.request.user).first()
|
||||
|
||||
if not self.request.user.is_admin and not user_subscripted:
|
||||
subscriptors = []
|
||||
|
||||
context.update({
|
||||
'lot': self.lot,
|
||||
|
@ -486,3 +496,59 @@ class AcceptDonorView(TemplateView):
|
|||
# self.send_email()
|
||||
|
||||
return redirect(self.success_url)
|
||||
|
||||
|
||||
class BeneficiaryView(DashboardView, FormView):
|
||||
template_name = "beneficiaries.html"
|
||||
title = _("Beneficiaries")
|
||||
breadcrumb = "Lot / Beneficiary"
|
||||
form_class = BeneficiaryForm
|
||||
lot = None
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
self.pk = self.kwargs.get('pk')
|
||||
context = super().get_context_data(**kwargs)
|
||||
self.get_lot()
|
||||
|
||||
self.is_shop = LotSubscription.objects.filter(
|
||||
lot=self.lot,
|
||||
user=self.request.user,
|
||||
type=LotSubscription.Type.SHOP
|
||||
).first()
|
||||
|
||||
beneficiaries = []
|
||||
if self.request.user.is_admin or self.is_shop:
|
||||
beneficiaries = Beneficiary.objects.filter(lot=self.lot)
|
||||
|
||||
context.update({
|
||||
'lot': self.lot,
|
||||
'beneficiaries': beneficiaries,
|
||||
"action": _("Add")
|
||||
})
|
||||
return context
|
||||
|
||||
def get_form_kwargs(self):
|
||||
self.pk = self.kwargs.get('pk')
|
||||
self.success_url = reverse_lazy('dashboard:lot', args=[self.pk])
|
||||
self.is_shop = LotSubscription.objects.filter(
|
||||
lot_id=self.pk,
|
||||
user=self.request.user,
|
||||
type=LotSubscription.Type.SHOP
|
||||
).first()
|
||||
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs["shop"] = self.is_shop
|
||||
kwargs["lot_pk"] = self.pk
|
||||
return kwargs
|
||||
|
||||
def get_lot(self):
|
||||
self.lot = get_object_or_404(
|
||||
Lot,
|
||||
owner=self.request.user.institution,
|
||||
id=self.pk
|
||||
)
|
||||
|
||||
def form_valid(self, form):
|
||||
form.save()
|
||||
response = super().form_valid(form)
|
||||
return response
|
||||
|
|
Loading…
Reference in a new issue