some fixes and improvements
This commit is contained in:
parent
19b2913a4e
commit
db751f7837
BIN
dbtest.sqlite3
Normal file
BIN
dbtest.sqlite3
Normal file
Binary file not shown.
@ -40,3 +40,46 @@ def breadcrumbs(request):
|
|||||||
url = "/" + "/".join(path[: i + 1]) + "/"
|
url = "/" + "/".join(path[: i + 1]) + "/"
|
||||||
breadcrumbs.append({"name": path[i].capitalize(), "url": url})
|
breadcrumbs.append({"name": path[i].capitalize(), "url": url})
|
||||||
return {"breadcrumbs": breadcrumbs}
|
return {"breadcrumbs": breadcrumbs}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def user_types(request):
|
||||||
|
"""
|
||||||
|
Sets various flags indicating the user's role types.
|
||||||
|
|
||||||
|
The flags are:
|
||||||
|
|
||||||
|
- request.is_dealer
|
||||||
|
- request.is_staff
|
||||||
|
- request.is_manager
|
||||||
|
- request.is_accountant
|
||||||
|
- request.is_sales
|
||||||
|
- request.is_inventory
|
||||||
|
|
||||||
|
:param request: The request object to set the flags upon.
|
||||||
|
:type request: HttpRequest
|
||||||
|
"""
|
||||||
|
request.is_dealer = False
|
||||||
|
request.is_staff = False
|
||||||
|
request.is_manager = False
|
||||||
|
request.is_accountant = False
|
||||||
|
request.is_sales = False
|
||||||
|
request.is_inventory = False
|
||||||
|
if hasattr(request.user, "dealer"):
|
||||||
|
request.is_dealer = True
|
||||||
|
elif hasattr(request.user, "staffmember"):
|
||||||
|
request.is_staff = True
|
||||||
|
staff = getattr(request.user.staffmember, "staff")
|
||||||
|
if "Accountant" in staff.groups.values_list("name", flat=True):
|
||||||
|
request.is_accountant = True
|
||||||
|
return {"is_accountant": True}
|
||||||
|
elif "Manager" in staff.groups.values_list("name", flat=True):
|
||||||
|
request.is_manager = True
|
||||||
|
return {"is_manager": True}
|
||||||
|
elif "Sales" in staff.groups.values_list("name", flat=True):
|
||||||
|
request.is_sales = True
|
||||||
|
return {"is_sales": True}
|
||||||
|
elif "Inventory" in staff.groups.values_list("name", flat=True):
|
||||||
|
request.is_inventory = True
|
||||||
|
return {"is_inventory": True}
|
||||||
|
return {}
|
||||||
|
|||||||
@ -107,11 +107,11 @@ class InjectDealerMiddleware:
|
|||||||
staff = getattr(request.user.staffmember, "staff")
|
staff = getattr(request.user.staffmember, "staff")
|
||||||
if "Accountant" in staff.groups.values_list("name", flat=True):
|
if "Accountant" in staff.groups.values_list("name", flat=True):
|
||||||
request.is_accountant = True
|
request.is_accountant = True
|
||||||
if "Manager" in staff.groups.values_list("name", flat=True):
|
elif "Manager" in staff.groups.values_list("name", flat=True):
|
||||||
request.is_manager = True
|
request.is_manager = True
|
||||||
if "Sales" in staff.groups.values_list("name", flat=True):
|
elif "Sales" in staff.groups.values_list("name", flat=True):
|
||||||
request.is_sales = True
|
request.is_sales = True
|
||||||
if "Inventory" in staff.groups.values_list("name", flat=True):
|
elif "Inventory" in staff.groups.values_list("name", flat=True):
|
||||||
request.is_inventory = True
|
request.is_inventory = True
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('appointment', '0001_initial'),
|
('appointment', '__first__'),
|
||||||
('auth', '0012_alter_user_first_name_max_length'),
|
('auth', '0012_alter_user_first_name_max_length'),
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'),
|
('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'),
|
||||||
|
|||||||
@ -1199,17 +1199,20 @@ class Staff(models.Model, LocalizedNameMixin):
|
|||||||
self.clear_groups()
|
self.clear_groups()
|
||||||
try:
|
try:
|
||||||
self.user.groups.add(group)
|
self.user.groups.add(group)
|
||||||
if "accountant" in group.name.lower() or "manager" in group.name.lower():
|
if "accountant" in group.name.lower():
|
||||||
self.add_superuser_permission()
|
self.add_superuser_permission()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
def add_superuser_permission(self):
|
def add_superuser_permission(self):
|
||||||
pass
|
entity = self.dealer.entity
|
||||||
# self.dealer.entity.managers.add(self.user)
|
if entity.managers.count() == 0:
|
||||||
|
entity.managers.add(self.user)
|
||||||
def remove_superuser_permission(self):
|
def remove_superuser_permission(self):
|
||||||
pass
|
entity = self.dealer.entity
|
||||||
# self.dealer.entity.managers.remove(self.user)
|
if self.user in entity.managers.all():
|
||||||
|
entity.managers.remove(self.user)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Staff")
|
verbose_name = _("Staff")
|
||||||
@ -2708,7 +2711,8 @@ class CustomGroup(models.Model):
|
|||||||
"tasks",
|
"tasks",
|
||||||
"activity",
|
"activity",
|
||||||
"payment",
|
"payment",
|
||||||
'vendor'],
|
"vendor",
|
||||||
|
],
|
||||||
other_perms=[
|
other_perms=[
|
||||||
"view_car",
|
"view_car",
|
||||||
"view_carlocation",
|
"view_carlocation",
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from .models import Dealer
|
||||||
from django.core.exceptions import ImproperlyConfigured,ValidationError
|
from django.core.exceptions import ImproperlyConfigured,ValidationError
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin,PermissionRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin,PermissionRequiredMixin
|
||||||
from django_ledger.forms.bill import (
|
from django_ledger.forms.bill import (
|
||||||
@ -30,7 +31,8 @@ from django_ledger.models import PurchaseOrderModel,EstimateModel,BillModel
|
|||||||
from django.views.generic.detail import SingleObjectMixin
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
from django.views.generic.edit import UpdateView
|
from django.views.generic.edit import UpdateView
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
from .models import Dealer
|
from django.views.generic.list import ListView
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -319,7 +321,12 @@ class BasePurchaseOrderActionActionView(LoginRequiredMixin,
|
|||||||
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
||||||
f"Error: {e}"
|
f"Error: {e}"
|
||||||
)
|
)
|
||||||
print(e)
|
except AttributeError as e:
|
||||||
|
logger.warning(
|
||||||
|
f"User {user_username} encountered an AttributeError "
|
||||||
|
f"while performing action '{self.action_name}' on Purchase Order ID: {po_model.pk}. "
|
||||||
|
f"Error: {e}"
|
||||||
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
class BillModelDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
class BillModelDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||||
@ -642,3 +649,41 @@ class BaseBillActionView(LoginRequiredMixin,PermissionRequiredMixin, RedirectVie
|
|||||||
level=messages.ERROR,
|
level=messages.ERROR,
|
||||||
extra_tags='is-danger')
|
extra_tags='is-danger')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||||
|
template_name = 'django_ledger/inventory/inventory_list.html'
|
||||||
|
context_object_name = 'inventory_list'
|
||||||
|
http_method_names = ['get']
|
||||||
|
|
||||||
|
def get_context_data(self, *, object_list=None, **kwargs):
|
||||||
|
context = super(InventoryListView, self).get_context_data(**kwargs)
|
||||||
|
qs = self.get_queryset()
|
||||||
|
|
||||||
|
# evaluates the queryset...
|
||||||
|
context['qs_count'] = qs.count()
|
||||||
|
|
||||||
|
# ordered inventory...
|
||||||
|
ordered_qs = qs.is_ordered()
|
||||||
|
context['inventory_ordered'] = ordered_qs
|
||||||
|
|
||||||
|
# in transit inventory...
|
||||||
|
in_transit_qs = qs.in_transit()
|
||||||
|
context['inventory_in_transit'] = in_transit_qs
|
||||||
|
|
||||||
|
# on hand inventory...
|
||||||
|
received_qs = qs.is_received()
|
||||||
|
context['inventory_received'] = received_qs
|
||||||
|
|
||||||
|
context['page_title'] = _('Inventory')
|
||||||
|
context['header_title'] = _('Inventory Status')
|
||||||
|
context['header_subtitle'] = _('Ordered/In Transit/On Hand')
|
||||||
|
context['header_subtitle_icon'] = 'ic:round-inventory'
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
if self.queryset is None:
|
||||||
|
self.queryset = ItemTransactionModel.objects.inventory_pipeline_aggregate(
|
||||||
|
entity_slug=self.kwargs['entity_slug'],
|
||||||
|
)
|
||||||
|
return super().get_queryset()
|
||||||
@ -1092,6 +1092,6 @@ def bill_model_after_approve_notification(sender, instance, created, **kwargs):
|
|||||||
message=f"""
|
message=f"""
|
||||||
Bill {instance.bill_number} has been approved.
|
Bill {instance.bill_number} has been approved.
|
||||||
<a href="{reverse('bill-detail', kwargs={'dealer_slug': dealer.slug, 'entity_slug':dealer.entity.slug, 'bill_pk': instance.pk})}" target="_blank">View</a>.
|
<a href="{reverse('bill-detail', kwargs={'dealer_slug': dealer.slug, 'entity_slug':dealer.entity.slug, 'bill_pk': instance.pk})}" target="_blank">View</a>.
|
||||||
please comlete the bill payment.
|
please complete the bill payment.
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
1137
inventory/tasks.py
1137
inventory/tasks.py
File diff suppressed because it is too large
Load Diff
@ -88,7 +88,6 @@ from django_ledger.views import (
|
|||||||
LedgerModelCreateView as LedgerModelCreateViewBase,
|
LedgerModelCreateView as LedgerModelCreateViewBase,
|
||||||
)
|
)
|
||||||
from django_ledger.forms.account import AccountModelCreateForm, AccountModelUpdateForm
|
from django_ledger.forms.account import AccountModelCreateForm, AccountModelUpdateForm
|
||||||
from django_ledger.views.inventory import InventoryListView as InventoryListViewBase
|
|
||||||
from django_ledger.views.entity import (
|
from django_ledger.views.entity import (
|
||||||
EntityModelDetailBaseView,
|
EntityModelDetailBaseView,
|
||||||
EntityModelDetailHandlerView,
|
EntityModelDetailHandlerView,
|
||||||
@ -143,6 +142,7 @@ from .override import (
|
|||||||
BillModelDetailView as BillModelDetailViewBase,
|
BillModelDetailView as BillModelDetailViewBase,
|
||||||
BillModelUpdateView as BillModelUpdateViewBase,
|
BillModelUpdateView as BillModelUpdateViewBase,
|
||||||
BaseBillActionView as BaseBillActionViewBase,
|
BaseBillActionView as BaseBillActionViewBase,
|
||||||
|
InventoryListView as InventoryListViewBase,
|
||||||
)
|
)
|
||||||
|
|
||||||
from django_ledger.models import (
|
from django_ledger.models import (
|
||||||
@ -10253,9 +10253,11 @@ def upload_cars(request, dealer_slug, pk=None):
|
|||||||
car_make = get_make(manufacturer_name)
|
car_make = get_make(manufacturer_name)
|
||||||
car_model = get_model(model_name, car_make)
|
car_model = get_model(model_name, car_make)
|
||||||
if (
|
if (
|
||||||
not all([car_make, car_model])
|
not all([car_make])
|
||||||
or (make.pk != car_make.pk)
|
or (make.pk != car_make.pk)
|
||||||
or (model.pk != car_model.pk)
|
# not all([car_make, car_model])
|
||||||
|
# or (make.pk != car_make.pk)
|
||||||
|
# or (model.pk != car_model.pk)
|
||||||
):
|
):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"User {user_username} uploaded CSV with VIN '{row['vin']}' "
|
f"User {user_username} uploaded CSV with VIN '{row['vin']}' "
|
||||||
@ -10368,12 +10370,3 @@ def bulk_update_car_price(request):
|
|||||||
class InventoryListView(InventoryListViewBase):
|
class InventoryListView(InventoryListViewBase):
|
||||||
template_name = "inventory/list.html"
|
template_name = "inventory/list.html"
|
||||||
permission_required = ["django_ledger.view_purchaseordermodel"]
|
permission_required = ["django_ledger.view_purchaseordermodel"]
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
dealer = get_user_type(self.request)
|
|
||||||
|
|
||||||
if self.queryset is None:
|
|
||||||
self.queryset = ItemTransactionModel.objects.inventory_pipeline_aggregate(
|
|
||||||
entity_slug=dealer.entity.slug,
|
|
||||||
)
|
|
||||||
return super().get_queryset()
|
|
||||||
|
|||||||
@ -1,126 +1,126 @@
|
|||||||
annotated-types==0.7.0
|
annotated-types
|
||||||
anyio==4.9.0
|
anyio
|
||||||
arrow==1.3.0
|
arrow
|
||||||
asgiref==3.8.1
|
asgiref
|
||||||
attrs==25.3.0
|
attrs
|
||||||
Babel==2.15.0
|
Babel
|
||||||
beautifulsoup4==4.13.4
|
beautifulsoup4
|
||||||
blessed==1.21.0
|
blessed
|
||||||
cattrs==24.1.3
|
cattrs
|
||||||
certifi==2025.1.31
|
certifi
|
||||||
cffi==1.17.1
|
cffi
|
||||||
charset-normalizer==3.4.1
|
charset-normalizer
|
||||||
click==8.2.1
|
click
|
||||||
colorama==0.4.6
|
colorama
|
||||||
crispy-bootstrap5==2024.10
|
crispy-bootstrap5
|
||||||
cryptography==44.0.2
|
cryptography
|
||||||
cssbeautifier==1.15.4
|
cssbeautifier
|
||||||
defusedxml==0.7.1
|
defusedxml
|
||||||
diff-match-patch==20241021
|
diff-match-patch
|
||||||
distro==1.9.0
|
distro
|
||||||
Django==5.2.3
|
Django
|
||||||
django-allauth==65.6.0
|
django-allauth
|
||||||
django-appointment==3.8.0
|
django-appointment
|
||||||
django-background-tasks==1.2.8
|
django-background-tasks
|
||||||
django-bootstrap5==25.1
|
django-bootstrap5
|
||||||
django-ckeditor==6.7.2
|
django-ckeditor
|
||||||
django-cors-headers==4.7.0
|
django-cors-headers
|
||||||
django-countries==7.6.1
|
django-countries
|
||||||
django-crispy-forms==2.3
|
django-crispy-forms
|
||||||
django-easy-audit==1.3.7
|
django-easy-audit
|
||||||
django-extensions==3.2.3
|
django-extensions
|
||||||
django-filter==25.1
|
django-filter
|
||||||
django-import-export==4.3.7
|
django-import-export
|
||||||
django-js-asset==3.1.2
|
django-js-asset
|
||||||
django-ledger==0.7.7
|
django-ledger
|
||||||
django-manager-utils==3.1.5
|
django-manager-utils
|
||||||
django-next-url-mixin==0.4.0
|
django-next-url-mixin
|
||||||
django-ordered-model==3.7.4
|
django-ordered-model
|
||||||
django-phonenumber-field==8.0.0
|
django-phonenumber-field
|
||||||
django-picklefield==3.3
|
django-picklefield
|
||||||
django-plans==2.0.0
|
django-plans
|
||||||
django-q2==1.8.0
|
django-q2
|
||||||
django-query-builder==3.2.0
|
django-query-builder
|
||||||
django-schema-graph==3.1.0
|
django-schema-graph
|
||||||
django-sequences==3.0
|
django-sequences
|
||||||
django-tables2==2.7.5
|
django-tables2
|
||||||
django-treebeard==4.7.1
|
django-treebeard
|
||||||
django-widget-tweaks==1.5.0
|
django-widget-tweaks
|
||||||
djangorestframework==3.15.2
|
djangorestframework
|
||||||
djhtml==3.0.7
|
djhtml
|
||||||
djlint==1.36.4
|
djlint
|
||||||
docopt==0.6.2
|
docopt
|
||||||
EditorConfig==0.17.0
|
EditorConfig
|
||||||
Faker==37.3.0
|
Faker
|
||||||
fleming==0.7.0
|
fleming
|
||||||
fonttools==4.57.0
|
fonttools
|
||||||
fpdf==1.7.2
|
fpdf
|
||||||
fpdf2==2.8.3
|
fpdf2
|
||||||
greenlet==3.2.2
|
greenlet
|
||||||
h11==0.14.0
|
h11
|
||||||
httpcore==1.0.7
|
httpcore
|
||||||
httpx==0.28.1
|
httpx
|
||||||
icalendar==6.1.2
|
icalendar
|
||||||
idna==3.10
|
idna
|
||||||
jiter==0.9.0
|
jiter
|
||||||
jsbeautifier==1.15.4
|
jsbeautifier
|
||||||
json5==0.12.0
|
json5
|
||||||
jsonpatch==1.33
|
jsonpatch
|
||||||
jsonpointer==3.0.0
|
jsonpointer
|
||||||
jwt==1.3.1
|
jwt
|
||||||
langchain==0.3.25
|
langchain
|
||||||
langchain-core==0.3.61
|
langchain-core
|
||||||
langchain-ollama==0.3.3
|
langchain-ollama
|
||||||
langchain-text-splitters==0.3.8
|
langchain-text-splitters
|
||||||
langsmith==0.3.42
|
langsmith
|
||||||
luhnchecker==0.0.12
|
luhnchecker
|
||||||
Markdown==3.8
|
Markdown
|
||||||
markdown-it-py==3.0.0
|
markdown-it-py
|
||||||
mdurl==0.1.2
|
mdurl
|
||||||
num2words==0.5.14
|
num2words
|
||||||
numpy==2.2.4
|
numpy
|
||||||
ofxtools==0.9.5
|
ofxtools
|
||||||
ollama==0.4.8
|
ollama
|
||||||
openai==1.68.2
|
openai
|
||||||
opencv-python==4.11.0.86
|
opencv-python
|
||||||
orjson==3.10.18
|
orjson
|
||||||
packaging==24.2
|
packaging
|
||||||
pandas==2.2.3
|
pandas
|
||||||
pathspec==0.12.1
|
pathspec
|
||||||
phonenumbers==8.13.42
|
phonenumbers
|
||||||
pillow==11.2.1
|
pillow
|
||||||
pycparser==2.22
|
pycparser
|
||||||
pydantic==2.10.6
|
pydantic
|
||||||
pydantic_core==2.27.2
|
pydantic_core
|
||||||
Pygments==2.19.1
|
Pygments
|
||||||
python-dateutil==2.9.0.post0
|
python-dateutil
|
||||||
python-slugify==8.0.4
|
python-slugify
|
||||||
python-stdnum==1.20
|
python-stdnum
|
||||||
pytz==2025.2
|
pytz
|
||||||
pyvin==0.0.2
|
pyvin
|
||||||
PyYAML==6.0.2
|
PyYAML
|
||||||
pyzbar==0.1.9
|
pyzbar
|
||||||
redis==3.5.3
|
redis
|
||||||
regex==2024.11.6
|
regex
|
||||||
requests==2.32.3
|
requests
|
||||||
requests-toolbelt==1.0.0
|
requests-toolbelt
|
||||||
rich==14.0.0
|
rich
|
||||||
ruff==0.11.10
|
ruff
|
||||||
setuptools==80.3.0
|
setuptools
|
||||||
six==1.17.0
|
six
|
||||||
sniffio==1.3.1
|
sniffio
|
||||||
soupsieve==2.7
|
soupsieve
|
||||||
SQLAlchemy==2.0.41
|
SQLAlchemy
|
||||||
sqlparse==0.5.3
|
sqlparse
|
||||||
suds==1.2.0
|
suds
|
||||||
swapper==1.3.0
|
swapper
|
||||||
tablib==3.8.0
|
tablib
|
||||||
tenacity==9.1.2
|
tenacity
|
||||||
text-unidecode==1.3
|
text-unidecode
|
||||||
tqdm==4.67.1
|
tqdm
|
||||||
types-python-dateutil==2.9.0.20250516
|
types-python-dateutil
|
||||||
typing_extensions==4.13.0
|
typing_extensions
|
||||||
tzdata==2025.2
|
tzdata
|
||||||
urllib3==2.3.0
|
urllib3
|
||||||
wcwidth==0.2.13
|
wcwidth
|
||||||
zstandard==0.23.0
|
zstandard
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
<div class="container py-4">
|
<div class="container py-4">
|
||||||
<div class="row g-2">
|
<div class="row g-2">
|
||||||
|
|
||||||
|
|
||||||
<!-- Bill Form -->
|
<!-- Bill Form -->
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
<!-- Item Column -->
|
<!-- Item Column -->
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column ms-2">
|
||||||
{% for hidden_field in f.hidden_fields %}
|
{% for hidden_field in f.hidden_fields %}
|
||||||
{{ hidden_field }}
|
{{ hidden_field }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@ -64,6 +64,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'inventort_list' request.dealer.slug request.dealer.entity.slug %}">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-boxes"></span></span><span class="nav-link-text">{% trans "Inventory List"|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -14,12 +14,11 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
{% for i in inventory_list %}
|
{% for i in inventory_list %}
|
||||||
|
<tr class="hover-actions-trigger">
|
||||||
<tr class="hover-actions-trigger">
|
<td class="ps-2 fw-medium">{{ i.item_model__name }}</td>
|
||||||
<td class="ps-2 fw-medium">{{ i.item_model__name }}</td>
|
<td class="text-center">{{ i.item_model__uom__name }}</td>
|
||||||
<td class="text-center">{{ i.item_model__uom__name }}</td>
|
<td class="text-end pe-3">{{ i.total_quantity | floatformat:3 }}</td>
|
||||||
<td class="text-end pe-3">{{ i.total_quantity | floatformat:3 }}</td>
|
<td class="text-end pe-3 fw-bold text-primary">
|
||||||
<td class="text-end pe-3 fw-bold text-primary">
|
|
||||||
<span class="currency">{{CURRENCY}}</span>{{ i.total_value | currency_format }}
|
<span class="currency">{{CURRENCY}}</span>{{ i.total_value | currency_format }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -30,7 +29,7 @@
|
|||||||
<td colspan="2"></td>
|
<td colspan="2"></td>
|
||||||
<td class="text-end pe-3 fw-bold">{% trans "Total Value" %}</td>
|
<td class="text-end pe-3 fw-bold">{% trans "Total Value" %}</td>
|
||||||
<td class="text-end pe-3 fw-bold text-success">
|
<td class="text-end pe-3 fw-bold text-success">
|
||||||
<span class="currency">{{CURRENCY}}</span>{{ inventory_total_value | currency_format }}
|
<span class="currency">{{CURRENCY}}</span>{{ inventory_total_value | currency_format }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user