1
0
forked from erp-dev/erp

feat: added some filed to shipment serializers

This commit is contained in:
2026-04-23 17:51:48 +08:00
parent 35a03218d8
commit d4fbb2c7fe
11 changed files with 287 additions and 1 deletions

1
.env
View File

@@ -10,3 +10,4 @@ PRINTING_SALES_ITEM_SOURCE_STATE_ID=2
WECOM_WEBHOOK_KEY=cc88bdef-a13f-4d7e-bdb6-ee51b68b8205
PRINTING_JOB_STATE_ADVANCED_FOLLOWUP_URL_TEMPLATE=https://app.yuwen.cloud/workstation/production/batch-advance?orderId={order_id}
AGENT_ACCESS_KEY=hophopkk
PRINTING_ORDER_CREATED_WECOM_NOTIFY_ENABLED=False

View File

@@ -62,6 +62,48 @@ def _build_nested_sales_item_context(items):
}
def _resolve_shipment_fabric(shipment: Shipment) -> str | None:
rel = getattr(shipment, "items", None)
if rel is None:
return None
first_item = rel.filter(delete_at__isnull=True).order_by("id").first()
if first_item is None or not first_item.printing_job_id:
return None
from printing.models import PrintingJob
printing_job = (
PrintingJob.objects.filter(id=first_item.printing_job_id)
.select_related("printing_order")
.first()
)
if printing_job is None or printing_job.printing_order is None:
return None
return printing_job.printing_order.fabric
def _resolve_shipment_order_description(shipment: Shipment) -> str | None:
rel = getattr(shipment, "items", None)
if rel is None:
return None
first_item = rel.filter(delete_at__isnull=True).order_by("id").first()
if first_item is None or not first_item.printing_job_id:
return None
from printing.models import PrintingJob
printing_job = (
PrintingJob.objects.filter(id=first_item.printing_job_id)
.select_related("printing_order")
.first()
)
if printing_job is None or printing_job.printing_order is None:
return None
return printing_job.printing_order.description
class ShipmentSerializer(serializers.ModelSerializer):
"""
出货单序列化器(只读,用于返回数据)
@@ -85,6 +127,8 @@ class ShipmentSerializer(serializers.ModelSerializer):
external_finished_products_count = serializers.SerializerMethodField()
merchant_id = serializers.IntegerField(source="merchant.id", read_only=True)
merchant_name = serializers.CharField(source="merchant.name", read_only=True)
fabric = serializers.SerializerMethodField()
order_description = serializers.SerializerMethodField()
delivery_id = serializers.IntegerField(read_only=True, allow_null=True)
sales_items = serializers.SerializerMethodField()
external_finished_products = serializers.SerializerMethodField()
@@ -97,6 +141,8 @@ class ShipmentSerializer(serializers.ModelSerializer):
"merchant_name",
"customer",
"customer_name",
"fabric",
"order_description",
"shipment_date",
"address",
"contact_name",
@@ -132,9 +178,15 @@ class ShipmentSerializer(serializers.ModelSerializer):
return obj.created_by.username
return None
def get_fabric(self, obj):
return _resolve_shipment_fabric(obj)
def get_items_count(self, obj):
return obj.items.filter(delete_at__isnull=True).count()
def get_order_description(self, obj):
return _resolve_shipment_order_description(obj)
def get_cancelled_by_name(self, obj):
if obj.cancelled_by:
employee = getattr(obj.cancelled_by, "employee", None)
@@ -494,6 +546,8 @@ class ShipmentSalesItemCustomerSerializer(serializers.Serializer):
class ShipmentDeliveryShipmentSummarySerializer(serializers.ModelSerializer):
customer_name = serializers.CharField(source="customer.name", read_only=True)
status_display = serializers.CharField(source="get_status_display", read_only=True)
fabric = serializers.SerializerMethodField()
order_description = serializers.SerializerMethodField()
delivery_id = serializers.IntegerField(read_only=True, allow_null=True)
class Meta:
@@ -502,6 +556,8 @@ class ShipmentDeliveryShipmentSummarySerializer(serializers.ModelSerializer):
"id",
"customer",
"customer_name",
"fabric",
"order_description",
"shipment_date",
"status",
"status_display",
@@ -510,6 +566,12 @@ class ShipmentDeliveryShipmentSummarySerializer(serializers.ModelSerializer):
]
read_only_fields = fields
def get_fabric(self, obj):
return _resolve_shipment_fabric(obj)
def get_order_description(self, obj):
return _resolve_shipment_order_description(obj)
class ShipmentDeliverySerializer(serializers.ModelSerializer):
status_display = serializers.CharField(source="get_status_display", read_only=True)
@@ -542,6 +604,7 @@ class ShipmentDeliverySerializer(serializers.ModelSerializer):
"vehicle_capacity",
"remark",
"internal_remark",
"shipment_order_ids",
"status",
"status_display",
"started_at",
@@ -617,6 +680,12 @@ class ShipmentDeliveryCreateSerializer(serializers.Serializer):
allow_blank=True,
help_text="内部备注(可选)",
)
shipment_order_ids = serializers.JSONField(
required=False,
allow_null=True,
default=list,
help_text="前端自管的出货单顺序 ID 数组(可选,可为 null",
)
shipments = serializers.ListField(
child=serializers.IntegerField(),
required=False,
@@ -627,6 +696,11 @@ class ShipmentDeliveryCreateSerializer(serializers.Serializer):
def validate_shipments(self, value):
return list(dict.fromkeys(value)) if value else []
def validate_shipment_order_ids(self, value):
if value is not None and not isinstance(value, list):
raise serializers.ValidationError("shipment_order_ids 必须是数组或 null")
return value
class ShipmentDeliveryUpdateSerializer(serializers.Serializer):
driver_name = serializers.CharField(
@@ -647,6 +721,11 @@ class ShipmentDeliveryUpdateSerializer(serializers.Serializer):
internal_remark = serializers.CharField(
max_length=200, required=False, allow_blank=True, help_text="内部备注(可选)"
)
shipment_order_ids = serializers.JSONField(
required=False,
allow_null=True,
help_text="前端自管的出货单顺序 ID 数组(可选,可为 null",
)
shipments = serializers.ListField(
child=serializers.IntegerField(),
required=False,
@@ -656,6 +735,11 @@ class ShipmentDeliveryUpdateSerializer(serializers.Serializer):
def validate_shipments(self, value):
return list(dict.fromkeys(value)) if value else []
def validate_shipment_order_ids(self, value):
if value is not None and not isinstance(value, list):
raise serializers.ValidationError("shipment_order_ids 必须是数组或 null")
return value
class ShipmentDeliveryStatusUpdateSerializer(serializers.Serializer):
status = serializers.ChoiceField(

View File

@@ -1633,6 +1633,7 @@ class ShipmentQueryAPITestCase(TestCase):
process=self.process1,
created_by=self.user1,
external_order_id="QUERY-PO-001",
description="查询订单备注",
)
self.printing_job1 = printing_models.PrintingJob.objects.create(
merchant=self.merchant1,
@@ -1692,6 +1693,8 @@ class ShipmentQueryAPITestCase(TestCase):
self.assertIn("area", item)
self.assertIn("delivery_id", item)
self.assertIsNone(item["delivery_id"])
self.assertEqual(item["fabric"], "查询面料")
self.assertEqual(item["order_description"], "查询订单备注")
self.assertEqual(item["area"], "A1")
self.assertEqual(item["status"], shipment_models.ShipmentStatus.DRAFT)
self.assertEqual(item["status_display"], "草稿(未发布)")
@@ -1837,6 +1840,8 @@ class ShipmentQueryAPITestCase(TestCase):
self.assertIn("contact_phone", result)
self.assertIn("delivery_id", result)
self.assertIsNone(result["delivery_id"])
self.assertEqual(result["fabric"], "查询面料")
self.assertEqual(result["order_description"], "查询订单备注")
self.assertEqual(result["id"], self.shipment1.id)
self.assertIn("area", result)
self.assertEqual(result["area"], "A1")
@@ -1949,6 +1954,25 @@ class ShipmentQueryAPITestCase(TestCase):
self.assertIn("remark", target)
self.assertEqual(target["remark"], "X备注")
def test_list_shipments_without_sales_items_returns_null_fabric(self):
shipment_without_sales_items = shipment_models.Shipment.objects.create(
merchant=self.merchant1,
customer=self.customer1,
shipment_date="2026-01-20",
created_by=self.user1,
remark="no-items",
area="A5",
)
resp = self.client.get("/api/v1/shipment/shipments/")
self.assertEqual(resp.status_code, status.HTTP_200_OK)
item = next(it for it in resp.json()["results"] if it["id"] == shipment_without_sales_items.id)
self.assertIn("fabric", item)
self.assertIsNone(item["fabric"])
self.assertIn("order_description", item)
self.assertIsNone(item["order_description"])
def test_retrieve_other_merchant_shipment_404(self):
resp = self.client.get(f"/api/v1/shipment/shipments/{self.shipment2.id}/")
self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND)
@@ -2697,6 +2721,7 @@ class ShipmentDeliveryAPITestCase(APITestCase):
"vehicle_capacity": "9.6米厢车",
"remark": "先装车",
"internal_remark": "注意对账",
"shipment_order_ids": [self.shipment2.id, self.shipment1.id],
"shipments": [self.shipment1.id, self.shipment2.id],
},
format="json",
@@ -2710,6 +2735,7 @@ class ShipmentDeliveryAPITestCase(APITestCase):
self.assertEqual(data["vehicle_capacity"], "9.6米厢车")
self.assertEqual(data["remark"], "先装车")
self.assertEqual(data["internal_remark"], "注意对账")
self.assertEqual(data["shipment_order_ids"], [self.shipment2.id, self.shipment1.id])
self.assertEqual(data["status"], shipment_models.ShipmentDeliveryStatus.PENDING)
self.assertEqual(data["shipments_count"], 2)
self.assertEqual(data["merchant_id"], self.merchant.id)
@@ -2722,6 +2748,34 @@ class ShipmentDeliveryAPITestCase(APITestCase):
self.assertIsNotNone(self.shipment1.delivery_id)
self.assertEqual(self.shipment1.delivery_id, self.shipment2.delivery_id)
def test_create_delivery_defaults_shipment_order_ids_to_empty_list(self):
resp = self.client.post(
"/api/v1/shipment/deliveries/",
{
"driver_name": "张司机",
"vehicle_trip": "KD-001-A",
"shipments": [self.shipment1.id],
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)
self.assertEqual(resp.json()["shipment_order_ids"], [])
def test_create_delivery_rejects_non_array_shipment_order_ids(self):
resp = self.client.post(
"/api/v1/shipment/deliveries/",
{
"driver_name": "张司机",
"vehicle_trip": "KD-001-B",
"shipment_order_ids": {"bad": "value"},
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("shipment_order_ids", resp.json())
def test_create_delivery_rejects_shipment_bound_to_other_delivery(self):
resp = self.client.post(
"/api/v1/shipment/deliveries/",
@@ -2817,6 +2871,11 @@ class ShipmentDeliveryAPITestCase(APITestCase):
for item in data["shipments"]:
self.assertIn("delivery_id", item)
self.assertEqual(item["delivery_id"], delivery.id)
self.assertIn("fabric", item)
self.assertIn("order_description", item)
first_shipment = next(item for item in data["shipments"] if item["id"] == self.shipment1.id)
self.assertIsNone(first_shipment["fabric"])
self.assertIsNone(first_shipment["order_description"])
def test_patch_delivery_updates_fields_and_replaces_shipments(self):
delivery = shipment_models.ShipmentDelivery.objects.create(
@@ -2837,6 +2896,7 @@ class ShipmentDeliveryAPITestCase(APITestCase):
"vehicle_capacity": "13米高栏",
"remark": "改派车辆",
"internal_remark": "已电话确认",
"shipment_order_ids": [self.shipment2.id],
"shipments": [self.shipment2.id],
},
format="json",
@@ -2850,6 +2910,7 @@ class ShipmentDeliveryAPITestCase(APITestCase):
self.assertEqual(data["vehicle_capacity"], "13米高栏")
self.assertEqual(data["remark"], "改派车辆")
self.assertEqual(data["internal_remark"], "已电话确认")
self.assertEqual(data["shipment_order_ids"], [self.shipment2.id])
self.assertEqual(data["operator_id"], self.employee.id)
self.assertEqual(data["shipments_count"], 1)
self.assertEqual(data["shipments"][0]["id"], self.shipment2.id)
@@ -2859,6 +2920,45 @@ class ShipmentDeliveryAPITestCase(APITestCase):
self.assertIsNone(self.shipment1.delivery_id)
self.assertEqual(self.shipment2.delivery_id, delivery.id)
def test_patch_delivery_allows_null_shipment_order_ids(self):
delivery = shipment_models.ShipmentDelivery.objects.create(
merchant=self.merchant,
driver_name="张司机",
vehicle_trip="KD-005-N",
shipment_order_ids=[self.shipment1.id],
created_by=self.user,
)
resp = self.client.patch(
f"/api/v1/shipment/deliveries/{delivery.id}/",
{
"shipment_order_ids": None,
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertIsNone(resp.json()["shipment_order_ids"])
def test_patch_delivery_rejects_non_array_shipment_order_ids(self):
delivery = shipment_models.ShipmentDelivery.objects.create(
merchant=self.merchant,
driver_name="张司机",
vehicle_trip="KD-005-C",
created_by=self.user,
)
resp = self.client.patch(
f"/api/v1/shipment/deliveries/{delivery.id}/",
{
"shipment_order_ids": "not-a-list",
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("shipment_order_ids", resp.json())
def test_modify_delivery_status_sets_timestamps(self):
delivery = shipment_models.ShipmentDelivery.objects.create(
merchant=self.merchant,

View File

@@ -423,6 +423,7 @@ class ShipmentDeliveryListCreateView(ListModelMixin, GenericAPIView):
contact_phone=serializer.validated_data.get("contact_phone", ""),
vehicle_capacity=serializer.validated_data.get("vehicle_capacity", ""),
shipment_ids=serializer.validated_data.get("shipments", []),
shipment_order_ids=serializer.validated_data.get("shipment_order_ids", []),
created_by=request.user,
remark=serializer.validated_data.get("remark", ""),
internal_remark=serializer.validated_data.get("internal_remark", ""),
@@ -483,7 +484,7 @@ class ShipmentDeliveryDetailView(RetrieveModelMixin, GenericAPIView):
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
from shipment.services import update_shipment_delivery
from shipment.services import UNSET, update_shipment_delivery
try:
delivery = update_shipment_delivery(
@@ -493,6 +494,11 @@ class ShipmentDeliveryDetailView(RetrieveModelMixin, GenericAPIView):
contact_phone=serializer.validated_data.get("contact_phone"),
vehicle_capacity=serializer.validated_data.get("vehicle_capacity"),
shipment_ids=serializer.validated_data.get("shipments"),
shipment_order_ids=(
serializer.validated_data["shipment_order_ids"]
if "shipment_order_ids" in serializer.validated_data
else UNSET
),
remark=serializer.validated_data.get("remark"),
internal_remark=serializer.validated_data.get("internal_remark"),
operator=request.user,

View File

@@ -101,6 +101,8 @@ class AgentSalesItemSerializer(serializers.ModelSerializer):
class AgentShipmentListSerializer(serializers.ModelSerializer):
customer_name = serializers.CharField(source="customer.name", read_only=True)
status_display = serializers.CharField(source="get_status_display", read_only=True)
fabric = serializers.SerializerMethodField()
order_description = serializers.SerializerMethodField()
delivery_id = serializers.IntegerField(read_only=True, allow_null=True)
sales_items = serializers.SerializerMethodField()
@@ -111,6 +113,8 @@ class AgentShipmentListSerializer(serializers.ModelSerializer):
"merchant_id",
"customer",
"customer_name",
"fabric",
"order_description",
"shipment_date",
"address",
"contact_name",
@@ -128,6 +132,46 @@ class AgentShipmentListSerializer(serializers.ModelSerializer):
"updated_at",
]
def get_fabric(self, obj):
rel = getattr(obj, "items", None)
if rel is None:
return None
first_item = next((item for item in obj.items.all() if item.delete_at is None), None)
if first_item is None or not first_item.printing_job_id:
return None
from printing.models import PrintingJob
printing_job = (
PrintingJob.objects.filter(id=first_item.printing_job_id)
.select_related("printing_order")
.first()
)
if printing_job is None or printing_job.printing_order is None:
return None
return printing_job.printing_order.fabric
def get_order_description(self, obj):
rel = getattr(obj, "items", None)
if rel is None:
return None
first_item = next((item for item in obj.items.all() if item.delete_at is None), None)
if first_item is None or not first_item.printing_job_id:
return None
from printing.models import PrintingJob
printing_job = (
PrintingJob.objects.filter(id=first_item.printing_job_id)
.select_related("printing_order")
.first()
)
if printing_job is None or printing_job.printing_order is None:
return None
return printing_job.printing_order.description
def get_sales_items(self, obj):
items = [i for i in obj.items.all() if i.delete_at is None]
return AgentSalesItemSerializer(items, many=True, context=self.context).data

View File

@@ -45,6 +45,8 @@ Authorization: <AGENT_ACCESS_KEY>
"merchant_id": 10,
"customer": 5,
"customer_name": "客户A",
"fabric": "棉布 40S",
"order_description": "订单备注",
"shipment_date": "2026-04-14",
"address": "广州市天河区",
"contact_name": "张三",
@@ -154,6 +156,8 @@ Authorization: <AGENT_ACCESS_KEY>
- "未出货"定义:`delivery` 为空,即尚未关联送货单
- `delivery_id` 始终返回送货单ID未关联时为 `null`
- `fabric` 来自该出货单所关联销售品对应生产订单的 `fabric`;若当前出货单没有销售品则返回 `null`
- `order_description` 来自该出货单所关联销售品对应生产订单的 `description`;若当前出货单没有销售品则返回 `null`
- 结果按 `created_at` 降序排列
- 只返回 `merchant_id` 对应商户的数据
- `sales_items` 包含该出货单的所有销售品(软删除的条目自动排除)

View File

@@ -53,6 +53,8 @@
"merchant_name": "测试印花厂",
"customer": 1,
"customer_name": "客户A",
"fabric": "棉布 40S",
"order_description": "订单备注",
"shipment_date": "2026-01-14",
"status": 1,
"status_display": "草稿(未发布)",
@@ -79,6 +81,8 @@
- `sales_items` 现在返回的是带图片字段的销售品详情结构
- `delivery_id` 始终返回送货单ID未绑定送货单时为 `null`
- `fabric` 来自该出货单所关联销售品对应生产订单的 `fabric`;若当前出货单没有销售品,则返回 `null`
- `order_description` 来自该出货单所关联销售品对应生产订单的 `description`;若当前出货单没有销售品,则返回 `null`
- `delivery_id=null` 不会触发过滤;如需按是否绑定送货单筛选,请使用 `delivery_isnull`
- 若销售品关联的 `PrintingJob.product` 存在主图,则会返回 `product_image_url`
- 若无关联图片,则 `product_image_url``null`
@@ -226,6 +230,8 @@
| merchant_name | string | 所属商户名称(从当前登录用户推导) |
| customer | int | 客户ID |
| customer_name | string | 客户名称 |
| fabric | string/null | 面料;来自关联生产订单,若当前出货单没有销售品则为 null |
| order_description | string/null | 订单备注;来自关联生产订单的 `description`,若当前出货单没有销售品则为 null |
| shipment_date | string | 出货日期 |
| delivery_id | int/null | 关联送货单ID未绑定时为 null |
| address | string | 地址 |

View File

@@ -47,6 +47,7 @@
- `vehicle_capacity`
- `remark`
- `internal_remark`
- `shipment_order_ids`
- `status`
- `started_at`
- `delivered_at`
@@ -67,6 +68,7 @@
- `merchant` 用于多商户隔离
- 创建、修改、状态流转时,会根据 `request.user.employee` 自动写入 `operator`
- 取消送货单时会写入 `cancelled_at``cancelled_by`
- `shipment_order_ids` 是前端自管的出货单顺序 JSON 字段;后端只保存和返回,不据此自动排序 `shipments`
## API 列表
@@ -112,6 +114,7 @@ GET /api/v1/shipment/deliveries/?status=2&driver_name=张&vehicle_trip=001&limit
"vehicle_capacity": "9.6米厢车",
"remark": "先装车",
"internal_remark": "注意对账",
"shipment_order_ids": [11, 10],
"status": 1,
"status_display": "待送货",
"started_at": null,
@@ -123,6 +126,7 @@ GET /api/v1/shipment/deliveries/?status=2&driver_name=张&vehicle_trip=001&limit
"id": 10,
"customer": 5,
"customer_name": "客户A",
"order_description": null,
"shipment_date": "2026-04-03",
"status": 2,
"status_display": "已发布",
@@ -156,6 +160,7 @@ GET /api/v1/shipment/deliveries/?status=2&driver_name=张&vehicle_trip=001&limit
"vehicle_capacity": "9.6米厢车",
"remark": "先装车",
"internal_remark": "注意对账",
"shipment_order_ids": [11, 10],
"shipments": [10, 11]
}
```
@@ -168,6 +173,7 @@ GET /api/v1/shipment/deliveries/?status=2&driver_name=张&vehicle_trip=001&limit
- `vehicle_capacity`: 可选,车辆容量
- `remark`: 可选,备注
- `internal_remark`: 可选,内部备注
- `shipment_order_ids`: 可选,前端自管的出货单顺序 JSON 数组;可传 `null`;未传时默认 `[]`
- `shipments`: 可选,出货单 ID 列表
创建规则:
@@ -198,6 +204,7 @@ GET /api/v1/shipment/deliveries/?status=2&driver_name=张&vehicle_trip=001&limit
"vehicle_capacity": "13米高栏",
"remark": "改派车辆",
"internal_remark": "已电话确认",
"shipment_order_ids": [11, 12],
"shipments": [11, 12]
}
```
@@ -205,6 +212,7 @@ GET /api/v1/shipment/deliveries/?status=2&driver_name=张&vehicle_trip=001&limit
修改规则:
- `driver_name``vehicle_trip``contact_phone``vehicle_capacity``remark``internal_remark` 可单独修改
- `shipment_order_ids` 按普通字段处理,后端仅保存与返回;值必须是数组或 `null`
- `shipments` 如果传入,则视为“整体替换当前绑定的出货单集合”
- 替换绑定时,出货单仍然必须满足“当前商户、已审核、未绑定到其他送货单”
- 更新接口不支持直接修改 `status`

View File

@@ -0,0 +1,16 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shipment', '0022_shipment_rejected_sales_item_ids'),
]
operations = [
migrations.AddField(
model_name='shipmentdelivery',
name='shipment_order_ids',
field=models.JSONField(blank=True, default=list, help_text='前端自管的出货单展示顺序,后端不据此重排 shipments 关系', null=True, verbose_name='出货单顺序ID列表'),
),
]

View File

@@ -561,6 +561,14 @@ class ShipmentDelivery(ModelBase):
verbose_name='内部备注',
)
shipment_order_ids = models.JSONField(
null=True,
blank=True,
default=list,
verbose_name='出货单顺序ID列表',
help_text='前端自管的出货单展示顺序,后端不据此重排 shipments 关系',
)
started_at = models.DateTimeField(
null=True,
blank=True,

View File

@@ -28,6 +28,9 @@ from shipment.models import (
from shipment.signals import shipment_created
UNSET = object()
def _resolve_user_merchant(user):
emp = getattr(user, "employee", None)
return getattr(emp, "merchant", None) if emp else None
@@ -405,6 +408,7 @@ def create_shipment_delivery(
contact_phone: str = "",
vehicle_capacity: str = "",
shipment_ids: list[int],
shipment_order_ids: list | None = None,
created_by,
remark: str = "",
internal_remark: str = "",
@@ -434,6 +438,7 @@ def create_shipment_delivery(
vehicle_capacity=(vehicle_capacity or "").strip(),
remark=(remark or "").strip(),
internal_remark=(internal_remark or "").strip(),
shipment_order_ids=shipment_order_ids,
created_by=created_by,
operator=operator,
)
@@ -453,6 +458,7 @@ def update_shipment_delivery(
contact_phone: str | None = None,
vehicle_capacity: str | None = None,
shipment_ids: list[int] | None = None,
shipment_order_ids=UNSET,
remark: str | None = None,
internal_remark: str | None = None,
operator=None,
@@ -481,6 +487,9 @@ def update_shipment_delivery(
if internal_remark is not None:
delivery.internal_remark = (internal_remark or "").strip()
if shipment_order_ids is not UNSET:
delivery.shipment_order_ids = shipment_order_ids
if shipment_ids is not None:
shipments = _resolve_delivery_shipments(
shipment_ids=shipment_ids,