feat(core): Add manufacturers

!10 #12
This commit is contained in:
2024-05-23 20:31:53 +09:30
parent a6a0da72b2
commit ef463b845d
11 changed files with 395 additions and 3 deletions

View File

@ -0,0 +1,32 @@
# Generated by Django 5.0.6 on 2024-05-23 10:58
import access.fields
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('access', '0002_alter_team_organization'),
('core', '0004_notes_is_null'),
]
operations = [
migrations.CreateModel(
name='Manufacturer',
fields=[
('is_global', models.BooleanField(default=False)),
('id', models.AutoField(primary_key=True, serialize=False, unique=True)),
('created', access.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False)),
('modified', access.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False)),
('name', models.CharField(max_length=50, unique=True)),
('slug', access.fields.AutoSlugField()),
('organization', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='access.organization')),
],
options={
'ordering': ['name'],
},
),
]

View File

@ -0,0 +1,43 @@
from django.contrib.auth.models import User
from django.db import models
from access.fields import *
from access.models import TenancyObject
from core.mixin.history_save import SaveHistory
class ManufacturerCommonFields(models.Model):
class Meta:
abstract = True
id = models.AutoField(
primary_key=True,
unique=True,
blank=False
)
created = AutoCreatedField()
modified = AutoCreatedField()
class Manufacturer(TenancyObject, ManufacturerCommonFields, SaveHistory):
class Meta:
ordering = [
'name'
]
name = models.CharField(
blank = False,
max_length = 50,
unique = True,
)
slug = AutoSlugField()

View File

@ -32,13 +32,17 @@ div#content article h3 {
</style>
<div id="content" style="">
<article style="">
<h3>Common</h3>
<ul>
<li><a href="{% url 'Settings:_manufacturers' %}">Manufacturers / Publishers</a></li>
</ul>
</article>
<article style="">
<h3>ITAM</h3>
<ul>
<li><a href="{% url 'Settings:_device_types' %}">Device Types</a></li>
<li><a href="">Manufacturers / Publishers</a></li>
<li><a href="">Models</a></li>
<li><a href="{% url 'Settings:_software_categories' %}">Software Categories</a></li>
</ul>
</article>

View File

@ -0,0 +1,43 @@
{% extends 'base.html.j2' %}
{% block content_header_icon %}{% endblock %}
{% block body %}
<input type="button" value="<< Back to settings" onclick="window.location='{% url 'Settings:Settings' %}';">
<input type="button" value="New Manufacturer" onclick="window.location='{% url 'Settings:_manufacturer_add' %}';">
<table class="data">
<tr>
<th>Name</th>
<th>Organization</th>
<th>&nbsp;</th>
</tr>
{% for item in list %}
<tr>
<td><a href="{% url 'Settings:_manufacturer_view' pk=item.id %}">{{ item.name }}</a></td>
<td>{% if item.is_global %}Global{% else %}{{ item.organization }}{% endif %}</td>
<td><a href="{% url 'Settings:_manufacturer_delete' pk=item.id %}">Delete</a></td>
</tr>
{% endfor %}
</table>
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">&laquo; first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
{% endif %}
</span>
</div>
{% endblock %}

View File

@ -0,0 +1,19 @@
from django.test import TestCase, Client
import pytest
import unittest
import requests
@pytest.mark.skip(reason="to be written")
def test_manufacturer_create_has_organization():
""" Devices must be assigned an organization """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_edit_has_organization():
""" Devices must be assigned an organization """
pass

View File

@ -0,0 +1,31 @@
from django.test import TestCase, Client
import pytest
import unittest
import requests
@pytest.mark.skip(reason="to be written")
def test_history_auth_view():
""" User requires Permission view_history """
pass
@pytest.mark.skip(reason="to be written")
def test_history_manufacturer_create():
""" History row must be added to history table on create """
pass
@pytest.mark.skip(reason="to be written")
def test_history_manufacturer_update():
""" History row must be added to history table on updatej """
pass
@pytest.mark.skip(reason="to be written")
def test_history_manufacturer_delete():
""" History row must be added to history table on delete """
pass

View File

@ -0,0 +1,32 @@
# from django.conf import settings
# from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_view():
""" Check correct permission for view """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_add():
""" Check correct permission for add """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_change():
""" Check correct permission for change """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_delete():
""" Check correct permission for delete """
pass

View File

@ -0,0 +1,32 @@
# from django.conf import settings
# from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_view_api():
""" Check correct permission for view """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_add_api():
""" Check correct permission for add """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_change_api():
""" Check correct permission for change """
pass
@pytest.mark.skip(reason="to be written")
def test_manufacturer_auth_delete_api():
""" Check correct permission for delete """
pass

View File

@ -1,6 +1,6 @@
from django.urls import path
from .views import home, device_types, software_categories
from .views import home, device_types, manufacturer, software_categories
from itam.views import device_type, software_category
@ -19,4 +19,9 @@ urlpatterns = [
path("software_category/add/", software_category.Add.as_view(), name="_software_category_add"),
path("software_category/<int:pk>/delete", software_category.Delete.as_view(), name="_software_category_delete"),
path("manufacturers", manufacturer.Index.as_view(), name="_manufacturers"),
path("manufacturer/<int:pk>", manufacturer.View.as_view(), name="_manufacturer_view"),
path("manufacturer/add/", manufacturer.Add.as_view(), name="_manufacturer_add"),
path("manufacturer/<int:pk>/delete", manufacturer.Delete.as_view(), name="_manufacturer_delete"),
]

View File

@ -0,0 +1,132 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.db.models import Q
from django.views import generic
from access.mixin import OrganizationPermission
from core.models.manufacturer import Manufacturer
class Index(PermissionRequiredMixin, OrganizationPermission, generic.ListView):
context_object_name = "list"
model = Manufacturer
paginate_by = 10
permission_required = 'itam.view_devicetype'
template_name = 'settings/manufacturers.html.j2'
def get_queryset(self):
if self.request.user.is_superuser:
return self.model.objects.filter().order_by('name')
else:
return self.model.objects.filter(Q(organization__in=self.user_organizations()) | Q(is_global = True)).order_by('name')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Manufacturers'
return context
class View(OrganizationPermission, generic.UpdateView):
context_object_name = "manufacturer"
fields = [
"name",
'slug',
'id',
'organization',
'is_global',
]
model = Manufacturer
permission_required = [
'itam.view_manufacturer'
]
template_name = 'form.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['model_pk'] = self.kwargs['pk']
context['model_name'] = self.model._meta.verbose_name.replace(' ', '')
context['content_title'] = self.object.name
return context
def get_success_url(self, **kwargs):
return f"/settings/manufacturer/{self.kwargs['pk']}"
class Add(PermissionRequiredMixin, OrganizationPermission, generic.CreateView):
fields = [
'name',
'organization',
'is_global'
]
model = Manufacturer
permission_required = [
'access.add_manufacturere',
]
template_name = 'form.html.j2'
def get_success_url(self, **kwargs):
return f"/settings/manufacturers"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Add Manufacturer'
return context
class Delete(PermissionRequiredMixin, OrganizationPermission, generic.DeleteView):
model = Manufacturer
permission_required = [
'access.delete_manufacturer',
]
def get_success_url(self, **kwargs):
return f"/settings/manufacturers"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Delete ' + self.object.name
return context