made the stock view more ugly by adding badges showing the number of stored parts, lots and substorages

This commit is contained in:
Stefan Strobel 2025-01-28 22:38:17 +01:00
parent aefcc472ea
commit 6ae94e9ea4
4 changed files with 32 additions and 8 deletions

View File

@ -75,6 +75,9 @@ class Storage(models.Model):
null=True, null=True,
related_name='template_of') related_name='template_of')
# caching variable for subtrees
storage_list = None
def get_path_components(self): def get_path_components(self):
chain = [] chain = []
iterator = self iterator = self
@ -115,12 +118,18 @@ class Storage(models.Model):
else: else:
return self.storage_set.all() return self.storage_set.all()
def get_tree(self): @classmethod
self.sub_storages = [self] def get_substorage_list(cls, sub_storages):
for storage in self.storage_set.all(): sub_sub_storages = cls.objects.filter(parent_storage__in=sub_storages)
self.sub_storages += storage.get_tree()
return self.sub_storages final_sub_storages = sub_storages | sub_sub_storages
if sub_sub_storages:
final_sub_storages |= cls.get_substorage_list(sub_sub_storages)
return final_sub_storages
def get_storage_list(self):
return Storage.objects.filter(id=self.id) | self.get_substorage_list(self.storage_set.all())
def validate_unique(self, exclude=None): def validate_unique(self, exclude=None):
if Storage.objects.exclude(id=self.id).filter(name=self.name, parent_storage__isnull=True).exists(): if Storage.objects.exclude(id=self.id).filter(name=self.name, parent_storage__isnull=True).exists():
@ -132,12 +141,18 @@ class Storage(models.Model):
raise raise
def get_total_stock_amount(self): def get_total_stock_amount(self):
stocks = Stock.objects.filter(storage=self) stocks = Stock.objects.filter(storage__in=self.storage_list or self.get_storage_list())
sum = stocks.aggregate(Sum('amount'))['amount__sum'] sum = stocks.aggregate(Sum('amount'))['amount__sum']
if sum is None: if sum is None:
sum = 0 sum = 0
return sum return sum
def get_total_stock_count(self):
return Stock.objects.filter(storage__in=self.storage_list or self.get_storage_list()).count()
def get_total_substorage_amount(self):
return len(self.storage_list or self.get_storage_list()) - 1 # -1 as thhe storage list counts the parent storage as well
@classmethod @classmethod
def from_path(cls, path, root_storage=None): def from_path(cls, path, root_storage=None):
''' '''

View File

@ -76,7 +76,7 @@ class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView):
def search_stock_queryset(self, search): def search_stock_queryset(self, search):
if self.object.expand_sub_storage_stocks: if self.object.expand_sub_storage_stocks:
stocks_in_storage = Stock.objects.filter(storage__in=self.object.get_tree()) stocks_in_storage = Stock.objects.filter(storage__in=self.object.get_storage_list())
else: else:
stocks_in_storage = Stock.objects.filter(storage=self.object) stocks_in_storage = Stock.objects.filter(storage=self.object)

View File

@ -83,6 +83,13 @@
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]') const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl)) const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))
</script> </script>
<!-- Initialize bootstrap tooltips -->
<script type="text/javascript">
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>
<!-- Select search field on start of QR scan if no input is currently selevted([) --> <!-- Select search field on start of QR scan if no input is currently selevted([) -->
<script type="text/javascript"> <script type="text/javascript">
window.addEventListener("keydown", (event)=>{ window.addEventListener("keydown", (event)=>{

View File

@ -55,7 +55,9 @@
<h5>{{storage.name}}{% if storage.verbose_name %}<small> ({{storage.verbose_name}})</small>{% endif %}</h5> <h5>{{storage.name}}{% if storage.verbose_name %}<small> ({{storage.verbose_name}})</small>{% endif %}</h5>
Responsible: {{ storage.responsible }} Responsible: {{ storage.responsible }}
</div> </div>
<span class="badge bg-primary rounded-pill">{{storage.get_total_stock_amount}}</span> <span class="badge ms-1 bg-primary rounded-pill" data-bs-toggle="tooltip" data-bs-placement="top" title="Total number of stored parts">{{storage.get_total_stock_amount}}</span>
<span class="badge ms-1 bg-secondary rounded-pill" data-bs-toggle="tooltip" data-bs-placement="top" title="Number of stored lots">{{storage.get_total_stock_count}}</span>
<span class="badge ms-1 bg-info rounded-pill" data-bs-toggle="tooltip" data-bs-placement="top" title="Number of substorages">{{storage.get_total_substorage_amount}}</span>
</li> </li>
</a> </a>
{% endfor %} {% endfor %}