karrio-server-graph 2025.5rc11__py3-none-any.whl → 2025.5rc13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karrio/server/graph/schemas/base/__init__.py +18 -0
- karrio/server/graph/schemas/base/inputs.py +29 -1
- karrio/server/graph/schemas/base/mutations.py +146 -12
- karrio/server/graph/schemas/base/types.py +3 -2
- karrio/server/graph/serializers.py +5 -4
- karrio/server/graph/tests/test_partial_shipments.py +603 -0
- karrio/server/graph/tests/test_rate_sheets.py +8 -2
- {karrio_server_graph-2025.5rc11.dist-info → karrio_server_graph-2025.5rc13.dist-info}/METADATA +1 -1
- {karrio_server_graph-2025.5rc11.dist-info → karrio_server_graph-2025.5rc13.dist-info}/RECORD +11 -10
- {karrio_server_graph-2025.5rc11.dist-info → karrio_server_graph-2025.5rc13.dist-info}/WHEEL +0 -0
- {karrio_server_graph-2025.5rc11.dist-info → karrio_server_graph-2025.5rc13.dist-info}/top_level.txt +0 -0
|
@@ -332,6 +332,24 @@ class Mutation:
|
|
|
332
332
|
) -> mutations.UpdateRateSheetMutation:
|
|
333
333
|
return mutations.UpdateRateSheetMutation.mutate(info, **input.to_dict())
|
|
334
334
|
|
|
335
|
+
@strawberry.mutation
|
|
336
|
+
def update_rate_sheet_zone_cell(
|
|
337
|
+
self, info: Info, input: inputs.UpdateRateSheetZoneCellMutationInput
|
|
338
|
+
) -> mutations.UpdateRateSheetZoneCellMutation:
|
|
339
|
+
return mutations.UpdateRateSheetZoneCellMutation.mutate(info, **input.to_dict())
|
|
340
|
+
|
|
341
|
+
@strawberry.mutation
|
|
342
|
+
def batch_update_rate_sheet_cells(
|
|
343
|
+
self, info: Info, input: inputs.BatchUpdateRateSheetCellsMutationInput
|
|
344
|
+
) -> mutations.BatchUpdateRateSheetCellsMutation:
|
|
345
|
+
return mutations.BatchUpdateRateSheetCellsMutation.mutate(info, **input.to_dict())
|
|
346
|
+
|
|
347
|
+
@strawberry.mutation
|
|
348
|
+
def delete_rate_sheet_service(
|
|
349
|
+
self, info: Info, input: inputs.DeleteRateSheetServiceMutationInput
|
|
350
|
+
) -> mutations.DeleteRateSheetServiceMutation:
|
|
351
|
+
return mutations.DeleteRateSheetServiceMutation.mutate(info, **input.to_dict())
|
|
352
|
+
|
|
335
353
|
@strawberry.mutation
|
|
336
354
|
def delete_rate_sheet(
|
|
337
355
|
self, info: Info, input: inputs.DeleteMutationInput
|
|
@@ -245,7 +245,6 @@ class AddressInput:
|
|
|
245
245
|
email: typing.Optional[str] = strawberry.UNSET
|
|
246
246
|
phone_number: typing.Optional[str] = strawberry.UNSET
|
|
247
247
|
state_code: typing.Optional[str] = strawberry.UNSET
|
|
248
|
-
suburb: typing.Optional[str] = strawberry.UNSET
|
|
249
248
|
residential: typing.Optional[bool] = strawberry.UNSET
|
|
250
249
|
street_number: typing.Optional[str] = strawberry.UNSET
|
|
251
250
|
address_line1: typing.Optional[str] = strawberry.UNSET
|
|
@@ -517,6 +516,35 @@ class UpdateRateSheetMutationInput(utils.BaseInput):
|
|
|
517
516
|
metadata: typing.Optional[utils.JSON] = strawberry.UNSET
|
|
518
517
|
|
|
519
518
|
|
|
519
|
+
@strawberry.input
|
|
520
|
+
class UpdateRateSheetZoneCellMutationInput(utils.BaseInput):
|
|
521
|
+
id: str # Rate sheet ID
|
|
522
|
+
service_id: str # Service level ID
|
|
523
|
+
zone_id: str # Zone ID
|
|
524
|
+
field: str # Field name to update
|
|
525
|
+
value: utils.JSON # New value
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
@strawberry.input
|
|
529
|
+
class CellUpdate(utils.BaseInput):
|
|
530
|
+
service_id: str
|
|
531
|
+
zone_id: str
|
|
532
|
+
field: str
|
|
533
|
+
value: utils.JSON
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
@strawberry.input
|
|
537
|
+
class BatchUpdateRateSheetCellsMutationInput(utils.BaseInput):
|
|
538
|
+
id: str # Rate sheet ID
|
|
539
|
+
updates: typing.List[CellUpdate]
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
@strawberry.input
|
|
543
|
+
class DeleteRateSheetServiceMutationInput(utils.BaseInput):
|
|
544
|
+
rate_sheet_id: str
|
|
545
|
+
service_id: str
|
|
546
|
+
|
|
547
|
+
|
|
520
548
|
@strawberry.input
|
|
521
549
|
class RateSheetFilter(utils.Paginated):
|
|
522
550
|
keyword: typing.Optional[str] = strawberry.UNSET
|
|
@@ -538,8 +538,8 @@ class CreateRateSheetMutation(utils.BaseMutation):
|
|
|
538
538
|
carrier_name=rate_sheet.carrier_name,
|
|
539
539
|
).filter(id__in=carriers)
|
|
540
540
|
for _ in _carriers:
|
|
541
|
-
_.
|
|
542
|
-
_.
|
|
541
|
+
_.rate_sheet = rate_sheet
|
|
542
|
+
_.save(update_fields=["rate_sheet"])
|
|
543
543
|
|
|
544
544
|
return CreateRateSheetMutation(rate_sheet=rate_sheet)
|
|
545
545
|
|
|
@@ -558,9 +558,10 @@ class UpdateRateSheetMutation(utils.BaseMutation):
|
|
|
558
558
|
instance = providers.RateSheet.access_by(info.context.request).get(
|
|
559
559
|
id=input["id"]
|
|
560
560
|
)
|
|
561
|
+
data = input.copy()
|
|
561
562
|
serializer = serializers.RateSheetModelSerializer(
|
|
562
563
|
instance,
|
|
563
|
-
data=
|
|
564
|
+
data=data,
|
|
564
565
|
context=info.context.request,
|
|
565
566
|
partial=True,
|
|
566
567
|
)
|
|
@@ -568,11 +569,136 @@ class UpdateRateSheetMutation(utils.BaseMutation):
|
|
|
568
569
|
serializer.is_valid(raise_exception=True)
|
|
569
570
|
rate_sheet = serializer.save()
|
|
570
571
|
|
|
572
|
+
# Handle services updates like in CreateRateSheetMutation
|
|
573
|
+
if "services" in data:
|
|
574
|
+
save_many_to_many_data(
|
|
575
|
+
"services",
|
|
576
|
+
serializers.ServiceLevelModelSerializer,
|
|
577
|
+
rate_sheet,
|
|
578
|
+
payload=data,
|
|
579
|
+
context=info.context.request,
|
|
580
|
+
)
|
|
581
|
+
|
|
571
582
|
return UpdateRateSheetMutation(
|
|
572
583
|
rate_sheet=providers.RateSheet.objects.get(id=input["id"])
|
|
573
584
|
)
|
|
574
585
|
|
|
575
586
|
|
|
587
|
+
@strawberry.type
|
|
588
|
+
class UpdateRateSheetZoneCellMutation(utils.BaseMutation):
|
|
589
|
+
rate_sheet: typing.Optional[types.RateSheetType] = None
|
|
590
|
+
|
|
591
|
+
@staticmethod
|
|
592
|
+
@transaction.atomic
|
|
593
|
+
@utils.authentication_required
|
|
594
|
+
@utils.authorization_required(["manage_carriers"])
|
|
595
|
+
def mutate(
|
|
596
|
+
info: Info, **input: inputs.UpdateRateSheetZoneCellMutationInput
|
|
597
|
+
) -> "UpdateRateSheetZoneCellMutation":
|
|
598
|
+
rate_sheet = providers.RateSheet.access_by(info.context.request).get(
|
|
599
|
+
id=input["id"]
|
|
600
|
+
)
|
|
601
|
+
service = rate_sheet.services.get(id=input["service_id"])
|
|
602
|
+
|
|
603
|
+
try:
|
|
604
|
+
service.update_zone_cell(
|
|
605
|
+
zone_id=input["zone_id"], field=input["field"], value=input["value"]
|
|
606
|
+
)
|
|
607
|
+
except ValueError as e:
|
|
608
|
+
logger.error(f"Invalid zone id: {e}")
|
|
609
|
+
raise exceptions.ValidationError({"zone_id": "invalid zone id"})
|
|
610
|
+
|
|
611
|
+
return UpdateRateSheetZoneCellMutation(rate_sheet=rate_sheet)
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
@strawberry.type
|
|
615
|
+
class BatchUpdateRateSheetCellsMutation(utils.BaseMutation):
|
|
616
|
+
rate_sheet: typing.Optional[types.RateSheetType] = None
|
|
617
|
+
|
|
618
|
+
@staticmethod
|
|
619
|
+
@transaction.atomic
|
|
620
|
+
@utils.authentication_required
|
|
621
|
+
@utils.authorization_required(["manage_carriers"])
|
|
622
|
+
def mutate(
|
|
623
|
+
info: Info, **input: inputs.BatchUpdateRateSheetCellsMutationInput
|
|
624
|
+
) -> "BatchUpdateRateSheetCellsMutation":
|
|
625
|
+
rate_sheet = providers.RateSheet.access_by(info.context.request).get(
|
|
626
|
+
id=input["id"]
|
|
627
|
+
)
|
|
628
|
+
|
|
629
|
+
# Group updates by service_id for efficient processing
|
|
630
|
+
service_updates = {}
|
|
631
|
+
for update in input["updates"]:
|
|
632
|
+
service_id = update["service_id"]
|
|
633
|
+
if service_id not in service_updates:
|
|
634
|
+
service_updates[service_id] = []
|
|
635
|
+
service_updates[service_id].append(
|
|
636
|
+
{
|
|
637
|
+
"zone_id": update["zone_id"],
|
|
638
|
+
"field": update["field"],
|
|
639
|
+
"value": update["value"],
|
|
640
|
+
}
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
# Use optimized structure if available, otherwise fall back to legacy
|
|
644
|
+
if rate_sheet.zones is not None and rate_sheet.service_rates is not None:
|
|
645
|
+
# Use optimized batch update on rate sheet
|
|
646
|
+
all_updates = []
|
|
647
|
+
for service_id, updates in service_updates.items():
|
|
648
|
+
for update in updates:
|
|
649
|
+
all_updates.append(
|
|
650
|
+
{
|
|
651
|
+
"service_id": service_id,
|
|
652
|
+
"zone_id": update["zone_id"],
|
|
653
|
+
"field": update["field"],
|
|
654
|
+
"value": update["value"],
|
|
655
|
+
}
|
|
656
|
+
)
|
|
657
|
+
try:
|
|
658
|
+
rate_sheet.batch_update_service_rates(all_updates)
|
|
659
|
+
except Exception as e:
|
|
660
|
+
logger.error(f"Invalid zone id: {e}")
|
|
661
|
+
raise exceptions.ValidationError(
|
|
662
|
+
{"rate_sheet": "failed to update rate sheet"}
|
|
663
|
+
)
|
|
664
|
+
else:
|
|
665
|
+
# Fall back to legacy per-service updates
|
|
666
|
+
for service_id, updates in service_updates.items():
|
|
667
|
+
try:
|
|
668
|
+
service = rate_sheet.services.get(id=service_id)
|
|
669
|
+
service.batch_update_cells(updates)
|
|
670
|
+
except ValueError as e:
|
|
671
|
+
logger.error(f"Invalid zone id: {e}")
|
|
672
|
+
raise exceptions.ValidationError(
|
|
673
|
+
{"service_id": "failed to update service"}
|
|
674
|
+
)
|
|
675
|
+
|
|
676
|
+
return BatchUpdateRateSheetCellsMutation(rate_sheet=rate_sheet)
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
@strawberry.type
|
|
680
|
+
class DeleteRateSheetServiceMutation(utils.BaseMutation):
|
|
681
|
+
rate_sheet: typing.Optional[types.RateSheetType] = None
|
|
682
|
+
|
|
683
|
+
@staticmethod
|
|
684
|
+
@transaction.atomic
|
|
685
|
+
@utils.authentication_required
|
|
686
|
+
@utils.authorization_required(["manage_carriers"])
|
|
687
|
+
def mutate(
|
|
688
|
+
info: Info, **input: inputs.DeleteRateSheetServiceMutationInput
|
|
689
|
+
) -> "DeleteRateSheetServiceMutation":
|
|
690
|
+
rate_sheet = providers.RateSheet.access_by(info.context.request).get(
|
|
691
|
+
id=input["rate_sheet_id"]
|
|
692
|
+
)
|
|
693
|
+
service = rate_sheet.services.get(id=input["service_id"])
|
|
694
|
+
|
|
695
|
+
# Remove service from rate sheet and delete it
|
|
696
|
+
rate_sheet.services.remove(service)
|
|
697
|
+
service.delete()
|
|
698
|
+
|
|
699
|
+
return DeleteRateSheetServiceMutation(rate_sheet=rate_sheet)
|
|
700
|
+
|
|
701
|
+
|
|
576
702
|
@strawberry.type
|
|
577
703
|
class PartialShipmentMutation(utils.BaseMutation):
|
|
578
704
|
shipment: typing.Optional[types.ShipmentType] = None
|
|
@@ -841,10 +967,14 @@ class CreateMetafieldMutation(utils.BaseMutation):
|
|
|
841
967
|
) -> "CreateMetafieldMutation":
|
|
842
968
|
data = input.copy()
|
|
843
969
|
|
|
844
|
-
metafield =
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
970
|
+
metafield = (
|
|
971
|
+
serializers.MetafieldModelSerializer.map(
|
|
972
|
+
data=data,
|
|
973
|
+
context=info.context.request,
|
|
974
|
+
)
|
|
975
|
+
.save()
|
|
976
|
+
.instance
|
|
977
|
+
)
|
|
848
978
|
|
|
849
979
|
return CreateMetafieldMutation(metafield=metafield)
|
|
850
980
|
|
|
@@ -862,10 +992,14 @@ class UpdateMetafieldMutation(utils.BaseMutation):
|
|
|
862
992
|
data = input.copy()
|
|
863
993
|
instance = core.Metafield.access_by(info.context.request).get(id=data.get("id"))
|
|
864
994
|
|
|
865
|
-
metafield =
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
995
|
+
metafield = (
|
|
996
|
+
serializers.MetafieldModelSerializer.map(
|
|
997
|
+
instance,
|
|
998
|
+
data=data,
|
|
999
|
+
context=info.context.request,
|
|
1000
|
+
)
|
|
1001
|
+
.save()
|
|
1002
|
+
.instance
|
|
1003
|
+
)
|
|
870
1004
|
|
|
871
1005
|
return UpdateMetafieldMutation(metafield=metafield)
|
|
@@ -639,7 +639,6 @@ class AddressType:
|
|
|
639
639
|
email: typing.Optional[str]
|
|
640
640
|
phone_number: typing.Optional[str]
|
|
641
641
|
state_code: typing.Optional[str]
|
|
642
|
-
suburb: typing.Optional[str]
|
|
643
642
|
residential: typing.Optional[bool]
|
|
644
643
|
street_number: typing.Optional[str]
|
|
645
644
|
address_line1: typing.Optional[str]
|
|
@@ -1118,6 +1117,7 @@ class ShipmentType:
|
|
|
1118
1117
|
@strawberry.type
|
|
1119
1118
|
class ServiceZoneType:
|
|
1120
1119
|
object_type: str
|
|
1120
|
+
id: typing.Optional[str] = None
|
|
1121
1121
|
label: typing.Optional[str] = None
|
|
1122
1122
|
rate: typing.Optional[float] = None
|
|
1123
1123
|
|
|
@@ -1176,7 +1176,8 @@ class ServiceLevelType:
|
|
|
1176
1176
|
|
|
1177
1177
|
@strawberry.field
|
|
1178
1178
|
def zones(self: providers.ServiceLevel) -> typing.List[ServiceZoneType]:
|
|
1179
|
-
|
|
1179
|
+
# Use computed_zones for backward compatibility with optimized structure
|
|
1180
|
+
return [ServiceZoneType.parse(zone) for zone in self.computed_zones]
|
|
1180
1181
|
|
|
1181
1182
|
@strawberry.field
|
|
1182
1183
|
def metadata(self: providers.RateSheet) -> typing.Optional[utils.JSON]:
|
|
@@ -12,6 +12,7 @@ import karrio.server.manager.models as manager
|
|
|
12
12
|
import karrio.server.graph.models as graph
|
|
13
13
|
import karrio.server.core.models as core
|
|
14
14
|
import karrio.server.user.models as auth
|
|
15
|
+
import karrio.server.core.gateway as gateway
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class UserModelSerializer(serializers.ModelSerializer):
|
|
@@ -268,10 +269,10 @@ class ServiceLevelModelSerializer(serializers.ModelSerializer):
|
|
|
268
269
|
)
|
|
269
270
|
self.instance.save(update_fields=["zones"])
|
|
270
271
|
|
|
271
|
-
def update(self, instance, validated_data):
|
|
272
|
+
def update(self, instance, validated_data, context=None, **kwargs):
|
|
272
273
|
"""Handle partial updates of service level data including zones."""
|
|
273
274
|
zones_data = validated_data.pop("zones", None)
|
|
274
|
-
instance = super().update(instance, validated_data)
|
|
275
|
+
instance = super().update(instance, validated_data, context=context)
|
|
275
276
|
|
|
276
277
|
if zones_data is not None:
|
|
277
278
|
# Handle zone updates if provided
|
|
@@ -362,10 +363,10 @@ class RateSheetModelSerializer(serializers.ModelSerializer):
|
|
|
362
363
|
).filter(id__in=list(_ids))
|
|
363
364
|
|
|
364
365
|
for carrier in _carriers:
|
|
365
|
-
carrier.
|
|
366
|
+
carrier.rate_sheet = (
|
|
366
367
|
self.instance if carrier.id in carriers else None
|
|
367
368
|
)
|
|
368
|
-
carrier.
|
|
369
|
+
carrier.save(update_fields=["rate_sheet"])
|
|
369
370
|
|
|
370
371
|
def update(self, instance, validated_data, **kwargs):
|
|
371
372
|
"""Handle updates of rate sheet data including services and carriers."""
|
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from unittest.mock import ANY, patch
|
|
3
|
+
from django.urls import reverse
|
|
4
|
+
from rest_framework import status
|
|
5
|
+
from karrio.core.models import RateDetails, ChargeDetails
|
|
6
|
+
from karrio.server.graph.tests.base import GraphTestCase, Result
|
|
7
|
+
import karrio.server.manager.models as manager
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestPartialShipmentMutation(GraphTestCase):
|
|
11
|
+
def setUp(self) -> None:
|
|
12
|
+
super().setUp()
|
|
13
|
+
# Create a draft shipment using the REST API
|
|
14
|
+
self.shipment = self._create_draft_shipment()
|
|
15
|
+
|
|
16
|
+
def _create_draft_shipment(self):
|
|
17
|
+
"""Create a draft shipment using the REST API without service (no rates fetched)"""
|
|
18
|
+
url = reverse("karrio.server.manager:shipment-list")
|
|
19
|
+
|
|
20
|
+
with patch("karrio.server.core.gateway.utils.identity") as mock:
|
|
21
|
+
mock.return_value = RETURNED_RATES_VALUE
|
|
22
|
+
response = self.client.post(url, DRAFT_SHIPMENT_DATA)
|
|
23
|
+
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
|
24
|
+
response_data = json.loads(response.content)
|
|
25
|
+
return response_data
|
|
26
|
+
|
|
27
|
+
def test_partial_update_options_with_none_values(self):
|
|
28
|
+
"""Test updating options with explicit None values to remove existing options"""
|
|
29
|
+
shipment_id = self.shipment["id"]
|
|
30
|
+
|
|
31
|
+
response = self.query(
|
|
32
|
+
"""
|
|
33
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
34
|
+
partial_shipment_update(input: $data) {
|
|
35
|
+
shipment {
|
|
36
|
+
id
|
|
37
|
+
options
|
|
38
|
+
}
|
|
39
|
+
errors {
|
|
40
|
+
field
|
|
41
|
+
messages
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
""",
|
|
46
|
+
operation_name="partial_shipment_update",
|
|
47
|
+
variables={
|
|
48
|
+
"data": {
|
|
49
|
+
"id": shipment_id,
|
|
50
|
+
"options": {
|
|
51
|
+
"insurance": None,
|
|
52
|
+
"signature_confirmation": None,
|
|
53
|
+
"currency": "USD",
|
|
54
|
+
"new_option": "test_value",
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
self.assertResponseNoErrors(response)
|
|
61
|
+
self.assertDictEqual(response.data, OPTIONS_UPDATE_RESPONSE)
|
|
62
|
+
|
|
63
|
+
def test_partial_update_shipper_address_fields(self):
|
|
64
|
+
"""Test updating random fields within shipper address"""
|
|
65
|
+
shipment_id = self.shipment["id"]
|
|
66
|
+
|
|
67
|
+
response = self.query(
|
|
68
|
+
"""
|
|
69
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
70
|
+
partial_shipment_update(input: $data) {
|
|
71
|
+
shipment {
|
|
72
|
+
id
|
|
73
|
+
shipper {
|
|
74
|
+
id
|
|
75
|
+
company_name
|
|
76
|
+
person_name
|
|
77
|
+
phone_number
|
|
78
|
+
email
|
|
79
|
+
city
|
|
80
|
+
postal_code
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
errors {
|
|
84
|
+
field
|
|
85
|
+
messages
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
""",
|
|
90
|
+
operation_name="partial_shipment_update",
|
|
91
|
+
variables={
|
|
92
|
+
"data": {
|
|
93
|
+
"id": shipment_id,
|
|
94
|
+
"shipper": {
|
|
95
|
+
"company_name": "Updated Corp Inc.",
|
|
96
|
+
"email": "updated@example.com",
|
|
97
|
+
"phone_number": "555-123-4567",
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
self.assertResponseNoErrors(response)
|
|
104
|
+
self.assertDictEqual(response.data, SHIPPER_UPDATE_RESPONSE)
|
|
105
|
+
|
|
106
|
+
def test_partial_update_recipient_address_fields(self):
|
|
107
|
+
"""Test updating random fields within recipient address"""
|
|
108
|
+
shipment_id = self.shipment["id"]
|
|
109
|
+
|
|
110
|
+
response = self.query(
|
|
111
|
+
"""
|
|
112
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
113
|
+
partial_shipment_update(input: $data) {
|
|
114
|
+
shipment {
|
|
115
|
+
id
|
|
116
|
+
recipient {
|
|
117
|
+
id
|
|
118
|
+
company_name
|
|
119
|
+
person_name
|
|
120
|
+
address_line1
|
|
121
|
+
city
|
|
122
|
+
state_code
|
|
123
|
+
residential
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
errors {
|
|
127
|
+
field
|
|
128
|
+
messages
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
""",
|
|
133
|
+
operation_name="partial_shipment_update",
|
|
134
|
+
variables={
|
|
135
|
+
"data": {
|
|
136
|
+
"id": shipment_id,
|
|
137
|
+
"recipient": {
|
|
138
|
+
"person_name": "John Updated",
|
|
139
|
+
"address_line1": "456 Updated St",
|
|
140
|
+
"residential": True,
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
self.assertResponseNoErrors(response)
|
|
147
|
+
self.assertDictEqual(response.data, RECIPIENT_UPDATE_RESPONSE)
|
|
148
|
+
|
|
149
|
+
def test_partial_update_payment_and_metadata(self):
|
|
150
|
+
"""Test updating payment information and metadata"""
|
|
151
|
+
shipment_id = self.shipment["id"]
|
|
152
|
+
|
|
153
|
+
response = self.query(
|
|
154
|
+
"""
|
|
155
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
156
|
+
partial_shipment_update(input: $data) {
|
|
157
|
+
shipment {
|
|
158
|
+
id
|
|
159
|
+
payment {
|
|
160
|
+
paid_by
|
|
161
|
+
currency
|
|
162
|
+
account_number
|
|
163
|
+
}
|
|
164
|
+
metadata
|
|
165
|
+
reference
|
|
166
|
+
}
|
|
167
|
+
errors {
|
|
168
|
+
field
|
|
169
|
+
messages
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
""",
|
|
174
|
+
operation_name="partial_shipment_update",
|
|
175
|
+
variables={
|
|
176
|
+
"data": {
|
|
177
|
+
"id": shipment_id,
|
|
178
|
+
"payment": {"paid_by": "recipient", "account_number": "123456789"},
|
|
179
|
+
"metadata": {"customer_id": "CUST123", "order_number": "ORD456"},
|
|
180
|
+
"reference": "REF789",
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
self.assertResponseNoErrors(response)
|
|
186
|
+
self.assertDictEqual(response.data, PAYMENT_METADATA_UPDATE_RESPONSE)
|
|
187
|
+
|
|
188
|
+
def test_partial_update_parcel_information(self):
|
|
189
|
+
"""Test updating parcel information"""
|
|
190
|
+
shipment_id = self.shipment["id"]
|
|
191
|
+
|
|
192
|
+
response = self.query(
|
|
193
|
+
"""
|
|
194
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
195
|
+
partial_shipment_update(input: $data) {
|
|
196
|
+
shipment {
|
|
197
|
+
id
|
|
198
|
+
parcels {
|
|
199
|
+
id
|
|
200
|
+
weight
|
|
201
|
+
weight_unit
|
|
202
|
+
package_preset
|
|
203
|
+
description
|
|
204
|
+
reference_number
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
errors {
|
|
208
|
+
field
|
|
209
|
+
messages
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
""",
|
|
214
|
+
operation_name="partial_shipment_update",
|
|
215
|
+
variables={
|
|
216
|
+
"data": {
|
|
217
|
+
"id": shipment_id,
|
|
218
|
+
"parcels": [
|
|
219
|
+
{
|
|
220
|
+
"weight": 2.5,
|
|
221
|
+
"weight_unit": "LB",
|
|
222
|
+
"description": "Updated parcel description",
|
|
223
|
+
"package_preset": "canadapost_corrugated_medium_box",
|
|
224
|
+
}
|
|
225
|
+
],
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
self.assertResponseNoErrors(response)
|
|
231
|
+
self.assertDictEqual(response.data, PARCEL_UPDATE_RESPONSE)
|
|
232
|
+
|
|
233
|
+
def test_partial_update_label_type_and_options_merge(self):
|
|
234
|
+
"""Test updating label type and ensuring options are properly merged"""
|
|
235
|
+
shipment_id = self.shipment["id"]
|
|
236
|
+
|
|
237
|
+
# First, set some initial options
|
|
238
|
+
self.query(
|
|
239
|
+
"""
|
|
240
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
241
|
+
partial_shipment_update(input: $data) {
|
|
242
|
+
shipment {
|
|
243
|
+
id
|
|
244
|
+
options
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
""",
|
|
249
|
+
operation_name="partial_shipment_update",
|
|
250
|
+
variables={
|
|
251
|
+
"data": {
|
|
252
|
+
"id": shipment_id,
|
|
253
|
+
"options": {
|
|
254
|
+
"insurance": 100,
|
|
255
|
+
"signature_confirmation": True,
|
|
256
|
+
"currency": "CAD",
|
|
257
|
+
},
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
# Now update label type and add more options
|
|
263
|
+
response = self.query(
|
|
264
|
+
"""
|
|
265
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
266
|
+
partial_shipment_update(input: $data) {
|
|
267
|
+
shipment {
|
|
268
|
+
id
|
|
269
|
+
label_type
|
|
270
|
+
options
|
|
271
|
+
}
|
|
272
|
+
errors {
|
|
273
|
+
field
|
|
274
|
+
messages
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
""",
|
|
279
|
+
operation_name="partial_shipment_update",
|
|
280
|
+
variables={
|
|
281
|
+
"data": {
|
|
282
|
+
"id": shipment_id,
|
|
283
|
+
"label_type": "ZPL",
|
|
284
|
+
"options": {"delivery_confirmation": True, "priority": "high"},
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
self.assertResponseNoErrors(response)
|
|
290
|
+
self.assertDictEqual(response.data, LABEL_OPTIONS_MERGE_RESPONSE)
|
|
291
|
+
|
|
292
|
+
def test_full_shipment_update_simulation(self):
|
|
293
|
+
"""Test updating multiple fields at once to simulate frontend save operation"""
|
|
294
|
+
shipment_id = self.shipment["id"]
|
|
295
|
+
|
|
296
|
+
# Set the shipment ID dynamically in the test data
|
|
297
|
+
full_update_data = FULL_UPDATE_DATA.copy()
|
|
298
|
+
full_update_data["data"]["id"] = shipment_id
|
|
299
|
+
|
|
300
|
+
response = self.query(
|
|
301
|
+
"""
|
|
302
|
+
mutation partial_shipment_update($data: PartialShipmentMutationInput!) {
|
|
303
|
+
partial_shipment_update(input: $data) {
|
|
304
|
+
shipment {
|
|
305
|
+
id
|
|
306
|
+
status
|
|
307
|
+
shipper {
|
|
308
|
+
company_name
|
|
309
|
+
person_name
|
|
310
|
+
email
|
|
311
|
+
}
|
|
312
|
+
recipient {
|
|
313
|
+
company_name
|
|
314
|
+
person_name
|
|
315
|
+
email
|
|
316
|
+
}
|
|
317
|
+
parcels {
|
|
318
|
+
weight
|
|
319
|
+
weight_unit
|
|
320
|
+
description
|
|
321
|
+
}
|
|
322
|
+
payment {
|
|
323
|
+
paid_by
|
|
324
|
+
currency
|
|
325
|
+
}
|
|
326
|
+
options
|
|
327
|
+
metadata
|
|
328
|
+
reference
|
|
329
|
+
label_type
|
|
330
|
+
}
|
|
331
|
+
errors {
|
|
332
|
+
field
|
|
333
|
+
messages
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
""",
|
|
338
|
+
operation_name="partial_shipment_update",
|
|
339
|
+
variables=full_update_data,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
self.assertResponseNoErrors(response)
|
|
343
|
+
self.assertDictEqual(response.data, FULL_UPDATE_SIMULATION_RESPONSE)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
# Test data
|
|
347
|
+
DRAFT_SHIPMENT_DATA = {
|
|
348
|
+
"recipient": {
|
|
349
|
+
"address_line1": "125 Church St",
|
|
350
|
+
"person_name": "John Poop",
|
|
351
|
+
"company_name": "A corp.",
|
|
352
|
+
"phone_number": "514 000 0000",
|
|
353
|
+
"city": "Moncton",
|
|
354
|
+
"country_code": "CA",
|
|
355
|
+
"postal_code": "E1C4Z8",
|
|
356
|
+
"residential": False,
|
|
357
|
+
"state_code": "NB",
|
|
358
|
+
},
|
|
359
|
+
"shipper": {
|
|
360
|
+
"address_line1": "5840 Oak St",
|
|
361
|
+
"person_name": "Jane Doe",
|
|
362
|
+
"company_name": "B corp.",
|
|
363
|
+
"phone_number": "514 000 9999",
|
|
364
|
+
"city": "Vancouver",
|
|
365
|
+
"country_code": "CA",
|
|
366
|
+
"postal_code": "V6M2V9",
|
|
367
|
+
"residential": False,
|
|
368
|
+
"state_code": "BC",
|
|
369
|
+
},
|
|
370
|
+
"parcels": [
|
|
371
|
+
{
|
|
372
|
+
"weight": 1,
|
|
373
|
+
"weight_unit": "KG",
|
|
374
|
+
"package_preset": "canadapost_corrugated_small_box",
|
|
375
|
+
}
|
|
376
|
+
],
|
|
377
|
+
"payment": {"currency": "CAD", "paid_by": "sender"},
|
|
378
|
+
# Note: No service specified, so this creates a draft without rates
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
RETURNED_RATES_VALUE = [
|
|
382
|
+
[
|
|
383
|
+
RateDetails(
|
|
384
|
+
carrier_id="canadapost",
|
|
385
|
+
carrier_name="canadapost",
|
|
386
|
+
currency="CAD",
|
|
387
|
+
transit_days=2,
|
|
388
|
+
service="canadapost_priority",
|
|
389
|
+
total_charge=106.71,
|
|
390
|
+
extra_charges=[
|
|
391
|
+
ChargeDetails(amount=13.92, currency="CAD", name="Duty and taxes"),
|
|
392
|
+
ChargeDetails(amount=2.7, currency="CAD", name="Fuel surcharge"),
|
|
393
|
+
ChargeDetails(amount=-11.74, currency="CAD", name="SMB Savings"),
|
|
394
|
+
ChargeDetails(amount=-9.04, currency="CAD", name="Discount"),
|
|
395
|
+
ChargeDetails(amount=101.83, currency="CAD", name="Base surcharge"),
|
|
396
|
+
],
|
|
397
|
+
)
|
|
398
|
+
],
|
|
399
|
+
[],
|
|
400
|
+
]
|
|
401
|
+
|
|
402
|
+
FULL_UPDATE_DATA = {
|
|
403
|
+
"data": {
|
|
404
|
+
"id": None, # Will be set dynamically in the test
|
|
405
|
+
"shipper": {
|
|
406
|
+
"company_name": "Full Update Shipper Corp",
|
|
407
|
+
"person_name": "Updated Shipper",
|
|
408
|
+
"email": "shipper@fullupdate.com",
|
|
409
|
+
},
|
|
410
|
+
"recipient": {
|
|
411
|
+
"company_name": "Full Update Recipient Corp",
|
|
412
|
+
"person_name": "Updated Recipient",
|
|
413
|
+
"email": "recipient@fullupdate.com",
|
|
414
|
+
},
|
|
415
|
+
"parcels": [
|
|
416
|
+
{"weight": 3.0, "weight_unit": "KG", "description": "Full update parcel"}
|
|
417
|
+
],
|
|
418
|
+
"payment": {"paid_by": "third_party", "currency": "USD"},
|
|
419
|
+
"options": {"insurance": 250, "priority": "express"},
|
|
420
|
+
"metadata": {"full_update": True, "test_case": "full_update_simulation"},
|
|
421
|
+
"reference": "FULL_UPDATE_REF",
|
|
422
|
+
"label_type": "PNG",
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
# Expected responses for assertDictEqual
|
|
427
|
+
OPTIONS_UPDATE_RESPONSE = {
|
|
428
|
+
"data": {
|
|
429
|
+
"partial_shipment_update": {
|
|
430
|
+
"shipment": {
|
|
431
|
+
"id": ANY,
|
|
432
|
+
"options": {
|
|
433
|
+
"shipping_date": ANY,
|
|
434
|
+
"shipment_date": ANY,
|
|
435
|
+
"currency": "USD",
|
|
436
|
+
"new_option": "test_value",
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
"errors": None,
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
SHIPPER_UPDATE_RESPONSE = {
|
|
445
|
+
"data": {
|
|
446
|
+
"partial_shipment_update": {
|
|
447
|
+
"shipment": {
|
|
448
|
+
"id": ANY,
|
|
449
|
+
"shipper": {
|
|
450
|
+
"id": ANY,
|
|
451
|
+
"company_name": "Updated Corp Inc.",
|
|
452
|
+
"person_name": "Jane Doe",
|
|
453
|
+
"phone_number": "555-123-4567",
|
|
454
|
+
"email": "updated@example.com",
|
|
455
|
+
"city": "Vancouver",
|
|
456
|
+
"postal_code": "V6M2V9",
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
"errors": None,
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
RECIPIENT_UPDATE_RESPONSE = {
|
|
465
|
+
"data": {
|
|
466
|
+
"partial_shipment_update": {
|
|
467
|
+
"shipment": {
|
|
468
|
+
"id": ANY,
|
|
469
|
+
"recipient": {
|
|
470
|
+
"id": ANY,
|
|
471
|
+
"company_name": "A corp.",
|
|
472
|
+
"person_name": "John Updated",
|
|
473
|
+
"address_line1": "456 Updated St",
|
|
474
|
+
"city": "Moncton",
|
|
475
|
+
"state_code": "NB",
|
|
476
|
+
"residential": True,
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
"errors": None,
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
PAYMENT_METADATA_UPDATE_RESPONSE = {
|
|
485
|
+
"data": {
|
|
486
|
+
"partial_shipment_update": {
|
|
487
|
+
"shipment": {
|
|
488
|
+
"id": ANY,
|
|
489
|
+
"payment": {
|
|
490
|
+
"paid_by": "recipient",
|
|
491
|
+
"currency": None,
|
|
492
|
+
"account_number": "123456789",
|
|
493
|
+
},
|
|
494
|
+
"metadata": {
|
|
495
|
+
"customer_id": "CUST123",
|
|
496
|
+
"order_number": "ORD456",
|
|
497
|
+
},
|
|
498
|
+
"reference": "REF789",
|
|
499
|
+
},
|
|
500
|
+
"errors": None,
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
PARCEL_UPDATE_RESPONSE = {
|
|
506
|
+
"data": {
|
|
507
|
+
"partial_shipment_update": {
|
|
508
|
+
"shipment": {
|
|
509
|
+
"id": ANY,
|
|
510
|
+
"parcels": [
|
|
511
|
+
{
|
|
512
|
+
"id": ANY,
|
|
513
|
+
"weight": 1.0,
|
|
514
|
+
"weight_unit": "KG",
|
|
515
|
+
"package_preset": "canadapost_corrugated_small_box",
|
|
516
|
+
"description": None,
|
|
517
|
+
"reference_number": ANY,
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"id": ANY,
|
|
521
|
+
"weight": 2.5,
|
|
522
|
+
"weight_unit": "LB",
|
|
523
|
+
"package_preset": "canadapost_corrugated_medium_box",
|
|
524
|
+
"description": "Updated parcel description",
|
|
525
|
+
"reference_number": ANY,
|
|
526
|
+
},
|
|
527
|
+
],
|
|
528
|
+
},
|
|
529
|
+
"errors": None,
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
LABEL_OPTIONS_MERGE_RESPONSE = {
|
|
535
|
+
"data": {
|
|
536
|
+
"partial_shipment_update": {
|
|
537
|
+
"shipment": {
|
|
538
|
+
"id": ANY,
|
|
539
|
+
"label_type": "ZPL",
|
|
540
|
+
"options": {
|
|
541
|
+
"shipping_date": ANY,
|
|
542
|
+
"shipment_date": ANY,
|
|
543
|
+
"currency": "CAD",
|
|
544
|
+
"insurance": 100,
|
|
545
|
+
"signature_confirmation": True,
|
|
546
|
+
"delivery_confirmation": True,
|
|
547
|
+
"priority": "high",
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
"errors": None,
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
FULL_UPDATE_SIMULATION_RESPONSE = {
|
|
556
|
+
"data": {
|
|
557
|
+
"partial_shipment_update": {
|
|
558
|
+
"shipment": {
|
|
559
|
+
"id": ANY,
|
|
560
|
+
"status": "draft",
|
|
561
|
+
"shipper": {
|
|
562
|
+
"company_name": "Full Update Shipper Corp",
|
|
563
|
+
"person_name": "Updated Shipper",
|
|
564
|
+
"email": "shipper@fullupdate.com",
|
|
565
|
+
},
|
|
566
|
+
"recipient": {
|
|
567
|
+
"company_name": "Full Update Recipient Corp",
|
|
568
|
+
"person_name": "Updated Recipient",
|
|
569
|
+
"email": "recipient@fullupdate.com",
|
|
570
|
+
},
|
|
571
|
+
"parcels": [
|
|
572
|
+
{
|
|
573
|
+
"weight": 1.0,
|
|
574
|
+
"weight_unit": "KG",
|
|
575
|
+
"description": None,
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
"weight": 3.0,
|
|
579
|
+
"weight_unit": "KG",
|
|
580
|
+
"description": "Full update parcel",
|
|
581
|
+
},
|
|
582
|
+
],
|
|
583
|
+
"payment": {
|
|
584
|
+
"paid_by": "third_party",
|
|
585
|
+
"currency": "USD",
|
|
586
|
+
},
|
|
587
|
+
"options": {
|
|
588
|
+
"shipping_date": ANY,
|
|
589
|
+
"shipment_date": ANY,
|
|
590
|
+
"insurance": 250,
|
|
591
|
+
"priority": "express",
|
|
592
|
+
},
|
|
593
|
+
"metadata": {
|
|
594
|
+
"full_update": True,
|
|
595
|
+
"test_case": "full_update_simulation",
|
|
596
|
+
},
|
|
597
|
+
"reference": "FULL_UPDATE_REF",
|
|
598
|
+
"label_type": "PNG",
|
|
599
|
+
},
|
|
600
|
+
"errors": None,
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
@@ -305,8 +305,14 @@ UPDATE_RATE_SHEET_RESPONSE = {
|
|
|
305
305
|
"services": [
|
|
306
306
|
{
|
|
307
307
|
"id": ANY,
|
|
308
|
-
"service_name": "
|
|
309
|
-
"zones": [
|
|
308
|
+
"service_name": "Updated Service",
|
|
309
|
+
"zones": [
|
|
310
|
+
{
|
|
311
|
+
"country_codes": ["US", "CA"],
|
|
312
|
+
"label": "Updated Zone",
|
|
313
|
+
"rate": 20.0,
|
|
314
|
+
}
|
|
315
|
+
],
|
|
310
316
|
}
|
|
311
317
|
],
|
|
312
318
|
}
|
{karrio_server_graph-2025.5rc11.dist-info → karrio_server_graph-2025.5rc13.dist-info}/RECORD
RENAMED
|
@@ -4,7 +4,7 @@ karrio/server/graph/apps.py,sha256=grL5ySDnW2amzj0nTXFm-WCoTWViVYvKqGlsi4k5epI,9
|
|
|
4
4
|
karrio/server/graph/forms.py,sha256=5iGC3hj6dsAsupYz4QubyygTeTKDRR56Q5mYq0vbGhI,1962
|
|
5
5
|
karrio/server/graph/models.py,sha256=CEnE4AsVyjBufyK6ebWmUH3s8DwA0HvZg0fUoZb5Pn4,1321
|
|
6
6
|
karrio/server/graph/schema.py,sha256=2dXM8nD1usOc1S6QSalajoFmgwYuXxsrwj20AJ5HtT4,1151
|
|
7
|
-
karrio/server/graph/serializers.py,sha256=
|
|
7
|
+
karrio/server/graph/serializers.py,sha256=kAVpyoN74gkA20ZnmDycvr_yrwFOb_A9di2-vrkdL7U,13760
|
|
8
8
|
karrio/server/graph/urls.py,sha256=HKo0gkx5TgoWDV0ap2QCtueNTmaAqvX6qVDe3c2UT1E,183
|
|
9
9
|
karrio/server/graph/utils.py,sha256=eeIKeTfGP-8U6MkdMdTyobnk6wbNEE75Bm0cFu85RfU,9031
|
|
10
10
|
karrio/server/graph/views.py,sha256=qWfa-wteB-Mb7glAYz6SVlZSwHPw_ImMm7XVmewdmTQ,2889
|
|
@@ -15,10 +15,10 @@ karrio/server/graph/migrations/0001_initial.py,sha256=oeaS5JSkQP6w9ulYar3mdn695y
|
|
|
15
15
|
karrio/server/graph/migrations/0002_auto_20210512_1353.py,sha256=TnUwR9EP0qp3gJ38f9w0PYawK2VheDtqXEgyRhYZS2M,538
|
|
16
16
|
karrio/server/graph/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
karrio/server/graph/schemas/__init__.py,sha256=Kn-I1j3HP3jwZccpz6FL9r1k6b3UEAMVh2kFPCKNS0w,80
|
|
18
|
-
karrio/server/graph/schemas/base/__init__.py,sha256=
|
|
19
|
-
karrio/server/graph/schemas/base/inputs.py,sha256=
|
|
20
|
-
karrio/server/graph/schemas/base/mutations.py,sha256=
|
|
21
|
-
karrio/server/graph/schemas/base/types.py,sha256=
|
|
18
|
+
karrio/server/graph/schemas/base/__init__.py,sha256=J6pf4SzfAtQ4yaNapEuHuoyOA0-UGhueqDD3n0JzTb0,15118
|
|
19
|
+
karrio/server/graph/schemas/base/inputs.py,sha256=T1T7cNVGudgVGOkPnus6TfK_i-lT_cjOBlpaPTHummk,21363
|
|
20
|
+
karrio/server/graph/schemas/base/mutations.py,sha256=1S-aUpoKwwDslLtbReJb_5kx9tDr3-EfAhQQ9D7-6K0,33583
|
|
21
|
+
karrio/server/graph/schemas/base/types.py,sha256=lKC-mdLluLNaPn9DXQDxh7Vl8JT9b_s_CIqZkiO0NWo,46458
|
|
22
22
|
karrio/server/graph/templates/graphql/graphiql.html,sha256=MQjQbBqoRE0QLsOUck8SaXo6B2oJO8dT6YZzUqbDan0,3786
|
|
23
23
|
karrio/server/graph/templates/karrio/email_change_email.html,sha256=YHqTy9VGV_s7kio57Tg3v7TCIN3QlnPHi2ioTOcHJLE,467
|
|
24
24
|
karrio/server/graph/templates/karrio/email_change_email.txt,sha256=NXXuzLR63hn2F1fVAjzmuguptuuTvujwqI7YLSrQoio,431
|
|
@@ -27,11 +27,12 @@ karrio/server/graph/tests/__init__.py,sha256=dPzsYY5hoO5gmY6fhL8tiz7Bfst8RB3JzsB
|
|
|
27
27
|
karrio/server/graph/tests/base.py,sha256=m3k1CE-d9JHDsqfyXX0Fwksmkel33S7sh9-zkypp8wc,4004
|
|
28
28
|
karrio/server/graph/tests/test_carrier_connections.py,sha256=PoXxJB53jBIz8j1GYCzTiaTW14Q0D1McdOkDYgcOqNM,6140
|
|
29
29
|
karrio/server/graph/tests/test_metafield.py,sha256=K7Oon0CLEm_MUMbmcu0t2iAZvFN8Wl7Kp4QAWeUXo_Y,12783
|
|
30
|
-
karrio/server/graph/tests/
|
|
30
|
+
karrio/server/graph/tests/test_partial_shipments.py,sha256=dPIdIq4wiyovOaIIzbIX69eZnBqCA4ZvBSiGKYADM2g,19031
|
|
31
|
+
karrio/server/graph/tests/test_rate_sheets.py,sha256=cUzPV8dXQFPFh1r7W8bY6Lou3fjh8f9VGpyZrfbMXec,10300
|
|
31
32
|
karrio/server/graph/tests/test_templates.py,sha256=WVU6vcfr6tEk917uSn1dECU8bkQtgD7FNuE-GJuFido,21626
|
|
32
33
|
karrio/server/graph/tests/test_user_info.py,sha256=K91BL7SgxLWflCZriSVI8Vt5M5RIqmSCHKrgN2w8GmM,1928
|
|
33
34
|
karrio/server/settings/graph.py,sha256=cz2yQHbp3xCfyFKuUkPEFfkI2fFVggExIY49wGz7mt0,106
|
|
34
|
-
karrio_server_graph-2025.
|
|
35
|
-
karrio_server_graph-2025.
|
|
36
|
-
karrio_server_graph-2025.
|
|
37
|
-
karrio_server_graph-2025.
|
|
35
|
+
karrio_server_graph-2025.5rc13.dist-info/METADATA,sha256=qUDbtpb-Ih-hHRixZXLIiLxsPIcnsCJaqIf14lzGcJk,744
|
|
36
|
+
karrio_server_graph-2025.5rc13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
37
|
+
karrio_server_graph-2025.5rc13.dist-info/top_level.txt,sha256=D1D7x8R3cTfjF_15mfiO7wCQ5QMtuM4x8GaPr7z5i78,12
|
|
38
|
+
karrio_server_graph-2025.5rc13.dist-info/RECORD,,
|
|
File without changes
|
{karrio_server_graph-2025.5rc11.dist-info → karrio_server_graph-2025.5rc13.dist-info}/top_level.txt
RENAMED
|
File without changes
|