karrio-server-pricing 2026.1.1__py3-none-any.whl → 2026.1.3__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/pricing/admin.py +119 -23
- karrio/server/pricing/apps.py +5 -1
- karrio/server/pricing/migrations/0076_create_markup_and_fee_models.py +258 -0
- karrio/server/pricing/migrations/0077_migrate_surcharge_to_markup_data.py +70 -0
- karrio/server/pricing/migrations/0078_cleanup.py +109 -0
- karrio/server/pricing/migrations/0079_fee_snapshot_model.py +283 -0
- karrio/server/pricing/models.py +268 -87
- karrio/server/pricing/serializers.py +16 -11
- karrio/server/pricing/signals.py +136 -12
- karrio/server/pricing/tests.py +397 -9
- {karrio_server_pricing-2026.1.1.dist-info → karrio_server_pricing-2026.1.3.dist-info}/METADATA +1 -1
- {karrio_server_pricing-2026.1.1.dist-info → karrio_server_pricing-2026.1.3.dist-info}/RECORD +14 -10
- {karrio_server_pricing-2026.1.1.dist-info → karrio_server_pricing-2026.1.3.dist-info}/WHEEL +1 -1
- {karrio_server_pricing-2026.1.1.dist-info → karrio_server_pricing-2026.1.3.dist-info}/top_level.txt +0 -0
karrio/server/pricing/tests.py
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the Pricing module (Markup and Fee models).
|
|
3
|
+
|
|
4
|
+
These tests cover:
|
|
5
|
+
1. Markup application to shipping rates (amount and percentage types)
|
|
6
|
+
2. Fee capture after shipment label creation
|
|
7
|
+
3. Various filter combinations (carrier_codes, service_codes, connection_ids)
|
|
8
|
+
"""
|
|
9
|
+
|
|
1
10
|
import json
|
|
2
11
|
import logging
|
|
3
12
|
from unittest.mock import patch, ANY
|
|
13
|
+
from django.test import TestCase
|
|
4
14
|
from django.urls import reverse
|
|
5
15
|
from rest_framework import status
|
|
6
16
|
from karrio.core.models import RateDetails, ChargeDetails
|
|
7
17
|
from karrio.server.core.tests import APITestCase
|
|
8
18
|
import karrio.server.pricing.models as models
|
|
19
|
+
import karrio.server.pricing.signals as signals
|
|
9
20
|
|
|
10
21
|
logging.disable(logging.CRITICAL)
|
|
11
22
|
|
|
12
23
|
|
|
13
|
-
class
|
|
24
|
+
class TestMarkupApplication(APITestCase):
|
|
25
|
+
"""Test markup application to shipping rates."""
|
|
26
|
+
|
|
14
27
|
def setUp(self) -> None:
|
|
15
28
|
super().setUp()
|
|
16
29
|
|
|
17
|
-
|
|
30
|
+
# Create a markup targeting specific carriers and services
|
|
31
|
+
self.markup: models.Markup = models.Markup.objects.create(
|
|
18
32
|
**{
|
|
19
33
|
"amount": 1.0,
|
|
20
34
|
"name": "brokerage",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
35
|
+
"carrier_codes": ["canadapost"],
|
|
36
|
+
"service_codes": ["canadapost_priority", "canadapost_regular_parcel"],
|
|
23
37
|
}
|
|
24
38
|
)
|
|
25
39
|
|
|
26
|
-
def
|
|
40
|
+
def test_apply_markup_amount_to_shipment_rates(self):
|
|
41
|
+
"""Test applying fixed amount markup to rates."""
|
|
27
42
|
url = reverse("karrio.server.proxy:shipment-rates")
|
|
28
43
|
data = RATING_DATA
|
|
29
44
|
|
|
@@ -35,10 +50,11 @@ class TestPricing(APITestCase):
|
|
|
35
50
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
36
51
|
self.assertDictEqual(response_data, RATING_RESPONSE)
|
|
37
52
|
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
self.
|
|
41
|
-
self.
|
|
53
|
+
def test_apply_markup_percentage_to_shipment_rates(self):
|
|
54
|
+
"""Test applying percentage markup to rates."""
|
|
55
|
+
self.markup.amount = 2.0
|
|
56
|
+
self.markup.markup_type = "PERCENTAGE"
|
|
57
|
+
self.markup.save()
|
|
42
58
|
url = reverse("karrio.server.proxy:shipment-rates")
|
|
43
59
|
data = RATING_DATA
|
|
44
60
|
|
|
@@ -51,6 +67,378 @@ class TestPricing(APITestCase):
|
|
|
51
67
|
self.assertDictEqual(response_data, RATING_WITH_PERCENTAGE_RESPONSE)
|
|
52
68
|
|
|
53
69
|
|
|
70
|
+
class TestMarkupFilters(TestCase):
|
|
71
|
+
"""Test markup filter logic."""
|
|
72
|
+
|
|
73
|
+
def test_carrier_codes_filter(self):
|
|
74
|
+
"""Test that markup only applies to specified carrier codes."""
|
|
75
|
+
markup = models.Markup.objects.create(
|
|
76
|
+
name="fedex_markup",
|
|
77
|
+
amount=5.0,
|
|
78
|
+
markup_type="AMOUNT",
|
|
79
|
+
carrier_codes=["fedex"],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Create mock rate for FedEx
|
|
83
|
+
from karrio.server.core.datatypes import Rate, RateResponse
|
|
84
|
+
|
|
85
|
+
fedex_rate = Rate(
|
|
86
|
+
id="rate_1",
|
|
87
|
+
carrier_id="fedex",
|
|
88
|
+
carrier_name="fedex",
|
|
89
|
+
service="fedex_ground",
|
|
90
|
+
total_charge=10.0,
|
|
91
|
+
currency="USD",
|
|
92
|
+
extra_charges=[],
|
|
93
|
+
meta={"carrier_connection_id": "car_123"},
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
ups_rate = Rate(
|
|
97
|
+
id="rate_2",
|
|
98
|
+
carrier_id="ups",
|
|
99
|
+
carrier_name="ups",
|
|
100
|
+
service="ups_ground",
|
|
101
|
+
total_charge=12.0,
|
|
102
|
+
currency="USD",
|
|
103
|
+
extra_charges=[],
|
|
104
|
+
meta={"carrier_connection_id": "car_456"},
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
response = RateResponse(
|
|
108
|
+
rates=[fedex_rate, ups_rate],
|
|
109
|
+
messages=[],
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
result = markup.apply_charge(response)
|
|
113
|
+
|
|
114
|
+
# FedEx rate should have markup applied
|
|
115
|
+
fedex_result = next(r for r in result.rates if r.carrier_name == "fedex")
|
|
116
|
+
self.assertEqual(fedex_result.total_charge, 15.0) # 10 + 5
|
|
117
|
+
|
|
118
|
+
# UPS rate should NOT have markup applied
|
|
119
|
+
ups_result = next(r for r in result.rates if r.carrier_name == "ups")
|
|
120
|
+
self.assertEqual(ups_result.total_charge, 12.0) # unchanged
|
|
121
|
+
|
|
122
|
+
def test_service_codes_filter(self):
|
|
123
|
+
"""Test that markup only applies to specified service codes."""
|
|
124
|
+
markup = models.Markup.objects.create(
|
|
125
|
+
name="express_markup",
|
|
126
|
+
amount=10.0,
|
|
127
|
+
markup_type="PERCENTAGE",
|
|
128
|
+
service_codes=["fedex_overnight"],
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
from karrio.server.core.datatypes import Rate, RateResponse
|
|
132
|
+
|
|
133
|
+
overnight_rate = Rate(
|
|
134
|
+
id="rate_1",
|
|
135
|
+
carrier_id="fedex",
|
|
136
|
+
carrier_name="fedex",
|
|
137
|
+
service="fedex_overnight",
|
|
138
|
+
total_charge=100.0,
|
|
139
|
+
currency="USD",
|
|
140
|
+
extra_charges=[],
|
|
141
|
+
meta={"carrier_connection_id": "car_123"},
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
ground_rate = Rate(
|
|
145
|
+
id="rate_2",
|
|
146
|
+
carrier_id="fedex",
|
|
147
|
+
carrier_name="fedex",
|
|
148
|
+
service="fedex_ground",
|
|
149
|
+
total_charge=50.0,
|
|
150
|
+
currency="USD",
|
|
151
|
+
extra_charges=[],
|
|
152
|
+
meta={"carrier_connection_id": "car_123"},
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
response = RateResponse(
|
|
156
|
+
rates=[overnight_rate, ground_rate],
|
|
157
|
+
messages=[],
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
result = markup.apply_charge(response)
|
|
161
|
+
|
|
162
|
+
# Overnight rate should have 10% markup applied
|
|
163
|
+
overnight_result = next(r for r in result.rates if r.service == "fedex_overnight")
|
|
164
|
+
self.assertEqual(overnight_result.total_charge, 110.0) # 100 + 10%
|
|
165
|
+
|
|
166
|
+
# Ground rate should NOT have markup applied
|
|
167
|
+
ground_result = next(r for r in result.rates if r.service == "fedex_ground")
|
|
168
|
+
self.assertEqual(ground_result.total_charge, 50.0) # unchanged
|
|
169
|
+
|
|
170
|
+
def test_connection_ids_filter(self):
|
|
171
|
+
"""Test that markup only applies to specified connection IDs."""
|
|
172
|
+
markup = models.Markup.objects.create(
|
|
173
|
+
name="specific_connection_markup",
|
|
174
|
+
amount=3.0,
|
|
175
|
+
markup_type="AMOUNT",
|
|
176
|
+
connection_ids=["car_special_123"],
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
from karrio.server.core.datatypes import Rate, RateResponse
|
|
180
|
+
|
|
181
|
+
special_rate = Rate(
|
|
182
|
+
id="rate_1",
|
|
183
|
+
carrier_id="fedex",
|
|
184
|
+
carrier_name="fedex",
|
|
185
|
+
service="fedex_ground",
|
|
186
|
+
total_charge=25.0,
|
|
187
|
+
currency="USD",
|
|
188
|
+
extra_charges=[],
|
|
189
|
+
meta={"carrier_connection_id": "car_special_123"},
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
regular_rate = Rate(
|
|
193
|
+
id="rate_2",
|
|
194
|
+
carrier_id="fedex",
|
|
195
|
+
carrier_name="fedex",
|
|
196
|
+
service="fedex_ground",
|
|
197
|
+
total_charge=25.0,
|
|
198
|
+
currency="USD",
|
|
199
|
+
extra_charges=[],
|
|
200
|
+
meta={"carrier_connection_id": "car_regular_456"},
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
response = RateResponse(
|
|
204
|
+
rates=[special_rate, regular_rate],
|
|
205
|
+
messages=[],
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
result = markup.apply_charge(response)
|
|
209
|
+
|
|
210
|
+
# Rate with special connection should have markup
|
|
211
|
+
special_result = next(
|
|
212
|
+
r for r in result.rates
|
|
213
|
+
if r.meta.get("carrier_connection_id") == "car_special_123"
|
|
214
|
+
)
|
|
215
|
+
self.assertEqual(special_result.total_charge, 28.0) # 25 + 3
|
|
216
|
+
|
|
217
|
+
# Rate with regular connection should NOT have markup
|
|
218
|
+
regular_result = next(
|
|
219
|
+
r for r in result.rates
|
|
220
|
+
if r.meta.get("carrier_connection_id") == "car_regular_456"
|
|
221
|
+
)
|
|
222
|
+
self.assertEqual(regular_result.total_charge, 25.0) # unchanged
|
|
223
|
+
|
|
224
|
+
def test_empty_filters_apply_to_all(self):
|
|
225
|
+
"""Test that markup with no filters applies to all rates."""
|
|
226
|
+
markup = models.Markup.objects.create(
|
|
227
|
+
name="global_markup",
|
|
228
|
+
amount=1.0,
|
|
229
|
+
markup_type="AMOUNT",
|
|
230
|
+
carrier_codes=[],
|
|
231
|
+
service_codes=[],
|
|
232
|
+
connection_ids=[],
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
from karrio.server.core.datatypes import Rate, RateResponse
|
|
236
|
+
|
|
237
|
+
rate1 = Rate(
|
|
238
|
+
id="rate_1",
|
|
239
|
+
carrier_id="fedex",
|
|
240
|
+
carrier_name="fedex",
|
|
241
|
+
service="fedex_ground",
|
|
242
|
+
total_charge=10.0,
|
|
243
|
+
currency="USD",
|
|
244
|
+
extra_charges=[],
|
|
245
|
+
meta={},
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
rate2 = Rate(
|
|
249
|
+
id="rate_2",
|
|
250
|
+
carrier_id="ups",
|
|
251
|
+
carrier_name="ups",
|
|
252
|
+
service="ups_ground",
|
|
253
|
+
total_charge=12.0,
|
|
254
|
+
currency="USD",
|
|
255
|
+
extra_charges=[],
|
|
256
|
+
meta={},
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
response = RateResponse(
|
|
260
|
+
rates=[rate1, rate2],
|
|
261
|
+
messages=[],
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
result = markup.apply_charge(response)
|
|
265
|
+
|
|
266
|
+
# Both rates should have markup applied
|
|
267
|
+
for rate in result.rates:
|
|
268
|
+
if rate.carrier_name == "fedex":
|
|
269
|
+
self.assertEqual(rate.total_charge, 11.0) # 10 + 1
|
|
270
|
+
elif rate.carrier_name == "ups":
|
|
271
|
+
self.assertEqual(rate.total_charge, 13.0) # 12 + 1
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class TestFeeCapture(TestCase):
|
|
275
|
+
"""Test fee capture after shipment creation."""
|
|
276
|
+
|
|
277
|
+
def setUp(self):
|
|
278
|
+
"""Set up test data."""
|
|
279
|
+
# Create a markup
|
|
280
|
+
self.markup = models.Markup.objects.create(
|
|
281
|
+
name="test_markup",
|
|
282
|
+
amount=5.0,
|
|
283
|
+
markup_type="AMOUNT",
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
def test_capture_fees_from_shipment(self):
|
|
287
|
+
"""Test that fees are captured from shipment's selected_rate via signal.
|
|
288
|
+
|
|
289
|
+
When a shipment is saved with status='purchased' and a selected_rate,
|
|
290
|
+
the fee capture signal should automatically capture fees.
|
|
291
|
+
"""
|
|
292
|
+
from django.contrib.auth import get_user_model
|
|
293
|
+
import karrio.server.manager.models as manager
|
|
294
|
+
|
|
295
|
+
User = get_user_model()
|
|
296
|
+
user = User.objects.create_user(
|
|
297
|
+
email="test@example.com",
|
|
298
|
+
password="testpass123",
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
# Create a shipment with markup in extra_charges
|
|
302
|
+
# The signal should automatically capture fees on save
|
|
303
|
+
shipment = manager.Shipment.objects.create(
|
|
304
|
+
status="purchased",
|
|
305
|
+
test_mode=True,
|
|
306
|
+
shipper={"city": "Montreal"},
|
|
307
|
+
recipient={"city": "Toronto"},
|
|
308
|
+
parcels=[{"weight": 1}],
|
|
309
|
+
selected_rate={
|
|
310
|
+
"carrier_name": "fedex",
|
|
311
|
+
"carrier_id": "fedex",
|
|
312
|
+
"service": "fedex_ground",
|
|
313
|
+
"total_charge": 15.0,
|
|
314
|
+
"currency": "USD",
|
|
315
|
+
"extra_charges": [
|
|
316
|
+
{"id": self.markup.id, "name": "test_markup", "amount": 5.0, "currency": "USD"},
|
|
317
|
+
],
|
|
318
|
+
"meta": {
|
|
319
|
+
"carrier_code": "fedex",
|
|
320
|
+
"carrier_connection_id": "car_123",
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
created_by=user,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
# Verify fee was captured by the signal (don't call manually)
|
|
327
|
+
fees = models.Fee.objects.filter(shipment_id=shipment.id)
|
|
328
|
+
self.assertEqual(fees.count(), 1)
|
|
329
|
+
|
|
330
|
+
fee = fees.first()
|
|
331
|
+
self.assertEqual(fee.markup_id, self.markup.id)
|
|
332
|
+
self.assertEqual(fee.name, "test_markup")
|
|
333
|
+
self.assertEqual(fee.amount, 5.0)
|
|
334
|
+
self.assertEqual(fee.currency, "USD")
|
|
335
|
+
self.assertEqual(fee.carrier_code, "fedex")
|
|
336
|
+
self.assertEqual(fee.service_code, "fedex_ground")
|
|
337
|
+
self.assertEqual(fee.connection_id, "car_123")
|
|
338
|
+
self.assertEqual(fee.test_mode, True)
|
|
339
|
+
|
|
340
|
+
def test_capture_fees_function_directly(self):
|
|
341
|
+
"""Test the capture_fees_for_shipment function in isolation.
|
|
342
|
+
|
|
343
|
+
Create shipment with status='created' (so signal won't fire),
|
|
344
|
+
then manually call capture function.
|
|
345
|
+
"""
|
|
346
|
+
from django.contrib.auth import get_user_model
|
|
347
|
+
import karrio.server.manager.models as manager
|
|
348
|
+
|
|
349
|
+
User = get_user_model()
|
|
350
|
+
user = User.objects.create_user(
|
|
351
|
+
email="test_direct@example.com",
|
|
352
|
+
password="testpass123",
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# Create shipment with status that won't trigger signal
|
|
356
|
+
shipment = manager.Shipment.objects.create(
|
|
357
|
+
status="created", # Signal won't fire for this status
|
|
358
|
+
test_mode=True,
|
|
359
|
+
shipper={"city": "Montreal"},
|
|
360
|
+
recipient={"city": "Toronto"},
|
|
361
|
+
parcels=[{"weight": 1}],
|
|
362
|
+
selected_rate={
|
|
363
|
+
"carrier_name": "fedex",
|
|
364
|
+
"carrier_id": "fedex",
|
|
365
|
+
"service": "fedex_ground",
|
|
366
|
+
"total_charge": 15.0,
|
|
367
|
+
"currency": "USD",
|
|
368
|
+
"extra_charges": [
|
|
369
|
+
{"id": self.markup.id, "name": "test_markup", "amount": 5.0, "currency": "USD"},
|
|
370
|
+
],
|
|
371
|
+
"meta": {
|
|
372
|
+
"carrier_code": "fedex",
|
|
373
|
+
"carrier_connection_id": "car_123",
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
created_by=user,
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
# No fees should exist yet
|
|
380
|
+
self.assertEqual(models.Fee.objects.filter(shipment_id=shipment.id).count(), 0)
|
|
381
|
+
|
|
382
|
+
# Manually capture fees
|
|
383
|
+
signals.capture_fees_for_shipment(shipment)
|
|
384
|
+
|
|
385
|
+
# Verify fee was captured
|
|
386
|
+
fees = models.Fee.objects.filter(shipment_id=shipment.id)
|
|
387
|
+
self.assertEqual(fees.count(), 1)
|
|
388
|
+
|
|
389
|
+
fee = fees.first()
|
|
390
|
+
self.assertEqual(fee.markup_id, self.markup.id)
|
|
391
|
+
self.assertEqual(fee.amount, 5.0)
|
|
392
|
+
|
|
393
|
+
def test_no_duplicate_fee_capture(self):
|
|
394
|
+
"""Test that fees are not captured twice for the same shipment.
|
|
395
|
+
|
|
396
|
+
Signal should check if fees exist before capturing.
|
|
397
|
+
"""
|
|
398
|
+
from django.contrib.auth import get_user_model
|
|
399
|
+
import karrio.server.manager.models as manager
|
|
400
|
+
|
|
401
|
+
User = get_user_model()
|
|
402
|
+
user = User.objects.create_user(
|
|
403
|
+
email="test2@example.com",
|
|
404
|
+
password="testpass123",
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
# Create shipment - signal will capture fee
|
|
408
|
+
shipment = manager.Shipment.objects.create(
|
|
409
|
+
status="purchased",
|
|
410
|
+
test_mode=True,
|
|
411
|
+
shipper={"city": "Montreal"},
|
|
412
|
+
recipient={"city": "Toronto"},
|
|
413
|
+
parcels=[{"weight": 1}],
|
|
414
|
+
selected_rate={
|
|
415
|
+
"carrier_name": "fedex",
|
|
416
|
+
"carrier_id": "fedex",
|
|
417
|
+
"service": "fedex_ground",
|
|
418
|
+
"total_charge": 15.0,
|
|
419
|
+
"currency": "USD",
|
|
420
|
+
"extra_charges": [
|
|
421
|
+
{"id": self.markup.id, "name": "test_markup", "amount": 5.0, "currency": "USD"},
|
|
422
|
+
],
|
|
423
|
+
"meta": {"carrier_connection_id": "car_123"},
|
|
424
|
+
},
|
|
425
|
+
created_by=user,
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
# Fee should already exist from signal
|
|
429
|
+
fees = models.Fee.objects.filter(shipment_id=shipment.id)
|
|
430
|
+
self.assertEqual(fees.count(), 1)
|
|
431
|
+
|
|
432
|
+
# Save again - signal should not create duplicate
|
|
433
|
+
shipment.save()
|
|
434
|
+
|
|
435
|
+
# Still only one fee
|
|
436
|
+
fees = models.Fee.objects.filter(shipment_id=shipment.id)
|
|
437
|
+
self.assertEqual(fees.count(), 1)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
# Test data fixtures
|
|
441
|
+
|
|
54
442
|
RATING_DATA = {
|
|
55
443
|
"shipper": {
|
|
56
444
|
"postal_code": "V6M2V9",
|
{karrio_server_pricing-2026.1.1.dist-info → karrio_server_pricing-2026.1.3.dist-info}/RECORD
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
karrio/server/pricing/__init__.py,sha256=zXpxAFuHsCdAaESYGLRvdqCs7CXtIn8cF688jV4ufQc,64
|
|
2
|
-
karrio/server/pricing/admin.py,sha256=
|
|
3
|
-
karrio/server/pricing/apps.py,sha256=
|
|
4
|
-
karrio/server/pricing/models.py,sha256=
|
|
5
|
-
karrio/server/pricing/serializers.py,sha256=
|
|
6
|
-
karrio/server/pricing/signals.py,sha256
|
|
7
|
-
karrio/server/pricing/tests.py,sha256=
|
|
2
|
+
karrio/server/pricing/admin.py,sha256=vDYvoFk9M6bGK6NBoJCRkxL5dla4sibNfej69_RIOT8,5642
|
|
3
|
+
karrio/server/pricing/apps.py,sha256=LBpxtFvuUn36DjMiPlQL51V5WfVMDf7N4QS3IUs_Pcs,431
|
|
4
|
+
karrio/server/pricing/models.py,sha256=gRcCHNEQpQSP4T44RvyPInNYzXL3SHXq9Ar0f9il3YY,11697
|
|
5
|
+
karrio/server/pricing/serializers.py,sha256=48panQv9ZyLzkVa94XzOqbXxFm0daMK1_jOVJwQiNbI,574
|
|
6
|
+
karrio/server/pricing/signals.py,sha256=-XNTjbnn1AnRZDP45YXIaSTXdYG6tXrnBXnCX9CFDOo,6560
|
|
7
|
+
karrio/server/pricing/tests.py,sha256=iaTqsY2pSPR1YRy9TqjhkfvRN8776l0Zoh4xeT0awQc,24818
|
|
8
8
|
karrio/server/pricing/views.py,sha256=xc1IQHrsij7j33TUbo-_oewy3vs03pw_etpBWaMYJl0,63
|
|
9
9
|
karrio/server/pricing/migrations/0001_initial.py,sha256=KKEklxf8Q1-IQn-8ZchbCi3-zmIyjn80DaGqPgRRI5w,52327
|
|
10
10
|
karrio/server/pricing/migrations/0002_auto_20201127_0721.py,sha256=zhiRIHjyUhwH8Mw2qljkWO1wkZPftqAJpwh6QH5oO2o,41778
|
|
@@ -81,8 +81,12 @@ karrio/server/pricing/migrations/0072_alter_surcharge_carriers_alter_surcharge_s
|
|
|
81
81
|
karrio/server/pricing/migrations/0073_alter_surcharge_carriers_alter_surcharge_services.py,sha256=X0QX4UHAFI_Gu0zqPeL-AvZrz4HD2W7mW9LsvvBDpkE,239938
|
|
82
82
|
karrio/server/pricing/migrations/0074_alter_surcharge_carriers_alter_surcharge_services.py,sha256=s-ic_8rAIdhUS7cmTwVdkeMQiemBMfpcfSwNnaTD410,11301
|
|
83
83
|
karrio/server/pricing/migrations/0075_alter_surcharge_carriers_alter_surcharge_services.py,sha256=hfEWE4zBbvz4Iv58NIA5HdNxqgjnwQb0ACSgMMA_aMs,240966
|
|
84
|
+
karrio/server/pricing/migrations/0076_create_markup_and_fee_models.py,sha256=ZsfQoLv4shhia9p3tIZ_eotpIipVhuqhjFnzQ2Hc3GQ,9152
|
|
85
|
+
karrio/server/pricing/migrations/0077_migrate_surcharge_to_markup_data.py,sha256=K0R8ffn9h-xajThtfEgQR2nEj6sui0PAhT_ouxV6bqw,2192
|
|
86
|
+
karrio/server/pricing/migrations/0078_cleanup.py,sha256=aEO5ceQ6-35jz3mGblQ2RD_144Uu-gVAjaEckqHM1OM,4263
|
|
87
|
+
karrio/server/pricing/migrations/0079_fee_snapshot_model.py,sha256=n18S32UPAp_WMzVL4_Hf96drwGPE72pc45Ul2qPs-nk,9843
|
|
84
88
|
karrio/server/pricing/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
|
-
karrio_server_pricing-2026.1.
|
|
86
|
-
karrio_server_pricing-2026.1.
|
|
87
|
-
karrio_server_pricing-2026.1.
|
|
88
|
-
karrio_server_pricing-2026.1.
|
|
89
|
+
karrio_server_pricing-2026.1.3.dist-info/METADATA,sha256=MJAX7agk7MRZSlPuQ7g0zOUHWr70ymy9D5w5oXDQ5-I,684
|
|
90
|
+
karrio_server_pricing-2026.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
91
|
+
karrio_server_pricing-2026.1.3.dist-info/top_level.txt,sha256=D1D7x8R3cTfjF_15mfiO7wCQ5QMtuM4x8GaPr7z5i78,12
|
|
92
|
+
karrio_server_pricing-2026.1.3.dist-info/RECORD,,
|
{karrio_server_pricing-2026.1.1.dist-info → karrio_server_pricing-2026.1.3.dist-info}/top_level.txt
RENAMED
|
File without changes
|