diff --git a/services/deal.py b/services/deal.py
index 501e828..eb5d144 100644
--- a/services/deal.py
+++ b/services/deal.py
@@ -1027,7 +1027,14 @@ class DealService(BaseService):
general_services_total = sum((service.price * service.quantity for service in deal.services))
product_services_totals = await self._get_product_services_totals(deal)
template = ENV.get_template("deal.html")
- product_images = await fetch_images([product.product.images[0].image_url for product in deal.products])
+
+ product_urls: List[Optional[str]] = []
+ for product in deal.products:
+ if len(product.product.images) > 0:
+ product_urls.append(product.product.images[0].image_url)
+ else:
+ product_urls.append(None)
+ product_images = await fetch_images(product_urls)
result = template.render({
"general_services_total": general_services_total,
diff --git a/static/css/deal.css b/static/css/deal.css
index 3e116ff..04e0f7d 100644
--- a/static/css/deal.css
+++ b/static/css/deal.css
@@ -39,12 +39,12 @@ hr {
.small-text {
font-size: 12px;
- margin-bottom: 5px;
+ margin-bottom: 4px;
}
.medium-text {
font-size: 15px;
- margin-bottom: 5px;
+ margin-bottom: 6px;
}
.large-text {
@@ -150,8 +150,9 @@ table tfoot {
}
.barcode-container {
- margin: 15px 0 -5px 385px;
+ margin: 15px 0 -5px 355px;
display: flex;
+ white-space: nowrap;
flex-direction: column;
align-items: center;
}
diff --git a/templates/documents/deal.html b/templates/documents/deal.html
index 3f3b93c..d730de4 100644
--- a/templates/documents/deal.html
+++ b/templates/documents/deal.html
@@ -43,8 +43,6 @@
{% if deal.comment %}
Комментарий к сделке: {{ deal.comment }}
- {% else %}
- Комментарий к сделке отсутствует
{% endif %}
@@ -62,42 +60,51 @@
{% if deal.shipping_warehouse.name %}
Склад отгрузки: {{ deal.shipping_warehouse.name }}
{% endif %}
-
-
-
- | Общие услуги |
- Количество |
- Сумма |
-
-
-
-
-
- {% for service in deal.services %}
+ {% if deal.services|length > 0 %}
+
+
- | {{ service.service.name }} |
- {{ '{:,}'.format(service.quantity) }} шт. |
- {{ '{:,}'.format(service.price * service.quantity).replace(',', ' ') }} Р |
+ Общие услуги |
+ Количество |
+ Сумма |
- {% endfor %}
-
-
-
- Итого: {{ general_services_total }} Р
-
+
+
+
+
+ {% for service in deal.services %}
+
+ | {{ service.service.name }} |
+ {{ '{:,}'.format(service.quantity) }} шт. |
+ {{ '{:,}'.format(service.price * service.quantity).replace(',', ' ') }} Р |
+
+ {% endfor %}
+
+
+
+ Итого: {{ general_services_total }} Р
+
+ {% else %}
+
+
+ {% endif %}
{% for product in deal.products %}
- {% if product.product.images|length != 0 %}
-
+
+ {% if product.product.images|length > 0 %}

-
- {% endif %}
-
+ {% else %}
+

+ {% endif %}
+
+
{{ loop.index }}. {{ product.product.name }}
@@ -126,38 +133,46 @@
-
- {{ encode128(product.product.barcodes[0].barcode, "A") }}
-
-
- {{ product.product.barcodes[0].barcode }}
-
+ {% if product.product.barcodes|length > 0 %}
+
+ {{ encode128(product.product.barcodes[0].barcode, "A") }}
+
+
+ {{ product.product.barcodes[0].barcode }}
+
+ {% else %}
+
+ {% endif %}
-
-
-
- | Наименование услуги |
- Цена |
- Сумма |
-
-
-
-
-
- {% for service in product.services %}
+ {% if product.services|length > 0 %}
+
+
- | {{ service.service.name }} |
- {{ '{:,}'.format(product.quantity) }} Р |
- {{ '{:,}'.format(service.price * product.quantity).replace(',', ' ') }} Р |
+ Наименование услуги |
+ Цена |
+ Сумма |
- {% endfor %}
-
-
-
- Итого: {{ product_services_totals[loop.index0] }} Р
-
+
+
+
+
+ {% for service in product.services %}
+
+ | {{ service.service.name }} |
+ {{ '{:,}'.format(product.quantity) }} Р |
+ {{ '{:,}'.format(service.price * product.quantity).replace(',', ' ') }} Р |
+
+ {% endfor %}
+
+
+
+ Итого: {{ product_services_totals[loop.index0] }} Р
+
+ {% else %}
+
+ {% endif %}
{% endfor %}
diff --git a/utils/images_fetcher.py b/utils/images_fetcher.py
index 62a5538..fb38a94 100644
--- a/utils/images_fetcher.py
+++ b/utils/images_fetcher.py
@@ -1,11 +1,14 @@
import asyncio
import base64
-from typing import List, Tuple
+from typing import List, Tuple, Optional
import aiohttp
-async def fetch_image(url: str) -> str:
+async def fetch_image(url: Optional[str]) -> str:
+ if not url:
+ return ""
+
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
@@ -15,6 +18,6 @@ async def fetch_image(url: str) -> str:
return ""
-async def fetch_images(urls: List[str]) -> Tuple[str]:
+async def fetch_images(urls: List[Optional[str]]) -> Tuple[str]:
tasks = [fetch_image(url) for url in urls]
return await asyncio.gather(*tasks)