karrio-server-pricing 2025.5__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/__init__.py +1 -0
- karrio/server/pricing/admin.py +55 -0
- karrio/server/pricing/apps.py +12 -0
- karrio/server/pricing/migrations/0001_initial.py +974 -0
- karrio/server/pricing/migrations/0002_auto_20201127_0721.py +855 -0
- karrio/server/pricing/migrations/0003_auto_20201230_0820.py +939 -0
- karrio/server/pricing/migrations/0004_auto_20201231_1402.py +940 -0
- karrio/server/pricing/migrations/0005_auto_20210204_1725.py +923 -0
- karrio/server/pricing/migrations/0006_auto_20210217_1109.py +1224 -0
- karrio/server/pricing/migrations/0007_auto_20210218_1202.py +955 -0
- karrio/server/pricing/migrations/0008_auto_20210418_0504.py +1010 -0
- karrio/server/pricing/migrations/0009_auto_20210603_2149.py +1043 -0
- karrio/server/pricing/migrations/0010_auto_20210612_1608.py +1070 -0
- karrio/server/pricing/migrations/0011_auto_20210615_1601.py +1109 -0
- karrio/server/pricing/migrations/0012_surcharge_carrier_accounts.py +23 -0
- karrio/server/pricing/migrations/0013_alter_surcharge_services.py +1086 -0
- karrio/server/pricing/migrations/0014_auto_20211013_1520.py +12 -0
- karrio/server/pricing/migrations/0015_auto_20211204_1350.py +1124 -0
- karrio/server/pricing/migrations/0016_auto_20211220_1500.py +1126 -0
- karrio/server/pricing/migrations/0017_alter_surcharge_services.py +1093 -0
- karrio/server/pricing/migrations/0018_alter_surcharge_services.py +1100 -0
- karrio/server/pricing/migrations/0019_alter_surcharge_services.py +1093 -0
- karrio/server/pricing/migrations/0020_auto_20220412_1215.py +3175 -0
- karrio/server/pricing/migrations/0021_auto_20220413_0959.py +3179 -0
- karrio/server/pricing/migrations/0022_alter_surcharge_services.py +3144 -0
- karrio/server/pricing/migrations/0023_auto_20220504_1335.py +3175 -0
- karrio/server/pricing/migrations/0024_auto_20220808_0803.py +3180 -0
- karrio/server/pricing/migrations/0025_alter_surcharge_carriers.py +51 -0
- karrio/server/pricing/migrations/0026_auto_20220828_0158.py +3199 -0
- karrio/server/pricing/migrations/0027_alter_surcharge_services.py +3170 -0
- karrio/server/pricing/migrations/0028_surcharge_markup_carriers_surcharge_markup_services.py +3016 -0
- karrio/server/pricing/migrations/0029_alter_surcharge_services.py +2939 -0
- karrio/server/pricing/migrations/0030_alter_surcharge_services.py +2940 -0
- karrio/server/pricing/migrations/0031_alter_surcharge_carriers.py +52 -0
- karrio/server/pricing/migrations/0032_alter_surcharge_services.py +2963 -0
- karrio/server/pricing/migrations/0033_alter_surcharge_services.py +2964 -0
- karrio/server/pricing/migrations/0034_alter_surcharge_carriers_alter_surcharge_services.py +3009 -0
- karrio/server/pricing/migrations/0035_alter_surcharge_carriers.py +56 -0
- karrio/server/pricing/migrations/0036_alter_surcharge_carriers_alter_surcharge_services.py +3022 -0
- karrio/server/pricing/migrations/0037_alter_surcharge_carriers_alter_surcharge_services.py +3078 -0
- karrio/server/pricing/migrations/0038_alter_surcharge_carriers_alter_surcharge_services.py +3093 -0
- karrio/server/pricing/migrations/0039_alter_surcharge_carriers_alter_surcharge_services.py +3095 -0
- karrio/server/pricing/migrations/0040_alter_surcharge_services.py +3058 -0
- karrio/server/pricing/migrations/0041_alter_surcharge_services.py +3061 -0
- karrio/server/pricing/migrations/0042_alter_surcharge_carriers_alter_surcharge_services.py +3128 -0
- karrio/server/pricing/migrations/0043_alter_surcharge_services.py +3090 -0
- karrio/server/pricing/migrations/0044_alter_surcharge_carriers.py +62 -0
- karrio/server/pricing/migrations/0045_alter_surcharge_carriers.py +63 -0
- karrio/server/pricing/migrations/0046_alter_surcharge_services.py +3100 -0
- karrio/server/pricing/migrations/0047_alter_surcharge_services.py +3171 -0
- karrio/server/pricing/migrations/0048_alter_surcharge_services.py +3195 -0
- karrio/server/pricing/migrations/0049_alter_surcharge_carriers_alter_surcharge_services.py +3246 -0
- karrio/server/pricing/migrations/0050_alter_surcharge_carriers.py +64 -0
- karrio/server/pricing/migrations/0051_alter_surcharge_carriers_alter_surcharge_services.py +2956 -0
- karrio/server/pricing/migrations/0052_alter_surcharge_carriers_alter_surcharge_services.py +3547 -0
- karrio/server/pricing/migrations/0053_alter_surcharge_carriers_alter_surcharge_services.py +3561 -0
- karrio/server/pricing/migrations/0054_alter_surcharge_services.py +3409 -0
- karrio/server/pricing/migrations/0055_alter_surcharge_services.py +3455 -0
- karrio/server/pricing/migrations/0056_alter_surcharge_carriers_alter_surcharge_services.py +3609 -0
- karrio/server/pricing/migrations/0057_alter_surcharge_carriers_alter_surcharge_services.py +4384 -0
- karrio/server/pricing/migrations/0058_alter_surcharge_services.py +4321 -0
- karrio/server/pricing/migrations/0059_alter_surcharge_carriers_alter_surcharge_services.py +4892 -0
- karrio/server/pricing/migrations/0060_alter_surcharge_services.py +4894 -0
- karrio/server/pricing/migrations/0061_alter_surcharge_services.py +4888 -0
- karrio/server/pricing/migrations/0062_alter_surcharge_carriers_alter_surcharge_services.py +4704 -0
- karrio/server/pricing/migrations/0063_alter_surcharge_carriers_alter_surcharge_services.py +34 -0
- karrio/server/pricing/migrations/0064_alter_surcharge_carriers_alter_surcharge_services.py +4669 -0
- karrio/server/pricing/migrations/0065_fix_surcharge_type_enum.py +36 -0
- karrio/server/pricing/migrations/0066_alter_surcharge_carriers_alter_surcharge_services_and_more.py +4712 -0
- karrio/server/pricing/migrations/0067_alter_surcharge_carriers_alter_surcharge_services.py +24 -0
- karrio/server/pricing/migrations/0068_alter_surcharge_carriers_alter_surcharge_services.py +24 -0
- karrio/server/pricing/migrations/0069_alter_surcharge_carriers_alter_surcharge_services.py +4707 -0
- karrio/server/pricing/migrations/0070_alter_surcharge_carriers_alter_surcharge_services.py +34 -0
- karrio/server/pricing/migrations/0071_alter_surcharge_carriers_alter_surcharge_services.py +4707 -0
- karrio/server/pricing/migrations/0072_alter_surcharge_carriers_alter_surcharge_services.py +24 -0
- karrio/server/pricing/migrations/__init__.py +0 -0
- karrio/server/pricing/models.py +153 -0
- karrio/server/pricing/serializers.py +18 -0
- karrio/server/pricing/signals.py +33 -0
- karrio/server/pricing/tests.py +301 -0
- karrio/server/pricing/views.py +3 -0
- karrio_server_pricing-2025.5.dist-info/METADATA +27 -0
- karrio_server_pricing-2025.5.dist-info/RECORD +85 -0
- karrio_server_pricing-2025.5.dist-info/WHEEL +5 -0
- karrio_server_pricing-2025.5.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Generated by Django 5.2.7 on 2025-11-19 19:09
|
|
2
|
+
|
|
3
|
+
import karrio.server.core.fields
|
|
4
|
+
from django.db import migrations
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('pricing', '0071_alter_surcharge_carriers_alter_surcharge_services'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name='surcharge',
|
|
16
|
+
name='carriers',
|
|
17
|
+
field=karrio.server.core.fields.MultiChoiceField(blank=True, choices=[('australiapost', 'australiapost'), ('canadapost', 'canadapost'), ('dhl_express', 'dhl_express'), ('dhl_parcel_de', 'dhl_parcel_de'), ('dhl_poland', 'dhl_poland'), ('dhl_universal', 'dhl_universal'), ('dpd', 'dpd'), ('fedex', 'fedex'), ('generic', 'generic'), ('landmark', 'landmark'), ('laposte', 'laposte'), ('purolator', 'purolator'), ('seko', 'seko'), ('sendle', 'sendle'), ('ups', 'ups'), ('usps', 'usps'), ('usps_international', 'usps_international')], help_text='\n The list of carriers you want to apply the surcharge to.\n <br/>\n Note that by default, the surcharge is applied to all carriers\n ', null=True),
|
|
18
|
+
),
|
|
19
|
+
migrations.AlterField(
|
|
20
|
+
model_name='surcharge',
|
|
21
|
+
name='services',
|
|
22
|
+
field=karrio.server.core.fields.MultiChoiceField(blank=True, choices=[('australiapost_parcel_post', 'australiapost_parcel_post'), ('australiapost_express_post', 'australiapost_express_post'), ('australiapost_parcel_post_signature', 'australiapost_parcel_post_signature'), ('australiapost_express_post_signature', 'australiapost_express_post_signature'), ('australiapost_intl_standard_pack_track', 'australiapost_intl_standard_pack_track'), ('australiapost_intl_standard_with_signature', 'australiapost_intl_standard_with_signature'), ('australiapost_intl_express_merch', 'australiapost_intl_express_merch'), ('australiapost_intl_express_docs', 'australiapost_intl_express_docs'), ('australiapost_eparcel_post_returns', 'australiapost_eparcel_post_returns'), ('australiapost_express_eparcel_post_returns', 'australiapost_express_eparcel_post_returns'), ('canadapost_regular_parcel', 'canadapost_regular_parcel'), ('canadapost_expedited_parcel', 'canadapost_expedited_parcel'), ('canadapost_xpresspost', 'canadapost_xpresspost'), ('canadapost_xpresspost_certified', 'canadapost_xpresspost_certified'), ('canadapost_priority', 'canadapost_priority'), ('canadapost_library_books', 'canadapost_library_books'), ('canadapost_expedited_parcel_usa', 'canadapost_expedited_parcel_usa'), ('canadapost_priority_worldwide_envelope_usa', 'canadapost_priority_worldwide_envelope_usa'), ('canadapost_priority_worldwide_pak_usa', 'canadapost_priority_worldwide_pak_usa'), ('canadapost_priority_worldwide_parcel_usa', 'canadapost_priority_worldwide_parcel_usa'), ('canadapost_small_packet_usa_air', 'canadapost_small_packet_usa_air'), ('canadapost_tracked_packet_usa', 'canadapost_tracked_packet_usa'), ('canadapost_tracked_packet_usa_lvm', 'canadapost_tracked_packet_usa_lvm'), ('canadapost_xpresspost_usa', 'canadapost_xpresspost_usa'), ('canadapost_xpresspost_international', 'canadapost_xpresspost_international'), ('canadapost_international_parcel_air', 'canadapost_international_parcel_air'), ('canadapost_international_parcel_surface', 'canadapost_international_parcel_surface'), ('canadapost_priority_worldwide_envelope_intl', 'canadapost_priority_worldwide_envelope_intl'), ('canadapost_priority_worldwide_pak_intl', 'canadapost_priority_worldwide_pak_intl'), ('canadapost_priority_worldwide_parcel_intl', 'canadapost_priority_worldwide_parcel_intl'), ('canadapost_small_packet_international_air', 'canadapost_small_packet_international_air'), ('canadapost_small_packet_international_surface', 'canadapost_small_packet_international_surface'), ('canadapost_tracked_packet_international', 'canadapost_tracked_packet_international'), ('dhl_logistics_services', 'dhl_logistics_services'), ('dhl_domestic_express_12_00', 'dhl_domestic_express_12_00'), ('dhl_express_choice', 'dhl_express_choice'), ('dhl_express_choice_nondoc', 'dhl_express_choice_nondoc'), ('dhl_jetline', 'dhl_jetline'), ('dhl_sprintline', 'dhl_sprintline'), ('dhl_air_capacity_sales', 'dhl_air_capacity_sales'), ('dhl_express_easy', 'dhl_express_easy'), ('dhl_express_easy_nondoc', 'dhl_express_easy_nondoc'), ('dhl_parcel_product', 'dhl_parcel_product'), ('dhl_accounting', 'dhl_accounting'), ('dhl_breakbulk_express', 'dhl_breakbulk_express'), ('dhl_medical_express', 'dhl_medical_express'), ('dhl_express_worldwide_doc', 'dhl_express_worldwide_doc'), ('dhl_express_9_00_nondoc', 'dhl_express_9_00_nondoc'), ('dhl_freight_worldwide_nondoc', 'dhl_freight_worldwide_nondoc'), ('dhl_economy_select_domestic', 'dhl_economy_select_domestic'), ('dhl_economy_select_nondoc', 'dhl_economy_select_nondoc'), ('dhl_express_domestic_9_00', 'dhl_express_domestic_9_00'), ('dhl_jumbo_box_nondoc', 'dhl_jumbo_box_nondoc'), ('dhl_express_9_00', 'dhl_express_9_00'), ('dhl_express_10_30', 'dhl_express_10_30'), ('dhl_express_10_30_nondoc', 'dhl_express_10_30_nondoc'), ('dhl_express_domestic', 'dhl_express_domestic'), ('dhl_express_domestic_10_30', 'dhl_express_domestic_10_30'), ('dhl_express_worldwide_nondoc', 'dhl_express_worldwide_nondoc'), ('dhl_medical_express_nondoc', 'dhl_medical_express_nondoc'), ('dhl_globalmail', 'dhl_globalmail'), ('dhl_same_day', 'dhl_same_day'), ('dhl_express_12_00', 'dhl_express_12_00'), ('dhl_express_worldwide', 'dhl_express_worldwide'), ('dhl_parcel_product_nondoc', 'dhl_parcel_product_nondoc'), ('dhl_economy_select', 'dhl_economy_select'), ('dhl_express_envelope', 'dhl_express_envelope'), ('dhl_express_12_00_nondoc', 'dhl_express_12_00_nondoc'), ('dhl_destination_charges', 'dhl_destination_charges'), ('dhl_express_all', 'dhl_express_all'), ('dhl_parcel_de_paket', 'dhl_parcel_de_paket'), ('dhl_parcel_de_warenpost', 'dhl_parcel_de_warenpost'), ('dhl_parcel_de_europaket', 'dhl_parcel_de_europaket'), ('dhl_parcel_de_paket_international', 'dhl_parcel_de_paket_international'), ('dhl_parcel_de_warenpost_international', 'dhl_parcel_de_warenpost_international'), ('dhl_poland_premium', 'dhl_poland_premium'), ('dhl_poland_polska', 'dhl_poland_polska'), ('dhl_poland_09', 'dhl_poland_09'), ('dhl_poland_12', 'dhl_poland_12'), ('dhl_poland_connect', 'dhl_poland_connect'), ('dhl_poland_international', 'dhl_poland_international'), ('dpd_cl', 'dpd_cl'), ('dpd_express_10h', 'dpd_express_10h'), ('dpd_express_12h', 'dpd_express_12h'), ('dpd_express_18h_guarantee', 'dpd_express_18h_guarantee'), ('dpd_express_b2b_predict', 'dpd_express_b2b_predict'), ('fedex_international_priority_express', 'fedex_international_priority_express'), ('fedex_international_first', 'fedex_international_first'), ('fedex_international_priority', 'fedex_international_priority'), ('fedex_international_economy', 'fedex_international_economy'), ('fedex_ground', 'fedex_ground'), ('fedex_cargo_mail', 'fedex_cargo_mail'), ('fedex_cargo_international_premium', 'fedex_cargo_international_premium'), ('fedex_first_overnight', 'fedex_first_overnight'), ('fedex_first_overnight_freight', 'fedex_first_overnight_freight'), ('fedex_1_day_freight', 'fedex_1_day_freight'), ('fedex_2_day_freight', 'fedex_2_day_freight'), ('fedex_3_day_freight', 'fedex_3_day_freight'), ('fedex_international_priority_freight', 'fedex_international_priority_freight'), ('fedex_international_economy_freight', 'fedex_international_economy_freight'), ('fedex_cargo_airport_to_airport', 'fedex_cargo_airport_to_airport'), ('fedex_international_priority_distribution', 'fedex_international_priority_distribution'), ('fedex_ip_direct_distribution_freight', 'fedex_ip_direct_distribution_freight'), ('fedex_intl_ground_distribution', 'fedex_intl_ground_distribution'), ('fedex_ground_home_delivery', 'fedex_ground_home_delivery'), ('fedex_smart_post', 'fedex_smart_post'), ('fedex_priority_overnight', 'fedex_priority_overnight'), ('fedex_standard_overnight', 'fedex_standard_overnight'), ('fedex_2_day', 'fedex_2_day'), ('fedex_2_day_am', 'fedex_2_day_am'), ('fedex_express_saver', 'fedex_express_saver'), ('fedex_same_day', 'fedex_same_day'), ('fedex_same_day_city', 'fedex_same_day_city'), ('fedex_one_day_freight', 'fedex_one_day_freight'), ('fedex_international_economy_distribution', 'fedex_international_economy_distribution'), ('fedex_international_connect_plus', 'fedex_international_connect_plus'), ('fedex_international_distribution_freight', 'fedex_international_distribution_freight'), ('fedex_regional_economy', 'fedex_regional_economy'), ('fedex_next_day_freight', 'fedex_next_day_freight'), ('fedex_next_day', 'fedex_next_day'), ('fedex_next_day_10am', 'fedex_next_day_10am'), ('fedex_next_day_12pm', 'fedex_next_day_12pm'), ('fedex_next_day_end_of_day', 'fedex_next_day_end_of_day'), ('fedex_distance_deferred', 'fedex_distance_deferred'), ('standard_service', 'standard_service'), ('landmark_maxipak_scan_ddp', 'landmark_maxipak_scan_ddp'), ('landmark_maxipak_scan_ddu', 'landmark_maxipak_scan_ddu'), ('landmark_minipak_scan_ddp', 'landmark_minipak_scan_ddp'), ('landmark_minipak_scan_ddu', 'landmark_minipak_scan_ddu'), ('landmark_maxipak_scan_ddp_pudo', 'landmark_maxipak_scan_ddp_pudo'), ('landmark_maxipak_scan_premium_ups_express_ddp', 'landmark_maxipak_scan_premium_ups_express_ddp'), ('landmark_maxipak_scan_premium_ups_express_ddu', 'landmark_maxipak_scan_premium_ups_express_ddu'), ('landmark_maxipak_scan_premium_ups_standard_ddp', 'landmark_maxipak_scan_premium_ups_standard_ddp'), ('landmark_maxipak_scan_premium_ups_standard_ddu', 'landmark_maxipak_scan_premium_ups_standard_ddu'), ('purolator_express_9_am', 'purolator_express_9_am'), ('purolator_express_us', 'purolator_express_us'), ('purolator_express_10_30_am', 'purolator_express_10_30_am'), ('purolator_express_us_9_am', 'purolator_express_us_9_am'), ('purolator_express_12_pm', 'purolator_express_12_pm'), ('purolator_express_us_10_30_am', 'purolator_express_us_10_30_am'), ('purolator_express', 'purolator_express'), ('purolator_express_us_12_00', 'purolator_express_us_12_00'), ('purolator_express_evening', 'purolator_express_evening'), ('purolator_express_envelope_us', 'purolator_express_envelope_us'), ('purolator_express_envelope_9_am', 'purolator_express_envelope_9_am'), ('purolator_express_us_envelope_9_am', 'purolator_express_us_envelope_9_am'), ('purolator_express_envelope_10_30_am', 'purolator_express_envelope_10_30_am'), ('purolator_express_us_envelope_10_30_am', 'purolator_express_us_envelope_10_30_am'), ('purolator_express_envelope_12_pm', 'purolator_express_envelope_12_pm'), ('purolator_express_us_envelope_12_00', 'purolator_express_us_envelope_12_00'), ('purolator_express_envelope', 'purolator_express_envelope'), ('purolator_express_pack_us', 'purolator_express_pack_us'), ('purolator_express_envelope_evening', 'purolator_express_envelope_evening'), ('purolator_express_us_pack_9_am', 'purolator_express_us_pack_9_am'), ('purolator_express_pack_9_am', 'purolator_express_pack_9_am'), ('purolator_express_us_pack_10_30_am', 'purolator_express_us_pack_10_30_am'), ('purolator_express_pack10_30_am', 'purolator_express_pack10_30_am'), ('purolator_express_us_pack_12_00', 'purolator_express_us_pack_12_00'), ('purolator_express_pack_12_pm', 'purolator_express_pack_12_pm'), ('purolator_express_box_us', 'purolator_express_box_us'), ('purolator_express_pack', 'purolator_express_pack'), ('purolator_express_us_box_9_am', 'purolator_express_us_box_9_am'), ('purolator_express_pack_evening', 'purolator_express_pack_evening'), ('purolator_express_us_box_10_30_am', 'purolator_express_us_box_10_30_am'), ('purolator_express_box_9_am', 'purolator_express_box_9_am'), ('purolator_express_us_box_12_00', 'purolator_express_us_box_12_00'), ('purolator_express_box_10_30_am', 'purolator_express_box_10_30_am'), ('purolator_ground_us', 'purolator_ground_us'), ('purolator_express_box_12_pm', 'purolator_express_box_12_pm'), ('purolator_express_international', 'purolator_express_international'), ('purolator_express_box', 'purolator_express_box'), ('purolator_express_international_9_am', 'purolator_express_international_9_am'), ('purolator_express_box_evening', 'purolator_express_box_evening'), ('purolator_express_international_10_30_am', 'purolator_express_international_10_30_am'), ('purolator_ground', 'purolator_ground'), ('purolator_express_international_12_00', 'purolator_express_international_12_00'), ('purolator_ground_9_am', 'purolator_ground_9_am'), ('purolator_express_envelope_international', 'purolator_express_envelope_international'), ('purolator_ground_10_30_am', 'purolator_ground_10_30_am'), ('purolator_express_international_envelope_9_am', 'purolator_express_international_envelope_9_am'), ('purolator_ground_evening', 'purolator_ground_evening'), ('purolator_express_international_envelope_10_30_am', 'purolator_express_international_envelope_10_30_am'), ('purolator_quick_ship', 'purolator_quick_ship'), ('purolator_express_international_envelope_12_00', 'purolator_express_international_envelope_12_00'), ('purolator_quick_ship_envelope', 'purolator_quick_ship_envelope'), ('purolator_express_pack_international', 'purolator_express_pack_international'), ('purolator_quick_ship_pack', 'purolator_quick_ship_pack'), ('purolator_express_international_pack_9_am', 'purolator_express_international_pack_9_am'), ('purolator_quick_ship_box', 'purolator_quick_ship_box'), ('purolator_express_international_pack_10_30_am', 'purolator_express_international_pack_10_30_am'), ('purolator_express_international_pack_12_00', 'purolator_express_international_pack_12_00'), ('purolator_express_box_international', 'purolator_express_box_international'), ('purolator_express_international_box_9_am', 'purolator_express_international_box_9_am'), ('purolator_express_international_box_10_30_am', 'purolator_express_international_box_10_30_am'), ('purolator_express_international_box_12_00', 'purolator_express_international_box_12_00'), ('seko_ecommerce_standard_tracked', 'seko_ecommerce_standard_tracked'), ('seko_ecommerce_express_tracked', 'seko_ecommerce_express_tracked'), ('seko_domestic_express', 'seko_domestic_express'), ('seko_domestic_standard', 'seko_domestic_standard'), ('seko_domestic_large_parcel', 'seko_domestic_large_parcel'), ('sendle_standard_pickup', 'sendle_standard_pickup'), ('sendle_standard_dropoff', 'sendle_standard_dropoff'), ('sendle_express_pickup', 'sendle_express_pickup'), ('ups_standard', 'ups_standard'), ('ups_worldwide_express', 'ups_worldwide_express'), ('ups_worldwide_expedited', 'ups_worldwide_expedited'), ('ups_worldwide_express_plus', 'ups_worldwide_express_plus'), ('ups_worldwide_saver', 'ups_worldwide_saver'), ('ups_2nd_day_air', 'ups_2nd_day_air'), ('ups_2nd_day_air_am', 'ups_2nd_day_air_am'), ('ups_3_day_select', 'ups_3_day_select'), ('ups_ground', 'ups_ground'), ('ups_next_day_air', 'ups_next_day_air'), ('ups_next_day_air_early', 'ups_next_day_air_early'), ('ups_next_day_air_saver', 'ups_next_day_air_saver'), ('ups_expedited_ca', 'ups_expedited_ca'), ('ups_express_saver_ca', 'ups_express_saver_ca'), ('ups_3_day_select_ca_us', 'ups_3_day_select_ca_us'), ('ups_access_point_economy_ca', 'ups_access_point_economy_ca'), ('ups_express_ca', 'ups_express_ca'), ('ups_express_early_ca', 'ups_express_early_ca'), ('ups_express_saver_intl_ca', 'ups_express_saver_intl_ca'), ('ups_standard_ca', 'ups_standard_ca'), ('ups_worldwide_expedited_ca', 'ups_worldwide_expedited_ca'), ('ups_worldwide_express_ca', 'ups_worldwide_express_ca'), ('ups_worldwide_express_plus_ca', 'ups_worldwide_express_plus_ca'), ('ups_express_early_ca_us', 'ups_express_early_ca_us'), ('ups_access_point_economy_eu', 'ups_access_point_economy_eu'), ('ups_expedited_eu', 'ups_expedited_eu'), ('ups_express_eu', 'ups_express_eu'), ('ups_standard_eu', 'ups_standard_eu'), ('ups_worldwide_express_plus_eu', 'ups_worldwide_express_plus_eu'), ('ups_worldwide_saver_eu', 'ups_worldwide_saver_eu'), ('ups_access_point_economy_mx', 'ups_access_point_economy_mx'), ('ups_expedited_mx', 'ups_expedited_mx'), ('ups_express_mx', 'ups_express_mx'), ('ups_standard_mx', 'ups_standard_mx'), ('ups_worldwide_express_plus_mx', 'ups_worldwide_express_plus_mx'), ('ups_worldwide_saver_mx', 'ups_worldwide_saver_mx'), ('ups_access_point_economy_pl', 'ups_access_point_economy_pl'), ('ups_today_dedicated_courrier_pl', 'ups_today_dedicated_courrier_pl'), ('ups_today_express_pl', 'ups_today_express_pl'), ('ups_today_express_saver_pl', 'ups_today_express_saver_pl'), ('ups_today_standard_pl', 'ups_today_standard_pl'), ('ups_expedited_pl', 'ups_expedited_pl'), ('ups_express_pl', 'ups_express_pl'), ('ups_express_plus_pl', 'ups_express_plus_pl'), ('ups_express_saver_pl', 'ups_express_saver_pl'), ('ups_standard_pl', 'ups_standard_pl'), ('ups_2nd_day_air_pr', 'ups_2nd_day_air_pr'), ('ups_ground_pr', 'ups_ground_pr'), ('ups_next_day_air_pr', 'ups_next_day_air_pr'), ('ups_next_day_air_early_pr', 'ups_next_day_air_early_pr'), ('ups_worldwide_expedited_pr', 'ups_worldwide_expedited_pr'), ('ups_worldwide_express_pr', 'ups_worldwide_express_pr'), ('ups_worldwide_express_plus_pr', 'ups_worldwide_express_plus_pr'), ('ups_worldwide_saver_pr', 'ups_worldwide_saver_pr'), ('ups_express_12_00_de', 'ups_express_12_00_de'), ('ups_worldwide_express_freight', 'ups_worldwide_express_freight'), ('ups_worldwide_express_freight_midday', 'ups_worldwide_express_freight_midday'), ('ups_worldwide_economy_ddu', 'ups_worldwide_economy_ddu'), ('ups_worldwide_economy_ddp', 'ups_worldwide_economy_ddp'), ('usps_parcel_select_lightweight', 'usps_parcel_select_lightweight'), ('usps_parcel_select', 'usps_parcel_select'), ('usps_priority_mail_express', 'usps_priority_mail_express'), ('usps_priority_mail', 'usps_priority_mail'), ('usps_library_mail', 'usps_library_mail'), ('usps_media_mail', 'usps_media_mail'), ('usps_bound_printed_matter', 'usps_bound_printed_matter'), ('usps_connect_local', 'usps_connect_local'), ('usps_connect_mail', 'usps_connect_mail'), ('usps_connect_next_day', 'usps_connect_next_day'), ('usps_connect_regional', 'usps_connect_regional'), ('usps_connect_same_day', 'usps_connect_same_day'), ('usps_ground_advantage', 'usps_ground_advantage'), ('usps_domestic_matter_for_the_blind', 'usps_domestic_matter_for_the_blind'), ('usps_all', 'usps_all'), ('usps_first_class_package_international_service', 'usps_first_class_package_international_service'), ('usps_priority_mail_international', 'usps_priority_mail_international'), ('usps_priority_mail_express_international', 'usps_priority_mail_express_international'), ('usps_global_express_guaranteed', 'usps_global_express_guaranteed'), ('usps_all', 'usps_all')], help_text='\n The list of services you want to apply the surcharge to.\n <br/>\n Note that by default, the surcharge is applied to all services\n ', null=True),
|
|
23
|
+
),
|
|
24
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
import functools
|
|
3
|
+
import django.db.models as models
|
|
4
|
+
import django.core.validators as validators
|
|
5
|
+
|
|
6
|
+
import karrio.lib as lib
|
|
7
|
+
import karrio.core.models as karrio
|
|
8
|
+
import karrio.server.core.models as core
|
|
9
|
+
import karrio.server.core.fields as fields
|
|
10
|
+
import karrio.server.core.datatypes as datatypes
|
|
11
|
+
import karrio.server.providers.models as providers
|
|
12
|
+
import karrio.server.pricing.serializers as serializers
|
|
13
|
+
from karrio.server.core.logging import logger
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@core.register_model
|
|
17
|
+
class Surcharge(core.ControlledAccessModel, core.Entity):
|
|
18
|
+
class Meta:
|
|
19
|
+
db_table = "surcharge"
|
|
20
|
+
verbose_name = "Markup"
|
|
21
|
+
verbose_name_plural = "Markups"
|
|
22
|
+
|
|
23
|
+
CONTEXT_RELATIONS = ["carrier_accounts"]
|
|
24
|
+
|
|
25
|
+
id = models.CharField(
|
|
26
|
+
max_length=50,
|
|
27
|
+
primary_key=True,
|
|
28
|
+
default=functools.partial(core.uuid, prefix="chrg_"),
|
|
29
|
+
editable=False,
|
|
30
|
+
)
|
|
31
|
+
active = models.BooleanField(default=True)
|
|
32
|
+
|
|
33
|
+
name = models.CharField(
|
|
34
|
+
max_length=100,
|
|
35
|
+
unique=True,
|
|
36
|
+
help_text="The surcharge name (label) that will appear in the rate (quote)",
|
|
37
|
+
)
|
|
38
|
+
amount = models.FloatField(
|
|
39
|
+
validators=[validators.MinValueValidator(0.1)],
|
|
40
|
+
default=0.0,
|
|
41
|
+
help_text="""
|
|
42
|
+
The surcharge amount or percentage to add to the quote
|
|
43
|
+
""",
|
|
44
|
+
)
|
|
45
|
+
surcharge_type = models.CharField(
|
|
46
|
+
max_length=25,
|
|
47
|
+
choices=serializers.SURCHAGE_TYPE,
|
|
48
|
+
default=serializers.SURCHAGE_TYPE[0][0],
|
|
49
|
+
help_text="""
|
|
50
|
+
Determine whether the surcharge is in percentage or net amount
|
|
51
|
+
<br/><br/>
|
|
52
|
+
For <strong>AMOUNT</strong>: rate ($22) and amount (1) will result in a new total_charge of ($23)
|
|
53
|
+
<br/>
|
|
54
|
+
For <strong>PERCENTAGE</strong>: rate ($22) and amount (5) will result in a new total_charge of ($23.10)
|
|
55
|
+
""",
|
|
56
|
+
)
|
|
57
|
+
carriers = fields.MultiChoiceField(
|
|
58
|
+
choices=serializers.CARRIERS,
|
|
59
|
+
null=True,
|
|
60
|
+
blank=True,
|
|
61
|
+
help_text="""
|
|
62
|
+
The list of carriers you want to apply the surcharge to.
|
|
63
|
+
<br/>
|
|
64
|
+
Note that by default, the surcharge is applied to all carriers
|
|
65
|
+
""",
|
|
66
|
+
)
|
|
67
|
+
carrier_accounts = models.ManyToManyField(
|
|
68
|
+
providers.Carrier,
|
|
69
|
+
blank=True,
|
|
70
|
+
help_text="""
|
|
71
|
+
The list of carrier accounts you want to apply the surcharge to.
|
|
72
|
+
<br/>
|
|
73
|
+
Note that by default, the surcharge is applied to all carrier accounts
|
|
74
|
+
""",
|
|
75
|
+
)
|
|
76
|
+
services = fields.MultiChoiceField(
|
|
77
|
+
choices=serializers.SERVICES,
|
|
78
|
+
null=True,
|
|
79
|
+
blank=True,
|
|
80
|
+
help_text="""
|
|
81
|
+
The list of services you want to apply the surcharge to.
|
|
82
|
+
<br/>
|
|
83
|
+
Note that by default, the surcharge is applied to all services
|
|
84
|
+
""",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def object_type(self):
|
|
89
|
+
return "surcharge"
|
|
90
|
+
|
|
91
|
+
def __str__(self):
|
|
92
|
+
type_ = "$" if self.surcharge_type == "AMOUNT" else "%"
|
|
93
|
+
return f"{self.id} ({self.amount} {type_})"
|
|
94
|
+
|
|
95
|
+
def apply_charge(self, response: datatypes.RateResponse) -> datatypes.RateResponse:
|
|
96
|
+
def apply(rate: datatypes.Rate) -> datatypes.Rate:
|
|
97
|
+
applicable = []
|
|
98
|
+
carrier_ids = [c.carrier_id for c in self.carrier_accounts.all()]
|
|
99
|
+
charges = getattr(rate, "extra_charges", None) or []
|
|
100
|
+
|
|
101
|
+
if any(self.carriers or []):
|
|
102
|
+
# For custom carriers (ext="generic"), check if "generic" is in the addon's carrier list
|
|
103
|
+
# since rate.carrier_name contains custom_carrier_name but users select "generic"
|
|
104
|
+
if (
|
|
105
|
+
rate.meta
|
|
106
|
+
and rate.meta.get("ext") == "generic"
|
|
107
|
+
and "generic" in self.carriers
|
|
108
|
+
):
|
|
109
|
+
applicable.append(True)
|
|
110
|
+
else:
|
|
111
|
+
applicable.append(rate.carrier_name in self.carriers)
|
|
112
|
+
|
|
113
|
+
if any(carrier_ids):
|
|
114
|
+
applicable.append(rate.carrier_id in carrier_ids)
|
|
115
|
+
|
|
116
|
+
if any(self.services or []):
|
|
117
|
+
applicable.append(rate.service in self.services)
|
|
118
|
+
|
|
119
|
+
if any(applicable) and all(applicable):
|
|
120
|
+
logger.debug("Applying broker surcharge to rate", rate_id=rate.id, surcharge_id=self.id)
|
|
121
|
+
|
|
122
|
+
amount = lib.to_decimal(
|
|
123
|
+
self.amount
|
|
124
|
+
if self.surcharge_type == "AMOUNT"
|
|
125
|
+
else (rate.total_charge * (typing.cast(float, self.amount) / 100))
|
|
126
|
+
)
|
|
127
|
+
total_charge = lib.to_decimal(rate.total_charge + amount)
|
|
128
|
+
extra_charges = rate.extra_charges + [
|
|
129
|
+
karrio.ChargeDetails(
|
|
130
|
+
name=typing.cast(str, self.name),
|
|
131
|
+
amount=amount,
|
|
132
|
+
currency=rate.currency,
|
|
133
|
+
id=self.id,
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
return datatypes.Rate(
|
|
138
|
+
**{
|
|
139
|
+
**lib.to_dict(rate),
|
|
140
|
+
"total_charge": total_charge,
|
|
141
|
+
"extra_charges": extra_charges,
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return rate
|
|
146
|
+
|
|
147
|
+
return datatypes.RateResponse(
|
|
148
|
+
messages=response.messages,
|
|
149
|
+
rates=sorted(
|
|
150
|
+
[apply(rate) for rate in response.rates],
|
|
151
|
+
key=lambda rate: rate.total_charge,
|
|
152
|
+
),
|
|
153
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
import karrio.server.core.dataunits as dataunits
|
|
3
|
+
from karrio.server.core.serializers import (
|
|
4
|
+
CARRIERS,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SurchargeType(enum.Enum):
|
|
9
|
+
AMOUNT = "AMOUNT"
|
|
10
|
+
PERCENTAGE = "PERCENTAGE"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
CARRIER_SERVICES = [
|
|
14
|
+
dataunits.REFERENCE_MODELS["services"][name]
|
|
15
|
+
for name in sorted(dataunits.REFERENCE_MODELS["services"].keys())
|
|
16
|
+
]
|
|
17
|
+
SERVICES = [(code, code) for services in CARRIER_SERVICES for code in services]
|
|
18
|
+
SURCHAGE_TYPE = [(c.name, c.name) for c in list(SurchargeType)]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import importlib
|
|
3
|
+
from django.db.models import Q
|
|
4
|
+
|
|
5
|
+
from karrio.server.serializers import Context
|
|
6
|
+
from karrio.server.core.gateway import Rates
|
|
7
|
+
from karrio.server.core.logging import logger
|
|
8
|
+
import karrio.server.pricing.models as models
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def register_rate_post_processing(*args, **kwargs):
|
|
12
|
+
Rates.post_process_functions += [apply_custom_surcharges]
|
|
13
|
+
logger.info("Signal registration complete", module="karrio.pricing")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def apply_custom_surcharges(context: Context, result):
|
|
17
|
+
_filters = tuple()
|
|
18
|
+
|
|
19
|
+
if importlib.util.find_spec("karrio.server.orgs") is not None:
|
|
20
|
+
_filters += (
|
|
21
|
+
Q(active=True, org__id=getattr(context.org, "id", None))
|
|
22
|
+
| Q(active=True, org=None),
|
|
23
|
+
)
|
|
24
|
+
else:
|
|
25
|
+
_filters += (Q(active=True),)
|
|
26
|
+
|
|
27
|
+
charges = models.Surcharge.objects.filter(*_filters)
|
|
28
|
+
|
|
29
|
+
return functools.reduce(
|
|
30
|
+
lambda cummulated_result, charge: charge.apply_charge(cummulated_result),
|
|
31
|
+
charges,
|
|
32
|
+
result,
|
|
33
|
+
)
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from unittest.mock import patch, ANY
|
|
4
|
+
from django.urls import reverse
|
|
5
|
+
from rest_framework import status
|
|
6
|
+
from karrio.core.models import RateDetails, ChargeDetails
|
|
7
|
+
from karrio.server.core.tests import APITestCase
|
|
8
|
+
import karrio.server.pricing.models as models
|
|
9
|
+
|
|
10
|
+
logging.disable(logging.CRITICAL)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestPricing(APITestCase):
|
|
14
|
+
def setUp(self) -> None:
|
|
15
|
+
super().setUp()
|
|
16
|
+
|
|
17
|
+
self.charge: models.Surcharge = models.Surcharge.objects.create(
|
|
18
|
+
**{
|
|
19
|
+
"amount": 1.0,
|
|
20
|
+
"name": "brokerage",
|
|
21
|
+
"carriers": ["canadapost"],
|
|
22
|
+
"services": ["canadapost_priority", "canadapost_regular_parcel"],
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
def test_apply_surcharge_amount_to_shipment_rates(self):
|
|
27
|
+
url = reverse("karrio.server.proxy:shipment-rates")
|
|
28
|
+
data = RATING_DATA
|
|
29
|
+
|
|
30
|
+
with patch("karrio.server.core.gateway.utils.identity") as mock:
|
|
31
|
+
mock.return_value = RETURNED_VALUE
|
|
32
|
+
response = self.client.post(f"{url}", data)
|
|
33
|
+
response_data = json.loads(response.content)
|
|
34
|
+
|
|
35
|
+
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
36
|
+
self.assertDictEqual(response_data, RATING_RESPONSE)
|
|
37
|
+
|
|
38
|
+
def test_apply_surcharge_percentage_to_shipment_rates(self):
|
|
39
|
+
self.charge.amount = 2.0
|
|
40
|
+
self.charge.surcharge_type = "PERCENTAGE"
|
|
41
|
+
self.charge.save()
|
|
42
|
+
url = reverse("karrio.server.proxy:shipment-rates")
|
|
43
|
+
data = RATING_DATA
|
|
44
|
+
|
|
45
|
+
with patch("karrio.server.core.gateway.utils.identity") as mock:
|
|
46
|
+
mock.return_value = RETURNED_VALUE
|
|
47
|
+
response = self.client.post(f"{url}", data)
|
|
48
|
+
response_data = json.loads(response.content)
|
|
49
|
+
|
|
50
|
+
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
51
|
+
self.assertDictEqual(response_data, RATING_WITH_PERCENTAGE_RESPONSE)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
RATING_DATA = {
|
|
55
|
+
"shipper": {
|
|
56
|
+
"postal_code": "V6M2V9",
|
|
57
|
+
"city": "Vancouver",
|
|
58
|
+
"country_code": "CA",
|
|
59
|
+
"state_code": "BC",
|
|
60
|
+
"residential": True,
|
|
61
|
+
"address_line1": "5840 Oak St",
|
|
62
|
+
},
|
|
63
|
+
"recipient": {
|
|
64
|
+
"postal_code": "E1C4Z8",
|
|
65
|
+
"city": "Moncton",
|
|
66
|
+
"country_code": "CA",
|
|
67
|
+
"state_code": "NB",
|
|
68
|
+
"residential": False,
|
|
69
|
+
"address_line1": "125 Church St",
|
|
70
|
+
},
|
|
71
|
+
"parcels": [
|
|
72
|
+
{
|
|
73
|
+
"weight": 1,
|
|
74
|
+
"weight_unit": "KG",
|
|
75
|
+
"packagePreset": "canadapost_corrugated_small_box",
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"services": [],
|
|
79
|
+
"carrier_ids": ["canadapost"],
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
RETURNED_VALUE = (
|
|
83
|
+
[
|
|
84
|
+
RateDetails(
|
|
85
|
+
carrier_id="canadapost",
|
|
86
|
+
carrier_name="canadapost",
|
|
87
|
+
currency="CAD",
|
|
88
|
+
transit_days=7,
|
|
89
|
+
service="canadapost_expedited_parcel",
|
|
90
|
+
total_charge=32.99,
|
|
91
|
+
extra_charges=[
|
|
92
|
+
ChargeDetails(amount=29.64, currency="CAD", name="Base charge"),
|
|
93
|
+
ChargeDetails(amount=1.24, currency="CAD", name="Fuel surcharge"),
|
|
94
|
+
ChargeDetails(amount=-2.19, currency="CAD", name="SMB Savings"),
|
|
95
|
+
ChargeDetails(amount=4.3, currency="CAD", name="Duty and taxes"),
|
|
96
|
+
ChargeDetails(amount=-0.95, currency="CAD", name="Discount"),
|
|
97
|
+
],
|
|
98
|
+
),
|
|
99
|
+
RateDetails(
|
|
100
|
+
carrier_id="canadapost",
|
|
101
|
+
carrier_name="canadapost",
|
|
102
|
+
currency="CAD",
|
|
103
|
+
transit_days=2,
|
|
104
|
+
service="canadapost_xpresspost",
|
|
105
|
+
total_charge=85.65,
|
|
106
|
+
extra_charges=[
|
|
107
|
+
ChargeDetails(amount=75.82, currency="CAD", name="Base charge"),
|
|
108
|
+
ChargeDetails(amount=3.21, currency="CAD", name="Fuel surcharge"),
|
|
109
|
+
ChargeDetails(amount=-4.55, currency="CAD", name="SMB Savings"),
|
|
110
|
+
ChargeDetails(amount=4.3, currency="CAD", name="Duty and taxes"),
|
|
111
|
+
ChargeDetails(amount=11.17, currency="CAD", name="Discount"),
|
|
112
|
+
],
|
|
113
|
+
),
|
|
114
|
+
RateDetails(
|
|
115
|
+
carrier_id="canadapost",
|
|
116
|
+
carrier_name="canadapost",
|
|
117
|
+
currency="CAD",
|
|
118
|
+
transit_days=2,
|
|
119
|
+
service="canadapost_priority",
|
|
120
|
+
total_charge=113.93,
|
|
121
|
+
extra_charges=[
|
|
122
|
+
ChargeDetails(amount=101.83, currency="CAD", name="Base charge"),
|
|
123
|
+
ChargeDetails(amount=4.27, currency="CAD", name="Fuel surcharge"),
|
|
124
|
+
ChargeDetails(amount=-7.03, currency="CAD", name="SMB Savings"),
|
|
125
|
+
ChargeDetails(amount=14.86, currency="CAD", name="Duties and taxes"),
|
|
126
|
+
ChargeDetails(amount=-2.76, currency="CAD", name="Discount"),
|
|
127
|
+
],
|
|
128
|
+
),
|
|
129
|
+
],
|
|
130
|
+
[],
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
RATING_RESPONSE = {
|
|
134
|
+
"messages": [],
|
|
135
|
+
"rates": [
|
|
136
|
+
{
|
|
137
|
+
"id": ANY,
|
|
138
|
+
"object_type": "rate",
|
|
139
|
+
"carrier_name": "canadapost",
|
|
140
|
+
"carrier_id": "canadapost",
|
|
141
|
+
"currency": "CAD",
|
|
142
|
+
"estimated_delivery": ANY,
|
|
143
|
+
"service": "canadapost_expedited_parcel",
|
|
144
|
+
"total_charge": 32.99,
|
|
145
|
+
"transit_days": 7,
|
|
146
|
+
"extra_charges": [
|
|
147
|
+
{"name": "Base charge", "amount": 29.64, "currency": "CAD", "id": None},
|
|
148
|
+
{"name": "Fuel surcharge", "amount": 1.24, "currency": "CAD", "id": None},
|
|
149
|
+
{"name": "SMB Savings", "amount": -2.19, "currency": "CAD", "id": None},
|
|
150
|
+
{"name": "Duty and taxes", "amount": 4.3, "currency": "CAD", "id": None},
|
|
151
|
+
{"name": "Discount", "amount": -0.95, "currency": "CAD", "id": None},
|
|
152
|
+
],
|
|
153
|
+
"meta": {
|
|
154
|
+
"ext": "canadapost",
|
|
155
|
+
"carrier": "canadapost",
|
|
156
|
+
"rate_provider": "canadapost",
|
|
157
|
+
"service_name": "CANADAPOST EXPEDITED PARCEL",
|
|
158
|
+
"carrier_connection_id": ANY,
|
|
159
|
+
},
|
|
160
|
+
"test_mode": True,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": ANY,
|
|
164
|
+
"object_type": "rate",
|
|
165
|
+
"carrier_name": "canadapost",
|
|
166
|
+
"carrier_id": "canadapost",
|
|
167
|
+
"currency": "CAD",
|
|
168
|
+
"estimated_delivery": ANY,
|
|
169
|
+
"service": "canadapost_xpresspost",
|
|
170
|
+
"total_charge": 85.65,
|
|
171
|
+
"transit_days": 2,
|
|
172
|
+
"extra_charges": [
|
|
173
|
+
{"name": "Base charge", "amount": 75.82, "currency": "CAD", "id": None},
|
|
174
|
+
{"name": "Fuel surcharge", "amount": 3.21, "currency": "CAD", "id": None},
|
|
175
|
+
{"name": "SMB Savings", "amount": -4.55, "currency": "CAD", "id": None},
|
|
176
|
+
{"name": "Duty and taxes", "amount": 4.3, "currency": "CAD", "id": None},
|
|
177
|
+
{"name": "Discount", "amount": 11.17, "currency": "CAD", "id": None},
|
|
178
|
+
],
|
|
179
|
+
"meta": {
|
|
180
|
+
"ext": "canadapost",
|
|
181
|
+
"carrier": "canadapost",
|
|
182
|
+
"rate_provider": "canadapost",
|
|
183
|
+
"service_name": "CANADAPOST XPRESSPOST",
|
|
184
|
+
"carrier_connection_id": ANY,
|
|
185
|
+
},
|
|
186
|
+
"test_mode": True,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"id": ANY,
|
|
190
|
+
"object_type": "rate",
|
|
191
|
+
"carrier_name": "canadapost",
|
|
192
|
+
"carrier_id": "canadapost",
|
|
193
|
+
"currency": "CAD",
|
|
194
|
+
"estimated_delivery": ANY,
|
|
195
|
+
"service": "canadapost_priority",
|
|
196
|
+
"total_charge": 114.93,
|
|
197
|
+
"transit_days": 2,
|
|
198
|
+
"extra_charges": [
|
|
199
|
+
{"name": "Base charge", "amount": 101.83, "currency": "CAD", "id": None},
|
|
200
|
+
{"name": "Fuel surcharge", "amount": 4.27, "currency": "CAD", "id": None},
|
|
201
|
+
{"name": "SMB Savings", "amount": -7.03, "currency": "CAD", "id": None},
|
|
202
|
+
{"name": "Duties and taxes", "amount": 14.86, "currency": "CAD", "id": None},
|
|
203
|
+
{"name": "Discount", "amount": -2.76, "currency": "CAD", "id": None},
|
|
204
|
+
{"name": "brokerage", "amount": 1.0, "currency": "CAD", "id": ANY},
|
|
205
|
+
],
|
|
206
|
+
"meta": {
|
|
207
|
+
"ext": "canadapost",
|
|
208
|
+
"carrier": "canadapost",
|
|
209
|
+
"carrier_connection_id": ANY,
|
|
210
|
+
"rate_provider": "canadapost",
|
|
211
|
+
"service_name": "CANADAPOST PRIORITY",
|
|
212
|
+
},
|
|
213
|
+
"test_mode": True,
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
RATING_WITH_PERCENTAGE_RESPONSE = {
|
|
219
|
+
"messages": [],
|
|
220
|
+
"rates": [
|
|
221
|
+
{
|
|
222
|
+
"id": ANY,
|
|
223
|
+
"object_type": "rate",
|
|
224
|
+
"carrier_name": "canadapost",
|
|
225
|
+
"carrier_id": "canadapost",
|
|
226
|
+
"currency": "CAD",
|
|
227
|
+
"estimated_delivery": ANY,
|
|
228
|
+
"service": "canadapost_expedited_parcel",
|
|
229
|
+
"total_charge": 32.99,
|
|
230
|
+
"transit_days": 7,
|
|
231
|
+
"extra_charges": [
|
|
232
|
+
{"name": "Base charge", "amount": 29.64, "currency": "CAD", "id": None},
|
|
233
|
+
{"name": "Fuel surcharge", "amount": 1.24, "currency": "CAD", "id": None},
|
|
234
|
+
{"name": "SMB Savings", "amount": -2.19, "currency": "CAD", "id": None},
|
|
235
|
+
{"name": "Duty and taxes", "amount": 4.3, "currency": "CAD", "id": None},
|
|
236
|
+
{"name": "Discount", "amount": -0.95, "currency": "CAD", "id": None},
|
|
237
|
+
],
|
|
238
|
+
"meta": {
|
|
239
|
+
"ext": "canadapost",
|
|
240
|
+
"carrier": "canadapost",
|
|
241
|
+
"rate_provider": "canadapost",
|
|
242
|
+
"service_name": "CANADAPOST EXPEDITED PARCEL",
|
|
243
|
+
"carrier_connection_id": ANY,
|
|
244
|
+
},
|
|
245
|
+
"test_mode": True,
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"id": ANY,
|
|
249
|
+
"object_type": "rate",
|
|
250
|
+
"carrier_name": "canadapost",
|
|
251
|
+
"carrier_id": "canadapost",
|
|
252
|
+
"currency": "CAD",
|
|
253
|
+
"estimated_delivery": ANY,
|
|
254
|
+
"service": "canadapost_xpresspost",
|
|
255
|
+
"total_charge": 85.65,
|
|
256
|
+
"transit_days": 2,
|
|
257
|
+
"extra_charges": [
|
|
258
|
+
{"name": "Base charge", "amount": 75.82, "currency": "CAD", "id": None},
|
|
259
|
+
{"name": "Fuel surcharge", "amount": 3.21, "currency": "CAD", "id": None},
|
|
260
|
+
{"name": "SMB Savings", "amount": -4.55, "currency": "CAD", "id": None},
|
|
261
|
+
{"name": "Duty and taxes", "amount": 4.3, "currency": "CAD", "id": None},
|
|
262
|
+
{"name": "Discount", "amount": 11.17, "currency": "CAD", "id": None},
|
|
263
|
+
],
|
|
264
|
+
"meta": {
|
|
265
|
+
"ext": "canadapost",
|
|
266
|
+
"carrier": "canadapost",
|
|
267
|
+
"rate_provider": "canadapost",
|
|
268
|
+
"service_name": "CANADAPOST XPRESSPOST",
|
|
269
|
+
"carrier_connection_id": ANY,
|
|
270
|
+
},
|
|
271
|
+
"test_mode": True,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"id": ANY,
|
|
275
|
+
"object_type": "rate",
|
|
276
|
+
"carrier_name": "canadapost",
|
|
277
|
+
"carrier_id": "canadapost",
|
|
278
|
+
"currency": "CAD",
|
|
279
|
+
"estimated_delivery": ANY,
|
|
280
|
+
"service": "canadapost_priority",
|
|
281
|
+
"total_charge": 116.21,
|
|
282
|
+
"transit_days": 2,
|
|
283
|
+
"extra_charges": [
|
|
284
|
+
{"name": "Base charge", "amount": 101.83, "currency": "CAD", "id": None},
|
|
285
|
+
{"name": "Fuel surcharge", "amount": 4.27, "currency": "CAD", "id": None},
|
|
286
|
+
{"name": "SMB Savings", "amount": -7.03, "currency": "CAD", "id": None},
|
|
287
|
+
{"name": "Duties and taxes", "amount": 14.86, "currency": "CAD", "id": None},
|
|
288
|
+
{"name": "Discount", "amount": -2.76, "currency": "CAD", "id": None},
|
|
289
|
+
{"name": "brokerage", "amount": 2.28, "currency": "CAD", "id": ANY},
|
|
290
|
+
],
|
|
291
|
+
"meta": {
|
|
292
|
+
"ext": "canadapost",
|
|
293
|
+
"carrier": "canadapost",
|
|
294
|
+
"carrier_connection_id": ANY,
|
|
295
|
+
"rate_provider": "canadapost",
|
|
296
|
+
"service_name": "CANADAPOST PRIORITY",
|
|
297
|
+
},
|
|
298
|
+
"test_mode": True,
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: karrio_server_pricing
|
|
3
|
+
Version: 2025.5
|
|
4
|
+
Summary: Multi-carrier shipping API Pricing panel
|
|
5
|
+
Author-email: karrio <hello@karrio.io>
|
|
6
|
+
License-Expression: LGPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/karrioapi/karrio
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: karrio_server_core
|
|
12
|
+
|
|
13
|
+
# karrio.server.pricing
|
|
14
|
+
|
|
15
|
+
This package is a module of the [karrio](https://pypi.org/project/karrio.server) universal shipping API.
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
`Python 3.11+`
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install karrio.server.pricing
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Check the [karrio docs](https://docs.karrio.io) to get started.
|