From 70ca42fb7dc2298e866bcabf3cafa15553398a16 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Wed, 15 Jan 2025 12:04:28 -0500 Subject: [PATCH 01/14] Add support for Freightcom API key configuration. This commit introduces an `api_key` field to Freightcom settings models and mappers, allowing the configuration of an API key. It includes model migration, data handling updates, and ensures compatibility for future API key usage. --- .../karrio/mappers/freightcom/settings.py | 1 + .../karrio/providers/freightcom/utils.py | 5 +++-- .../providers/extension/models/freightcom.py | 1 + .../0081_freightcomsettings_api_key.py | 18 ++++++++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py index 42e611cbbd..ebdd584997 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py @@ -10,6 +10,7 @@ class Settings(BaseSettings): username: str password: str + api_key: str id: str = None test_mode: bool = False diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index 9bd6d449b8..e682f195e5 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -9,6 +9,7 @@ class Settings(BaseSettings): username: str password: str + api_key: str account_country_code: str = None metadata: dict = {} @@ -17,9 +18,9 @@ class Settings(BaseSettings): @property def server_url(self): return ( - "https://test.freightcom.com/rpc2" + "https://customer-external-api.ssd-test.freightcom.com" if self.test_mode - else "https://app.freightcom.com/rpc2" + else "https://external-api.freightcom.com" ) @property diff --git a/modules/core/karrio/server/providers/extension/models/freightcom.py b/modules/core/karrio/server/providers/extension/models/freightcom.py index 751ac61857..6b056b0e09 100644 --- a/modules/core/karrio/server/providers/extension/models/freightcom.py +++ b/modules/core/karrio/server/providers/extension/models/freightcom.py @@ -12,6 +12,7 @@ class Meta: username = models.CharField(max_length=200) password = models.CharField(max_length=200) + api_key = models.CharField(max_length=200, null=True) @property def carrier_name(self) -> str: diff --git a/modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py b/modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py new file mode 100644 index 0000000000..5b059bbb6a --- /dev/null +++ b/modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.16 on 2025-01-14 22:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("providers", "0080_alter_aramexsettings_account_country_code_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="freightcomsettings", + name="api_key", + field=models.CharField(max_length=200, null=True), + ), + ] From 2fb3b062dfe655ff6796607ae3be1904ae0b073a Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 20 Jan 2025 15:07:57 -0500 Subject: [PATCH 02/14] Remove unused Freightcom sample files and schemas. Deleted various Freightcom-related sample XML and XSD files, along with outdated vendor documentation, from the repository. These files were no longer required and their removal helps clean up the project. --- .../documentation/Freightcom API v3.2.3.pdf | Bin 708457 -> 0 bytes .../vendor/sample/sample_quote_reply.xml | 12 -- .../vendor/sample/sample_quote_request.xml | 14 -- .../sample/sample_shipment_cancel_reply.xml | 6 - .../sample/sample_shipment_cancel_request.xml | 5 - .../vendor/sample/sample_shipping_reply.xml | 27 --- .../vendor/sample/sample_shipping_request.xml | 28 --- .../freightcom/vendor/schemas/error.xsd | 24 --- .../freightcom/vendor/schemas/quote_reply.xsd | 53 ----- .../vendor/schemas/quote_request.xsd | 131 ------------ .../vendor/schemas/shipment_cancel_reply.xsd | 34 --- .../schemas/shipment_cancel_request.xsd | 26 --- .../vendor/schemas/shipping_reply.xsd | 123 ----------- .../vendor/schemas/shipping_request.xsd | 196 ------------------ 14 files changed, 679 deletions(-) delete mode 100644 modules/connectors/freightcom/vendor/documentation/Freightcom API v3.2.3.pdf delete mode 100644 modules/connectors/freightcom/vendor/sample/sample_quote_reply.xml delete mode 100644 modules/connectors/freightcom/vendor/sample/sample_quote_request.xml delete mode 100644 modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_reply.xml delete mode 100644 modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_request.xml delete mode 100644 modules/connectors/freightcom/vendor/sample/sample_shipping_reply.xml delete mode 100644 modules/connectors/freightcom/vendor/sample/sample_shipping_request.xml delete mode 100644 modules/connectors/freightcom/vendor/schemas/error.xsd delete mode 100644 modules/connectors/freightcom/vendor/schemas/quote_reply.xsd delete mode 100644 modules/connectors/freightcom/vendor/schemas/quote_request.xsd delete mode 100644 modules/connectors/freightcom/vendor/schemas/shipment_cancel_reply.xsd delete mode 100644 modules/connectors/freightcom/vendor/schemas/shipment_cancel_request.xsd delete mode 100644 modules/connectors/freightcom/vendor/schemas/shipping_reply.xsd delete mode 100644 modules/connectors/freightcom/vendor/schemas/shipping_request.xsd diff --git a/modules/connectors/freightcom/vendor/documentation/Freightcom API v3.2.3.pdf b/modules/connectors/freightcom/vendor/documentation/Freightcom API v3.2.3.pdf deleted file mode 100644 index 9b119dce2a63562d9135a9933ac884723d0af11f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708457 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,`EM)=zxxXng%wc5w5gC!wRj1NCswrJ06Kd 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%0D$d;@)#iLQDMf++Eg@Qo4| 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

UeLZ@@ajPq25~O{8WQ7sC`17+OH_+TC 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%0A`-fX_deHsoJ) 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�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

Q5yn?NUwGWy~Uyz7n43F^fPP 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 o^1R_PFP!D?-AF0U*T>t<8 diff --git a/modules/connectors/freightcom/vendor/sample/sample_quote_reply.xml b/modules/connectors/freightcom/vendor/sample/sample_quote_reply.xml deleted file mode 100644 index 31da0921f4..0000000000 --- a/modules/connectors/freightcom/vendor/sample/sample_quote_reply.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/sample/sample_quote_request.xml b/modules/connectors/freightcom/vendor/sample/sample_quote_request.xml deleted file mode 100644 index b0398cdfb3..0000000000 --- a/modules/connectors/freightcom/vendor/sample/sample_quote_request.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_reply.xml b/modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_reply.xml deleted file mode 100644 index 0b03069080..0000000000 --- a/modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_reply.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_request.xml b/modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_request.xml deleted file mode 100644 index 38068e493b..0000000000 --- a/modules/connectors/freightcom/vendor/sample/sample_shipment_cancel_request.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/sample/sample_shipping_reply.xml b/modules/connectors/freightcom/vendor/sample/sample_shipping_reply.xml deleted file mode 100644 index 6d4ce49da2..0000000000 --- a/modules/connectors/freightcom/vendor/sample/sample_shipping_reply.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - [base-64 encoded String] - [base-64 encoded String] - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/sample/sample_shipping_request.xml b/modules/connectors/freightcom/vendor/sample/sample_shipping_request.xml deleted file mode 100644 index 686816c876..0000000000 --- a/modules/connectors/freightcom/vendor/sample/sample_shipping_request.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/connectors/freightcom/vendor/schemas/error.xsd b/modules/connectors/freightcom/vendor/schemas/error.xsd deleted file mode 100644 index 41443010d9..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/error.xsd +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/schemas/quote_reply.xsd b/modules/connectors/freightcom/vendor/schemas/quote_reply.xsd deleted file mode 100644 index d1cb551e09..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/quote_reply.xsd +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/schemas/quote_request.xsd b/modules/connectors/freightcom/vendor/schemas/quote_request.xsd deleted file mode 100644 index 341c301ccf..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/quote_request.xsd +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/schemas/shipment_cancel_reply.xsd b/modules/connectors/freightcom/vendor/schemas/shipment_cancel_reply.xsd deleted file mode 100644 index 69e896328a..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/shipment_cancel_reply.xsd +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/schemas/shipment_cancel_request.xsd b/modules/connectors/freightcom/vendor/schemas/shipment_cancel_request.xsd deleted file mode 100644 index 0b900a395f..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/shipment_cancel_request.xsd +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/schemas/shipping_reply.xsd b/modules/connectors/freightcom/vendor/schemas/shipping_reply.xsd deleted file mode 100644 index 584b8c86f2..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/shipping_reply.xsd +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/connectors/freightcom/vendor/schemas/shipping_request.xsd b/modules/connectors/freightcom/vendor/schemas/shipping_request.xsd deleted file mode 100644 index a5d9cedea3..0000000000 --- a/modules/connectors/freightcom/vendor/schemas/shipping_request.xsd +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 00ffabd324b96c624ab9664fe5af13f770d465ec Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 20 Jan 2025 15:08:35 -0500 Subject: [PATCH 03/14] Add new Freightcom JSON schemas and update code generation Introduced `rate_request`, `rate_response`, and `error_response` JSON schemas for Freightcom. Replaced `generateDS` with a `quicktype`-based approach for generating Python bindings. Enhanced test fixtures to include new `api_key` configuration. --- modules/connectors/freightcom/generate | 27 ++- .../freightcom/schemas/error_response.json | 6 + .../freightcom/schemas/rate_request.json | 171 ++++++++++++++++++ .../freightcom/schemas/rate_response.json | 47 +++++ .../freightcom/tests/freightcom/fixture.py | 1 + 5 files changed, 244 insertions(+), 8 deletions(-) create mode 100644 modules/connectors/freightcom/schemas/error_response.json create mode 100644 modules/connectors/freightcom/schemas/rate_request.json create mode 100644 modules/connectors/freightcom/schemas/rate_response.json diff --git a/modules/connectors/freightcom/generate b/modules/connectors/freightcom/generate index 37e3143e15..8a128cd13d 100755 --- a/modules/connectors/freightcom/generate +++ b/modules/connectors/freightcom/generate @@ -1,12 +1,23 @@ -SCHEMAS=./vendor/schemas +SCHEMAS=./schemas LIB_MODULES=./karrio/schemas/freightcom +echo `pwd` find "${LIB_MODULES}" -name "*.py" -exec rm -r {} \; touch "${LIB_MODULES}/__init__.py" -generateDS --no-namespace-defs -o "${LIB_MODULES}/quote_request.py" $SCHEMAS/quote_request.xsd -generateDS --no-namespace-defs -o "${LIB_MODULES}/quote_reply.py" $SCHEMAS/quote_reply.xsd -generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_request.py" $SCHEMAS/shipping_request.xsd -generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_reply.py" $SCHEMAS/shipping_reply.xsd -generateDS --no-namespace-defs -o "${LIB_MODULES}/error.py" $SCHEMAS/error.xsd -generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_request.py" $SCHEMAS/shipment_cancel_request.xsd -generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_reply.py" $SCHEMAS/shipment_cancel_reply.xsd +quicktype() { + echo "Generating $1..." + docker run -it --rm --name quicktype -v $PWD:/app -e SCHEMAS=/app/schemas -e LIB_MODULES=/app/karrio/schemas/freightcom \ + karrio/tools /quicktype/script/quicktype --no-uuids --no-date-times --no-enums --src-lang json --lang jstruct \ + --all-properties-optional --type-as-suffix $@ +} + + +quicktype --src="${SCHEMAS}/rate_request.json" --out="${LIB_MODULES}/rate_request.py" +quicktype --src="${SCHEMAS}/rate_response.json" --out="${LIB_MODULES}/rate_response.py" +quicktype --src="${SCHEMAS}/error_response.json" --out="${LIB_MODULES}/error.py" + +# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_request.py" $SCHEMAS/shipping_request.xsd +# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_reply.py" $SCHEMAS/shipping_reply.xsd +# generateDS --no-namespace-defs -o "${LIB_MODULES}/error.py" $SCHEMAS/error.xsd +# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_request.py" $SCHEMAS/shipment_cancel_request.xsd +# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_reply.py" $SCHEMAS/shipment_cancel_reply.xsd diff --git a/modules/connectors/freightcom/schemas/error_response.json b/modules/connectors/freightcom/schemas/error_response.json new file mode 100644 index 0000000000..1f295a22e9 --- /dev/null +++ b/modules/connectors/freightcom/schemas/error_response.json @@ -0,0 +1,6 @@ +{ + "message": "bad or missing data", + "data": { + "details.destination.signature_requirement": "invalid" + } +} diff --git a/modules/connectors/freightcom/schemas/rate_request.json b/modules/connectors/freightcom/schemas/rate_request.json new file mode 100644 index 0000000000..55b90a3fe7 --- /dev/null +++ b/modules/connectors/freightcom/schemas/rate_request.json @@ -0,0 +1,171 @@ +{ + "services": [ + "string" + ], + "excluded_services": [ + "string" + ], + "details": { + "origin": { + "name": "Philip J Fry", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "residential": true, + "tailgate_required": true, + "instructions": "string", + "contact_name": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "email_addresses": [ + "user@example.com" + ], + "receives_email_updates": true + }, + "destination": { + "name": "Philip J Fry", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "residential": true, + "tailgate_required": true, + "instructions": "string", + "contact_name": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "email_addresses": [ + "user@example.com" + ], + "receives_email_updates": true, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + }, + "signature_requirement": "not-required" + }, + "expected_ship_date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "packaging_type": "pallet", + "packaging_properties": { + "pallet_type": "ltl", + "has_stackable_pallets": true, + "dangerous_goods": "limited-quantity", + "dangerous_goods_details": { + "packaging_group": "string", + "goods_class": "string", + "description": "string", + "united_nations_number": "string", + "emergency_contact_name": "string", + "emergency_contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "pallets": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + }, + "cuboid": { + "unit": "ft", + "l": 5, + "w": 5, + "h": 5 + } + }, + "description": "string", + "freight_class": "string", + "nmfc": "string", + "contents_type": "string", + "num_pieces": 0 + } + ], + "packages": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + }, + "cuboid": { + "unit": "ft", + "l": 5, + "w": 5, + "h": 5 + } + }, + "description": "string" + } + ], + "courierpaks": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + } + }, + "description": "string" + } + ], + "includes_return_label": false, + "special_handling_required": false, + "has_dangerous_goods": false, + "pallet_service_details": { + "limited_access_delivery_type": "string", + "limited_access_delivery_other_name": "string", + "in_bond": true, + "in_bond_details": { + "type": "immediate-exportation", + "name": "string", + "address": "string", + "contact_method": "email-address", + "contact_email_address": "string", + "contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "appointment_delivery": true, + "protect_from_freeze": true, + "threshold_pickup": true, + "threshold_delivery": true + }, + "insurance": { + "type": "internal", + "total_cost": { + "currency": "CAD", + "value": "4250" + } + } + }, + "reference_codes": [ + "string" + ] + } +} diff --git a/modules/connectors/freightcom/schemas/rate_response.json b/modules/connectors/freightcom/schemas/rate_response.json new file mode 100644 index 0000000000..db82e35dd3 --- /dev/null +++ b/modules/connectors/freightcom/schemas/rate_response.json @@ -0,0 +1,47 @@ +{ + "status": { + "done": true, + "total": 0, + "complete": 0 + }, + "rates": [ + { + "carrier_name": "string", + "service_name": "string", + "service_id": "string", + "valid_until": { + "year": 2006, + "month": 6, + "day": 7 + }, + "total": { + "currency": "CAD", + "value": "4250" + }, + "base": { + "currency": "CAD", + "value": "4250" + }, + "surcharges": [ + { + "type": "fuel", + "amount": { + "currency": "CAD", + "value": "4250" + } + } + ], + "taxes": [ + { + "type": "fuel", + "amount": { + "currency": "CAD", + "value": "4250" + } + } + ], + "transit_time_days": 5, + "transit_time_not_available": true + } + ] +} diff --git a/modules/connectors/freightcom/tests/freightcom/fixture.py b/modules/connectors/freightcom/tests/freightcom/fixture.py index becebb7dd7..69c1b18140 100644 --- a/modules/connectors/freightcom/tests/freightcom/fixture.py +++ b/modules/connectors/freightcom/tests/freightcom/fixture.py @@ -4,5 +4,6 @@ dict( username="username", password="password", + api_key="api_key", ) ) From 1c9e42e71eb7208fd02b3aed56a0b3d012f5d604 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Tue, 21 Jan 2025 16:51:28 -0500 Subject: [PATCH 04/14] Implement Freightcom Rest rate API Replaces the quote script with a more standardized and modular rate API integration. Introduced new schemas, utilities, and data mappings to streamline rate requests and responses. Updated shipping logic to align with the new structure. --- .../karrio/mappers/freightcom/__init__.py | 3 +- .../karrio/mappers/freightcom/mapper.py | 8 +- .../karrio/mappers/freightcom/proxy.py | 116 +- .../karrio/providers/freightcom/__init__.py | 2 +- .../karrio/providers/freightcom/error.py | 81 +- .../karrio/providers/freightcom/metadata.json | 4671 +++++++++++++++++ .../karrio/providers/freightcom/quote.py | 179 - .../karrio/providers/freightcom/rate.py | 205 + .../karrio/providers/freightcom/shipping.py | 4 +- .../karrio/providers/freightcom/units.py | 195 +- .../karrio/schemas/freightcom/error.py | 1865 +------ .../karrio/schemas/freightcom/rate_request.py | 173 + .../schemas/freightcom/rate_response.py | 49 + 13 files changed, 5366 insertions(+), 2185 deletions(-) create mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/metadata.json delete mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/quote.py create mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/rate.py create mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/rate_request.py create mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/rate_response.py diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py b/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py index 14b08c02b5..f7ec65645c 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py @@ -16,6 +16,5 @@ Settings=Settings, # Data Units options=units.ShippingOption, - services=units.ShippingService, - hub_carriers=units.CARRIER_IDS, + services=units.ShippingService ) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py b/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py index 6637368a4f..61bc514b4c 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py @@ -12,8 +12,8 @@ ConfirmationDetails, ) from karrio.providers.freightcom import ( - parse_quote_reply, - quote_request, + parse_rate_response, + rate_request, parse_shipping_reply, shipping_request, shipment_cancel_request, @@ -27,7 +27,7 @@ class Mapper(BaseMapper): # Request Mappers def create_rate_request(self, payload: RateRequest) -> Serializable: - return quote_request(payload, self.settings) + return rate_request(payload, self.settings) def create_shipment_request(self, payload: ShipmentRequest) -> Serializable: return shipping_request(payload, self.settings) @@ -42,7 +42,7 @@ def create_cancel_shipment_request( def parse_rate_response( self, response: Deserializable ) -> Tuple[List[RateDetails], List[Message]]: - return parse_quote_reply(response, self.settings) + return parse_rate_response(response, self.settings) def parse_shipment_response( self, response: Deserializable diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py index 98d619d83e..419220f55a 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py @@ -1,38 +1,102 @@ -from karrio.core.utils import request as http, XP -from karrio.api.proxy import Proxy as BaseProxy +"""Karrio Freightcom client proxy.""" + +import time +import karrio.lib as lib +import karrio.api.proxy as proxy from karrio.mappers.freightcom.settings import Settings -from karrio.core.utils.serializable import Serializable, Deserializable -class Proxy(BaseProxy): +class Proxy(proxy.Proxy): settings: Settings + MAX_RETRIES = 10 + POLL_INTERVAL = 2 # seconds - def get_rates(self, request: Serializable) -> Deserializable: - response = http( - url=self.settings.server_url, - data=request.serialize(), - trace=self.trace_as("xml"), + def get_rates(self, request: lib.Serializable) -> lib.Deserializable[str]: + # Step 1: Submit rate request and get quote ID + response = lib.request( + url=f"{self.settings.server_url}/rate", + data=lib.to_json(request.serialize()), + trace=self.trace_as("json"), method="POST", - headers={"Content-Type": "application/xml"}, + headers={ + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": f"{self.settings.api_key}", + }, ) - return Deserializable(response, XP.to_xml) - def create_shipment(self, request: Serializable) -> Deserializable: - response = http( - url=self.settings.server_url, - data=request.serialize(), - trace=self.trace_as("xml"), + res = lib.Deserializable(response, lib.to_dict) + rate_id = res.deserialize().get('request_id') + if not rate_id: + return res + + # Step 2: Poll for rate results + for _ in range(self.MAX_RETRIES): + quote_response = lib.request( + url=f"{self.settings.server_url}/rate/{rate_id}", + trace=self.trace_as("json"), + method="GET", + headers={ + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": f"{self.settings.api_key}", + }, + ) + status_res = lib.Deserializable(quote_response, lib.to_dict) + + status = status_res.deserialize().get('status', {}).get('done', False) + + if status: # Quote is complete + return status_res + + time.sleep(self.POLL_INTERVAL) + + # If we exceed max retries + return lib.Deserializable({ + 'error': 'Rate calculation timed out' + }, lib.to_dict) + + def create_shipment(self, request: lib.Serializable) -> lib.Deserializable[str]: + response = lib.request( + url=f"{self.settings.server_url}/v2/shipments", + data=lib.to_json(request.serialize()), + trace=self.trace_as("json"), method="POST", - headers={"Content-Type": "application/xml"}, + headers={ + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": f"Bearer {self.settings.api_key}", + }, ) - return Deserializable(response, XP.to_xml) - def cancel_shipment(self, request: Serializable) -> Deserializable: - response = http( - url=self.settings.server_url, - data=request.serialize(), - trace=self.trace_as("xml"), - method="POST", - headers={"Content-Type": "application/xml"}, + return lib.Deserializable(response, lib.to_dict) + + def get_tracking(self, request: lib.Serializable) -> lib.Deserializable[str]: + tracking_id = request.serialize()["tracking_id"] + response = lib.request( + url=f"{self.settings.server_url}/v2/track/{tracking_id}", + trace=self.trace_as("json"), + method="GET", + headers={ + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": f"Bearer {self.settings.api_key}", + }, + ) + + return lib.Deserializable(response, lib.to_dict) + + def cancel_shipment(self, request: lib.Serializable) -> lib.Deserializable[str]: + tracking_id = request.serialize()["tracking_id"] + response = lib.request( + url=f"{self.settings.server_url}/v2/track/{tracking_id}", + trace=self.trace_as("json"), + method="GET", + headers={ + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": f"Bearer {self.settings.api_key}", + }, ) - return Deserializable(response, XP.to_xml) + + return lib.Deserializable(response, lib.to_dict) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py b/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py index a9b021054c..86744b8550 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py @@ -1,4 +1,4 @@ -from karrio.providers.freightcom.quote import parse_quote_reply, quote_request +from karrio.providers.freightcom.rate import parse_rate_response, rate_request from karrio.providers.freightcom.shipping import ( parse_shipping_reply, shipping_request, diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/error.py b/modules/connectors/freightcom/karrio/providers/freightcom/error.py index 923739e78d..83787fe884 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/error.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/error.py @@ -1,40 +1,55 @@ -from typing import List -from karrio.schemas.freightcom.error import ErrorType -from karrio.schemas.freightcom.quote_reply import CarrierErrorMessageType -from karrio.core.models import Message -from karrio.core.utils import Element, XP -from karrio.providers.freightcom.utils import Settings +import typing +import karrio.lib as lib +import karrio.core.models as models +import karrio.providers.freightcom.utils as provider_utils -def parse_error_response(response: Element, settings: Settings) -> List[Message]: - errors = XP.find("Error", response, ErrorType) - carrier_errors = XP.find("CarrierErrorMessage", response, CarrierErrorMessageType) +def parse_error_response( + response: dict, + settings: provider_utils.Settings, + **kwargs, +) -> typing.List[models.Message]: + responses = response if isinstance(response, list) else [response] + errors = [ + *[_ for _ in responses if _.get("message")], + # *sum( + # [ + # [dict(code="warning", message=__) for __ in _.get("warnings")] + # for _ in responses + # if _.get("warnings") + # ], + # [], + # ), + # *sum( + # [ + # [ + # dict( + # code="error", + # message=order["message"] + # ) + # for order in _.get("order", []) + # if "message" in order and order["message"].startswith("Error") + # ] + # for _ in responses + # ], + # [], + # ) + ] return [ - *[_extract_error(er, settings) for er in errors if er.Message != ""], - *[ - _extract_carrier_error(er, settings) - for er in carrier_errors - if er.errorMessage0 != "" - ], + models.Message( + carrier_id=settings.carrier_id, + carrier_name=settings.carrier_name, + code=error.get("code"), + message=error.get("message"), + details={ + **kwargs, + "type": error.get("type"), + "fieldErrors": error.get("fieldErrors"), + "thirdPartyMessage": error.get("thirdPartyMessage"), + }, + ) + for error in errors ] -def _extract_carrier_error( - error: CarrierErrorMessageType, settings: Settings -) -> Message: - return Message( - code="CarrierErrorMessage", - carrier_name=settings.carrier_name, - carrier_id=settings.carrier_id, - message=error.errorMessage0, - ) - - -def _extract_error(error: ErrorType, settings: Settings) -> Message: - return Message( - code="Error", - carrier_name=settings.carrier_name, - carrier_id=settings.carrier_id, - message=error.Message, - ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/metadata.json b/modules/connectors/freightcom/karrio/providers/freightcom/metadata.json new file mode 100644 index 0000000000..1fe4acbeee --- /dev/null +++ b/modules/connectors/freightcom/karrio/providers/freightcom/metadata.json @@ -0,0 +1,4671 @@ +{ + "PROD_SERVICES": [ + { + "id": "dhatttransfreightserviceinc-558.standard", + "carrier_name": "DHATT TRANSFREIGHT SERVICE INC.", + "service_name": "Standard" + }, + { + "id": "kelownaexpressfreightinc-570.standard", + "carrier_name": "Kelowna Express Freight Inc.", + "service_name": "Standard" + }, + { + "id": "metrofreightwaysltd-610.standard", + "carrier_name": "METRO FREIGHTWAYS LTD.", + "service_name": "Standard" + }, + { + "id": "scottfreight-190.standard", + "carrier_name": "Scott Freight", + "service_name": "Standard" + }, + { + "id": "tforcefreight-575.standard", + "carrier_name": "TForce Freight", + "service_name": "Standard" + }, + { + "id": "vkdeliverylinehaulltd-499.standard", + "carrier_name": "VK DELIVERY/LINEHAUL LTD", + "service_name": "Standard" + }, + { + "id": "customcourierco-469.standard", + "carrier_name": "Custom Courier Co.", + "service_name": "Standard" + }, + { + "id": "ecotransinc-396.standard", + "carrier_name": "ECOTRANS INC", + "service_name": "Standard" + }, + { + "id": "fedex.economy", + "carrier_name": "FedEx Freight", + "service_name": "Economy" + }, + { + "id": "fedex.standard", + "carrier_name": "FedEx Freight", + "service_name": "Priority" + }, + { + "id": "gtagsm-540.standard", + "carrier_name": "G.T.A GSM", + "service_name": "Standard" + }, + { + "id": "kindersleytransportusa-551.standard", + "carrier_name": "Kindersley Transport | USA", + "service_name": "Standard" + }, + { + "id": "lodestarlogistics-446.standard", + "carrier_name": "LODESTAR LOGISTICS", + "service_name": "Standard" + }, + { + "id": "loomis-express.express-0900", + "carrier_name": "Loomis", + "service_name": "Express 9:00" + }, + { + "id": "loomis-express.express-1200", + "carrier_name": "Loomis", + "service_name": "Express 12:00" + }, + { + "id": "loomis-express.express-1800", + "carrier_name": "Loomis", + "service_name": "Express 18:00" + }, + { + "id": "loomis-express.ground", + "carrier_name": "Loomis", + "service_name": "Ground" + }, + { + "id": "mrflatbedstransportinc-284.standard", + "carrier_name": "Mr Flatbeds Transport Inc", + "service_name": "Standard" + }, + { + "id": "bisontransport-278.standard", + "carrier_name": "Bison Transport", + "service_name": "Standard" + }, + { + "id": "canpar.ground", + "carrier_name": "Canpar", + "service_name": "Ground" + }, + { + "id": "canpar.international", + "carrier_name": "Canpar", + "service_name": "International" + }, + { + "id": "canpar.overnight", + "carrier_name": "Canpar", + "service_name": "Overnight" + }, + { + "id": "canpar.overnight-letter", + "carrier_name": "Canpar", + "service_name": "Overnight Letter" + }, + { + "id": "canpar.overnight-pak", + "carrier_name": "Canpar", + "service_name": "Overnight Pak" + }, + { + "id": "canpar.select", + "carrier_name": "Canpar", + "service_name": "Select" + }, + { + "id": "canpar.select-letter", + "carrier_name": "Canpar", + "service_name": "Select Letter" + }, + { + "id": "canpar.select-pak", + "carrier_name": "Canpar", + "service_name": "Select Pak" + }, + { + "id": "canpar.select-usa", + "carrier_name": "Canpar", + "service_name": "Select U.S.A." + }, + { + "id": "canpar.usa", + "carrier_name": "Canpar", + "service_name": "U.S.A." + }, + { + "id": "canpar.usa-Letter", + "carrier_name": "Canpar", + "service_name": "U.S.A. Letter" + }, + { + "id": "canpar.usa-pak", + "carrier_name": "Canpar", + "service_name": "U.S.A. Pak" + }, + { + "id": "csa.standard", + "carrier_name": "CSA", + "service_name": "Standard" + }, + { + "id": "ettransportgroup-337.standard", + "carrier_name": "ET Transport Group", + "service_name": "Standard" + }, + { + "id": "guardiumlogisticsltd-608.standard", + "carrier_name": "Guardium Logistics Ltd.", + "service_name": "Standard" + }, + { + "id": "keltictransportation-465.standard", + "carrier_name": "Keltic Transportation", + "service_name": "Standard" + }, + { + "id": "kjlxpressinc-583.standard", + "carrier_name": "KJL Xpress Inc.", + "service_name": "Standard" + }, + { + "id": "newpennmotorexpress-445.standard", + "carrier_name": "New Penn Motor Express", + "service_name": "Standard" + }, + { + "id": "bridgepointlogisticsltd-524.standard", + "carrier_name": "BRIDGEPOINT LOGISTICS LTD", + "service_name": "Standard" + }, + { + "id": "canadapost.domestic", + "carrier_name": "Canada Post", + "service_name": "Domestic" + }, + { + "id": "canadapost.expedited-parcel", + "carrier_name": "Canada Post", + "service_name": "Expedited Parcel" + }, + { + "id": "canadapost.expedited-parcel-usa", + "carrier_name": "Canada Post", + "service_name": "Expedited Parcel USA" + }, + { + "id": "canadapost.international", + "carrier_name": "Canada Post", + "service_name": "International" + }, + { + "id": "canadapost.international-parcel-air", + "carrier_name": "Canada Post", + "service_name": "International Parcel Air" + }, + { + "id": "canadapost.international-parcel-surface", + "carrier_name": "Canada Post", + "service_name": "International Parcel Surface" + }, + { + "id": "canadapost.priority", + "carrier_name": "Canada Post", + "service_name": "Priority" + }, + { + "id": "canadapost.priority-ww-envelope-international", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide envelope INT’L" + }, + { + "id": "canadapost.priority-ww-envelope-usa", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide envelope USA" + }, + { + "id": "canadapost.priority-ww-pak-international", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide pak INT’L" + }, + { + "id": "canadapost.priority-ww-pak-usa", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide pak USA" + }, + { + "id": "canadapost.priority-ww-parcel-international", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide parcel INT’L" + }, + { + "id": "canadapost.priority-ww-parcel-usa", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide parcel USA" + }, + { + "id": "canadapost.regular-parcel", + "carrier_name": "Canada Post", + "service_name": "Regular Parcel" + }, + { + "id": "canadapost.small-packet-international-air", + "carrier_name": "Canada Post", + "service_name": "Small Packet International Air" + }, + { + "id": "canadapost.small-packet-international-surface", + "carrier_name": "Canada Post", + "service_name": "Small Packet International Surface" + }, + { + "id": "canadapost.small-packet-usa-air", + "carrier_name": "Canada Post", + "service_name": "Small Packet USA Air" + }, + { + "id": "canadapost.tracked-packet-international", + "carrier_name": "Canada Post", + "service_name": "Tracked Packet - International" + }, + { + "id": "canadapost.tracked-packet-usa", + "carrier_name": "Canada Post", + "service_name": "Tracked Packet USA" + }, + { + "id": "canadapost.xpresspost", + "carrier_name": "Canada Post", + "service_name": "Xpresspost" + }, + { + "id": "canadapost.xpresspost-international", + "carrier_name": "Canada Post", + "service_name": "Xpresspost International" + }, + { + "id": "canadapost.xpresspost-usa", + "carrier_name": "Canada Post", + "service_name": "Xpresspost USA" + }, + { + "id": "gardewine.standard", + "carrier_name": "Gardewine", + "service_name": "Standard" + }, + { + "id": "giantleaftruckinginc-556.standard", + "carrier_name": "GIANT LEAF TRUCKING INC.", + "service_name": "Standard" + }, + { + "id": "purolatorfreight.standard", + "carrier_name": "Purolator Freight", + "service_name": "Standard" + }, + { + "id": "swyft.nextday", + "carrier_name": "Swyft", + "service_name": "Next Day" + }, + { + "id": "swyft.sameday", + "carrier_name": "Swyft", + "service_name": "Same Day" + }, + { + "id": "usps.ground-advantage", + "carrier_name": "USPS", + "service_name": "Ground Advantage" + }, + { + "id": "usps.priority-mail", + "carrier_name": "USPS", + "service_name": "Priority Mail" + }, + { + "id": "usps.priority-mail-express", + "carrier_name": "USPS", + "service_name": "Priority Mail Express" + }, + { + "id": "xwestcarriersinc-547.standard", + "carrier_name": "X West Carriers Inc", + "service_name": "Standard" + }, + { + "id": "paulsfreightline-400.standard", + "carrier_name": "PAULS FREIGHTLINE", + "service_name": "Standard" + }, + { + "id": "ppgroadlinesinc-250.standard", + "carrier_name": "PPG ROADLINES INC.", + "service_name": "Standard" + }, + { + "id": "transportgilleslavigne-592.standard", + "carrier_name": "Transport Gilles Lavigne", + "service_name": "Standard" + }, + { + "id": "xpologistics-265.standard", + "carrier_name": "XPO Logistics", + "service_name": "Standard" + }, + { + "id": "upscourier-162.standard", + "carrier_name": "UPS Courier", + "service_name": "Standard" + }, + { + "id": "94222528qubecincdbagroupefmj-626.standard", + "carrier_name": "9422-2528 Québec Inc. DBA Groupe FMJ", + "service_name": "Standard" + }, + { + "id": "one.standard", + "carrier_name": "ONE Transportation", + "service_name": "Standard" + }, + { + "id": "readygotransportinc-435.standard", + "carrier_name": "READY GO TRANSPORT INC.", + "service_name": "Standard" + }, + { + "id": "streetkingtransportationltd-557.standard", + "carrier_name": "STREET KING TRANSPORTATION LTD", + "service_name": "Standard" + }, + { + "id": "martinroytransport-310.standard", + "carrier_name": "Martin Roy Transport", + "service_name": "Standard" + }, + { + "id": "sameday.2-man-delivery-to-entrance", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Entrance - 2 Person" + }, + { + "id": "sameday.2-man-delivery-to-room-of-choice", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Room of Choice - 2 Person" + }, + { + "id": "sameday.2-man-delivery-to-room-of-choice-with-debris-removal", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Two-person delivery to room of choice with debris removal" + }, + { + "id": "sameday.dayr-ecom-urgent-pac", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "eCommerce Urgent Pak" + }, + { + "id": "sameday.delivery-to-entrance", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Entrance" + }, + { + "id": "sameday.delivery-to-room-of-choice", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Room of Choice" + }, + { + "id": "sameday.delivery-to-room-of-choice-with-debris-removal", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Room of Choice with Debris Removal" + }, + { + "id": "sameday.ground-daynross-road", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Ground - Road" + }, + { + "id": "sameday.next-day-before-5pm", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Next Day Delivery by 5 PM" + }, + { + "id": "sameday.next-day-before-9am", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Next Day Delivery by 9 AM" + }, + { + "id": "sameday.next-day-delivery-before-noon", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Next Day Delivery Before Noon" + }, + { + "id": "searcytrucking-462.standard", + "carrier_name": "Searcy Trucking", + "service_name": "Standard" + }, + { + "id": "transkidinc-453.standard", + "carrier_name": "Transkid Inc", + "service_name": "Standard" + }, + { + "id": "amatransinc-251.standard", + "carrier_name": "AMA Trans Inc", + "service_name": "Standard" + }, + { + "id": "checkercourier-276.standard", + "carrier_name": "Checker Courier", + "service_name": "Standard" + }, + { + "id": "empiretransportltd-413.standard", + "carrier_name": "EMPIRE TRANSPORT LTD", + "service_name": "Standard" + }, + { + "id": "flashtransport-388.standard", + "carrier_name": "Flash Transport", + "service_name": "Standard" + }, + { + "id": "wce.standard", + "carrier_name": "WCE", + "service_name": "Intermodal" + }, + { + "id": "xpoglobalforwardinginc-416.standard", + "carrier_name": "XPO GLOBAL FORWARDING INC", + "service_name": "Standard" + }, + { + "id": "kjstransport-623.standard", + "carrier_name": "KJS Transport", + "service_name": "Standard" + }, + { + "id": "ltlexpressfreight-459.standard", + "carrier_name": "LTL EXPRESS FREIGHT", + "service_name": "Standard" + }, + { + "id": "overland.standard", + "carrier_name": "Overland", + "service_name": "Standard" + }, + { + "id": "dbgtrucking-132.standard", + "carrier_name": "DBG TRUCKING ", + "service_name": "Standard" + }, + { + "id": "dhillondhillontransportltd-528.standard", + "carrier_name": "Dhillon & Dhillon Transport Ltd.", + "service_name": "Standard" + }, + { + "id": "freightboy-565.standard", + "carrier_name": "FREIGHT BOY", + "service_name": "Standard" + }, + { + "id": "highrisetransport-545.standard", + "carrier_name": "HIGH RISE TRANSPORT", + "service_name": "Standard" + }, + { + "id": "yrcfreight-330.standard", + "carrier_name": "YRC Freight", + "service_name": "Standard" + }, + { + "id": "caledoncouriers-294.standard", + "carrier_name": "Caledon Couriers", + "service_name": "Standard" + }, + { + "id": "proactivetransportcoproactivesupplycahinsolutionsinc-471.standard", + "carrier_name": "PROACTIVE TRANSPORT C/O PROACTIVE SUPPLYCAHIN SOLUTIONS INC.", + "service_name": "Standard" + }, + { + "id": "roadtrainexpress-433.standard", + "carrier_name": "ROAD TRAIN EXPRESS ", + "service_name": "Standard" + }, + { + "id": "sablemarcoinc-509.standard", + "carrier_name": "Sable Marco inc.", + "service_name": "Standard" + }, + { + "id": "here2therefreightmanagementinc-629.standard", + "carrier_name": "Here 2 There Freight Management Inc", + "service_name": "Standard" + }, + { + "id": "thompsonemergencyfreightsystems-277.standard", + "carrier_name": "Thompson Emergency Freight Systems", + "service_name": "Standard" + }, + { + "id": "dhl-ecomm.packet-international", + "carrier_name": "DHL eCommerce", + "service_name": "Package International" + }, + { + "id": "dhl-ecomm.parcel-expedited", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel Expedited" + }, + { + "id": "dhl-ecomm.parcel-expedited-max", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel Expedited Max" + }, + { + "id": "dhl-ecomm.parcel-ground", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel Ground" + }, + { + "id": "dhl-ecomm.parcel-international-direct", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Direct" + }, + { + "id": "dhl-ecomm.parcel-international-direct-priority", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Direct Priority" + }, + { + "id": "dhl-ecomm.parcel-international-direct-standard", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Direct Standard" + }, + { + "id": "dhl-ecomm.parcel-international-standard", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Standard" + }, + { + "id": "excel-transport.standard", + "carrier_name": "Excel Transportation", + "service_name": "Standard" + }, + { + "id": "newpenn.standard", + "carrier_name": "New Penn", + "service_name": "Standard" + }, + { + "id": "bettertrucks.ddu", + "carrier_name": "Better Trucks", + "service_name": "DDU" + }, + { + "id": "bettertrucks.express", + "carrier_name": "Better Trucks", + "service_name": "Express" + }, + { + "id": "bettertrucks.next_day", + "carrier_name": "Better Trucks", + "service_name": "Next Day" + }, + { + "id": "bettertrucks.same_day", + "carrier_name": "Better Trucks", + "service_name": "Same Day" + }, + { + "id": "boxknight.next-day", + "carrier_name": "BoxKnight", + "service_name": "Next Day" + }, + { + "id": "boxknight.sameday", + "carrier_name": "BoxKnight", + "service_name": "Same Day" + }, + { + "id": "cranestransport-555.standard", + "carrier_name": "CRANES TRANSPORT", + "service_name": "Standard" + }, + { + "id": "daynross.cs", + "carrier_name": "Day & Ross", + "service_name": "CS" + }, + { + "id": "daynross.domestic-standard", + "carrier_name": "Day & Ross", + "service_name": "Domestic Standard" + }, + { + "id": "daynross.transborder-standard", + "carrier_name": "Day & Ross", + "service_name": "Transborder Standard" + }, + { + "id": "loadsafecrossborderfreightinc-493.standard", + "carrier_name": "LOADSAFE CROSSBORDER FREIGHT INC.", + "service_name": "Standard" + }, + { + "id": "maritimeontario-267.standard", + "carrier_name": "Maritime-Ontario", + "service_name": "Standard" + }, + { + "id": "saiamotorfreightinc-139.standard", + "carrier_name": "Saia Motor Freight Inc", + "service_name": "Standard" + }, + { + "id": "speedytransport-153.standard", + "carrier_name": "Speedy Transport", + "service_name": "Standard" + }, + { + "id": "bakshbroscartageinc-485.standard", + "carrier_name": "BAKSH BROS. CARTAGE INC", + "service_name": "Standard" + }, + { + "id": "estesexpresslines-274.standard", + "carrier_name": "ESTES Express Lines", + "service_name": "Standard" + }, + { + "id": "highenergytransportinc-533.standard", + "carrier_name": "High Energy Transport Inc", + "service_name": "Standard" + }, + { + "id": "kriskaytrucklinesinc-443.standard", + "carrier_name": "Kris Kay Truck Lines Inc", + "service_name": "Standard" + }, + { + "id": "rollsright-245.standard", + "carrier_name": "Rolls Right", + "service_name": "Standard" + }, + { + "id": "sunshinecoastlogisticsinc-614.standard", + "carrier_name": "Sunshine Coast Logistics Inc", + "service_name": "Standard" + }, + { + "id": "uppaltransportltddbabluewatertrucking-615.standard", + "carrier_name": "Uppal Transport Ltd dba Bluewater Trucking", + "service_name": "Standard" + }, + { + "id": "dayrossfreightrl-529.standard", + "carrier_name": "Day & Ross Freight | R+L", + "service_name": "Standard" + }, + { + "id": "fgmtrucklines-235.standard", + "carrier_name": "FGM Trucklines", + "service_name": "Standard" + }, + { + "id": "kdrtrucklinesinc-627.standard", + "carrier_name": "KDR Trucklines Inc", + "service_name": "Standard" + }, + { + "id": "psrlogisticsinc-506.standard", + "carrier_name": "PSR LOGISTICS INC.", + "service_name": "Standard" + }, + { + "id": "northplusgroupofcompanies-568.standard", + "carrier_name": "NORTH PLUS GROUP OF COMPANIES", + "service_name": "Standard" + }, + { + "id": "swiftdeliverysystems-268.standard", + "carrier_name": "Swift Delivery Systems", + "service_name": "Standard" + }, + { + "id": "vitran.maxx", + "carrier_name": "Vitran", + "service_name": "Maxx" + }, + { + "id": "vitran.priority", + "carrier_name": "Vitran", + "service_name": "Priority" + }, + { + "id": "vitran.regular", + "carrier_name": "Vitran", + "service_name": "Regular" + }, + { + "id": "fastnflowlogistics-487.standard", + "carrier_name": "FAST N FLOW LOGISTICS", + "service_name": "Standard" + }, + { + "id": "fpifreightpartnersinternationalinc-458.standard", + "carrier_name": "FPI - FREIGHT PARTNERS INTERNATIONAL INC.", + "service_name": "Standard" + }, + { + "id": "gsm.air-skip", + "carrier_name": "GTA GSM", + "service_name": "AirSkip" + }, + { + "id": "gsm.air-skip-plus", + "carrier_name": "GTA GSM", + "service_name": "AirSkip+" + }, + { + "id": "gsm.armed-secure-air", + "carrier_name": "GTA GSM", + "service_name": "Armed Secure Air" + }, + { + "id": "gsm.armed-secure-ground", + "carrier_name": "GTA GSM", + "service_name": "Armed Secure Ground" + }, + { + "id": "gsm.ground", + "carrier_name": "GTA GSM", + "service_name": "Ground" + }, + { + "id": "gsm.secure-air", + "carrier_name": "GTA GSM", + "service_name": "Secure Air" + }, + { + "id": "gsm.secure-ground", + "carrier_name": "GTA GSM", + "service_name": "Secure Ground" + }, + { + "id": "gsm.zone-skip", + "carrier_name": "GTA GSM", + "service_name": "ZoneSkip" + }, + { + "id": "gsm.zone-skip-plus", + "carrier_name": "GTA GSM", + "service_name": "ZoneSkip+" + }, + { + "id": "mcarthurexpress-503.standard", + "carrier_name": "Mcarthur Express", + "service_name": "Standard" + }, + { + "id": "himmatpuralogisticsinc-473.standard", + "carrier_name": "HIMMATPURA LOGISTICS INC", + "service_name": "Standard" + }, + { + "id": "proformanceintermodalinc-489.standard", + "carrier_name": "Pro-Formance Intermodal Inc.", + "service_name": "Standard" + }, + { + "id": "whistlercourier-621.standard", + "carrier_name": "Whistler Courier", + "service_name": "Standard" + }, + { + "id": "armourtransportationsystems-562.standard", + "carrier_name": "Armour Transportation Systems", + "service_name": "Standard" + }, + { + "id": "fastfrategroup-498.standard", + "carrier_name": "Fastfrate Group", + "service_name": "Standard" + }, + { + "id": "glotransports-530.standard", + "carrier_name": "GLO TRANSPORTS", + "service_name": "Standard" + }, + { + "id": "gsdirect-292.standard", + "carrier_name": "G&S Direct", + "service_name": "Standard" + }, + { + "id": "gls.ground", + "carrier_name": "GLS", + "service_name": "Ground" + }, + { + "id": "lighthousetransportationinc-619.standard", + "carrier_name": "LIGHTHOUSE TRANSPORTATION INC.", + "service_name": "Standard" + }, + { + "id": "pbtransport-507.standard", + "carrier_name": "P&B TRANSPORT", + "service_name": "Standard" + }, + { + "id": "servicestarfreightways-441.standard", + "carrier_name": "ServiceStar Freightways", + "service_name": "Standard" + }, + { + "id": "tforcefreight.tforcefreight-guarnteed", + "carrier_name": "TForceFreight", + "service_name": "TForceFreight Guaranteed" + }, + { + "id": "tforcefreight.tforcefreight-ltl", + "carrier_name": "TForceFreight", + "service_name": "TForceFreight LTL" + }, + { + "id": "tforcefreight.tforcefreight-standard", + "carrier_name": "TForceFreight", + "service_name": "TForceFreight Standard" + }, + { + "id": "zipcourier-468.standard", + "carrier_name": "Zip Courier", + "service_name": "Standard" + }, + { + "id": "cmwexpress-537.standard", + "carrier_name": "CMW Express", + "service_name": "Standard" + }, + { + "id": "ktslogisticsinc-620.standard", + "carrier_name": "KTS LOGISTICS INC", + "service_name": "Standard" + }, + { + "id": "raymanmotorfreight-357.standard", + "carrier_name": "Rayman Motor Freight", + "service_name": "Standard" + }, + { + "id": "safeloadtransportltd-510.standard", + "carrier_name": "SAFE LOAD TRANSPORT LTD. ", + "service_name": "Standard" + }, + { + "id": "milyardgroupinc-391.standard", + "carrier_name": "Milyard Group Inc.", + "service_name": "Standard" + }, + { + "id": "minimax.standard", + "carrier_name": "Minimax", + "service_name": "Standard" + }, + { + "id": "suretrackgroup-369.standard", + "carrier_name": "SureTrack Group", + "service_name": "Standard" + }, + { + "id": "ctmatransport-535.standard", + "carrier_name": "CTMA Transport", + "service_name": "Standard" + }, + { + "id": "kawarthacourier-425.standard", + "carrier_name": "Kawartha Courier", + "service_name": "Standard" + }, + { + "id": "kepatransportinc-516.standard", + "carrier_name": "KEPA Transport Inc", + "service_name": "Standard" + }, + { + "id": "kindersley-freight.domestic-expedited", + "carrier_name": "Kindersley Transport", + "service_name": "Domestic Expedited" + }, + { + "id": "kindersley-freight.domestic-rail", + "carrier_name": "Kindersley Transport", + "service_name": "Domestic Rail" + }, + { + "id": "kindersley-freight.domestic-road", + "carrier_name": "Kindersley Transport", + "service_name": "Domestic Road" + }, + { + "id": "kindersley-freight.transborder", + "carrier_name": "Kindersley Transport", + "service_name": "Transborder" + }, + { + "id": "boeingtruckinginc-593.standard", + "carrier_name": "Boeing Trucking Inc. ", + "service_name": "Standard" + }, + { + "id": "freightcom-134.standard", + "carrier_name": "Freightcom", + "service_name": "Standard" + }, + { + "id": "groupemorneau-599.standard", + "carrier_name": "Groupe Morneau", + "service_name": "Standard" + }, + { + "id": "xpofreightbrokerage-280.standard", + "carrier_name": "XPO Freight Brokerage", + "service_name": "Standard" + }, + { + "id": "aalfatransportationcorporation-596.standard", + "carrier_name": "A ALFA TRANSPORTATION CORPORATION", + "service_name": "Standard" + }, + { + "id": "barriedirecttransportation-428.standard", + "carrier_name": "Barrie Direct Transportation ", + "service_name": "Standard" + }, + { + "id": "fastfrate.express", + "carrier_name": "Fastfrate", + "service_name": "Express" + }, + { + "id": "fastfrate.standard", + "carrier_name": "Fastfrate", + "service_name": "Standard" + }, + { + "id": "flatouttransportation-566.standard", + "carrier_name": "Flat Out Transportation", + "service_name": "Standard" + }, + { + "id": "reddaway.guaranteed-3pm", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 3:30 PM" + }, + { + "id": "reddaway.guaranteed-9am", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 9 AM" + }, + { + "id": "reddaway.guaranteed-noon", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 12:00 PM (noon)" + }, + { + "id": "reddaway.guaranteed-weekend", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Weekend" + }, + { + "id": "reddaway.guarenteed-9am", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 9 AM" + }, + { + "id": "reddaway.guarenteed-noon", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 12:00 PM (noon)" + }, + { + "id": "reddaway.interline", + "carrier_name": "Reddaway", + "service_name": "Interline Delivery" + }, + { + "id": "reddaway.multi-hour-window", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Window - Multi-Hour Window" + }, + { + "id": "reddaway.regional-delivery", + "carrier_name": "Reddaway", + "service_name": "Regional Delivery" + }, + { + "id": "reddaway.single-hour-window", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Window - Single-hour Window" + }, + { + "id": "reddaway.single-or-multi-day", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Window - Single or Multi-day Window" + }, + { + "id": "reddaway.standard", + "carrier_name": "Reddaway", + "service_name": "Standard" + }, + { + "id": "urbanvalleytransport-526.standard", + "carrier_name": "Urban Valley Transport ", + "service_name": "Standard" + }, + { + "id": "xrpexpress-618.standard", + "carrier_name": "XRP Express", + "service_name": "Standard" + }, + { + "id": "actionforcetransportltd-363.standard", + "carrier_name": "Action Force Transport Ltd", + "service_name": "Standard" + }, + { + "id": "airpro-255.standard", + "carrier_name": "Air Pro", + "service_name": "Standard" + }, + { + "id": "asslafreightinc-588.standard", + "carrier_name": "ASSLA FREIGHT INC.", + "service_name": "Standard" + }, + { + "id": "dhlexpress.domestic-express", + "carrier_name": "DHL Express", + "service_name": "Domestic Express" + }, + { + "id": "dhlexpress.domestic-express1030am", + "carrier_name": "DHL Express", + "service_name": "Domestic Express 10:30" + }, + { + "id": "dhlexpress.domestic-express9am", + "carrier_name": "DHL Express", + "service_name": "Domestic Express 9:00" + }, + { + "id": "dhlexpress.economy-select", + "carrier_name": "DHL Express", + "service_name": "Economy Select" + }, + { + "id": "dhlexpress.express-easy", + "carrier_name": "DHL Express", + "service_name": "Express Easy" + }, + { + "id": "dhlexpress.express-worldwide", + "carrier_name": "DHL Express", + "service_name": "Express Worldwide" + }, + { + "id": "dhlexpress.express1030am", + "carrier_name": "DHL Express", + "service_name": "Express 10:30" + }, + { + "id": "dhlexpress.express12pm", + "carrier_name": "DHL Express", + "service_name": "Express 12:00" + }, + { + "id": "dhlexpress.express9am", + "carrier_name": "DHL Express", + "service_name": "Express 9:00" + }, + { + "id": "intelcom.standard", + "carrier_name": "Intelcom", + "service_name": "Standard" + }, + { + "id": "jardinetransport-217.standard", + "carrier_name": "JARDINE TRANSPORT", + "service_name": "Standard" + }, + { + "id": "sutcocontractingltddbasutcotransportationspecialist-552.standard", + "carrier_name": "SUTCO CONTRACTING LTD./DBA SUTCO TRANSPORTATION SPECIALIST", + "service_name": "Standard" + }, + { + "id": "whistler99courier-621.standard", + "carrier_name": "Whistler 99 Courier", + "service_name": "Standard" + }, + { + "id": "apps.intermodal", + "carrier_name": "APPS", + "service_name": "Intermodal" + }, + { + "id": "apps.standard", + "carrier_name": "APPS", + "service_name": "Standard" + }, + { + "id": "dbgtrucking-527.standard", + "carrier_name": "DBG TRUCKING ", + "service_name": "Standard" + }, + { + "id": "deliverytechinc-442.standard", + "carrier_name": "Delivery Tech Inc", + "service_name": "Standard" + }, + { + "id": "hiway.standard", + "carrier_name": "Hi-Way9", + "service_name": "Standard" + }, + { + "id": "speedxtransport-319.standard", + "carrier_name": "SpeedX Transport", + "service_name": "Standard" + }, + { + "id": "alldaystransportltd-449.standard", + "carrier_name": "ALL DAYS TRANSPORT LTD", + "service_name": "Standard" + }, + { + "id": "dhlexpress-230.standard", + "carrier_name": "DHL Express", + "service_name": "Standard" + }, + { + "id": "freightcomfulfilment-429.standard", + "carrier_name": "Freightcom Fulfilment", + "service_name": "Standard" + }, + { + "id": "makfreightlinesltd-422.standard", + "carrier_name": "MAK FREIGHT LINES LTD", + "service_name": "Standard" + }, + { + "id": "nationex.standard", + "carrier_name": "Nationex", + "service_name": "Standard" + }, + { + "id": "pacemarathon-611.standard", + "carrier_name": "Pace Marathon", + "service_name": "Standard" + }, + { + "id": "transprofreightsystemsltd-394.standard", + "carrier_name": "Transpro Freight Systems Ltd", + "service_name": "Standard" + }, + { + "id": "diamonddelivery-275.standard", + "carrier_name": "Diamond Delivery", + "service_name": "Standard" + }, + { + "id": "driverdirect-586.standard", + "carrier_name": "Driver Direct", + "service_name": "Standard" + }, + { + "id": "inetexpress-521.standard", + "carrier_name": "I-Net Express", + "service_name": "Standard" + }, + { + "id": "morneau.standard", + "carrier_name": "Morneau Transport", + "service_name": "Standard" + }, + { + "id": "wtmlogisticsltd-579.standard", + "carrier_name": "WTM LOGISTICS LTD.", + "service_name": "Standard" + }, + { + "id": "ab-courier.canada-1030am", + "carrier_name": "A&B Courier", + "service_name": "Canada 10:30am" + }, + { + "id": "ab-courier.canada-930am", + "carrier_name": "A&B Courier", + "service_name": "Canada 9:30am" + }, + { + "id": "ab-courier.canada-ground", + "carrier_name": "A&B Courier", + "service_name": "Canada Ground" + }, + { + "id": "ab-courier.canada-overnight", + "carrier_name": "A&B Courier", + "service_name": "Canada Overnight" + }, + { + "id": "ab-courier.direct", + "carrier_name": "A&B Courier", + "service_name": "Direct" + }, + { + "id": "ab-courier.four-hour", + "carrier_name": "A&B Courier", + "service_name": "Four Hour" + }, + { + "id": "ab-courier.rush", + "carrier_name": "A&B Courier", + "service_name": "Rush" + }, + { + "id": "ab-courier.sameday", + "carrier_name": "A&B Courier", + "service_name": "Sameday" + }, + { + "id": "ab-courier.usa-ground", + "carrier_name": "A&B Courier", + "service_name": "USA Ground" + }, + { + "id": "daytonfreight-581.standard", + "carrier_name": "Dayton Freight", + "service_name": "Standard" + }, + { + "id": "mtslogisticsint-307.standard", + "carrier_name": "MTS Logistics Int.", + "service_name": "Standard" + }, + { + "id": "quikxtransportationinc-490.standard", + "carrier_name": "Quik X Transportation Inc.", + "service_name": "Standard" + }, + { + "id": "sabbystransportinc-574.standard", + "carrier_name": "Sabby?s Transport Inc ", + "service_name": "Standard" + }, + { + "id": "spring-gds.spring-direct", + "carrier_name": "Spring GDS", + "service_name": "Spring Direct" + }, + { + "id": "spring-gds.spring-gateway-parcel", + "carrier_name": "Spring GDS", + "service_name": "Spring Gateway Parcel" + }, + { + "id": "spring-gds.spring-packet-plus", + "carrier_name": "Spring GDS", + "service_name": "Spring Packet Plus Registered" + }, + { + "id": "spring-gds.spring-packet-tracked", + "carrier_name": "Spring GDS", + "service_name": "Spring Packet Tracked" + }, + { + "id": "spring-gds.spring-packet-untracked", + "carrier_name": "Spring GDS", + "service_name": "Spring Packet Untracked" + }, + { + "id": "lplogisticsinc-622.standard", + "carrier_name": "LP Logistics Inc", + "service_name": "Standard" + }, + { + "id": "pctransport-256.standard", + "carrier_name": "PC Transport", + "service_name": "Standard" + }, + { + "id": "peaktransport-497.standard", + "carrier_name": "PEAK TRANSPORT", + "service_name": "Standard" + }, + { + "id": "polaristransportation-188.standard", + "carrier_name": "Polaris Transportation ", + "service_name": "Standard" + }, + { + "id": "uts-470.standard", + "carrier_name": "UTS ", + "service_name": "Standard" + }, + { + "id": "dhillonsnationalservices-531.standard", + "carrier_name": "DHILLON'S NATIONAL SERVICES", + "service_name": "Standard" + }, + { + "id": "gryphontransportationinc-563.standard", + "carrier_name": "GRYPHON TRANSPORTATION INC.", + "service_name": "Standard" + }, + { + "id": "holmesfreight-346.standard", + "carrier_name": "Holmes Freight", + "service_name": "Standard" + }, + { + "id": "transporttransramexpressinc-370.standard", + "carrier_name": "Transport Transram Express Inc", + "service_name": "Standard" + }, + { + "id": "overlandwestfreightlines-253.standard", + "carrier_name": "Overland West Freight Lines", + "service_name": "Standard" + }, + { + "id": "cbstealthexpressinc-520.standard", + "carrier_name": "C.B. Stealth Express Inc.", + "service_name": "Standard" + }, + { + "id": "geowavelogistics-604.standard", + "carrier_name": "Geo Wave Logistics", + "service_name": "Standard" + }, + { + "id": "heartlandtransportltd-624.standard", + "carrier_name": "Heartland Transport Ltd.", + "service_name": "Standard" + }, + { + "id": "kindersley-courier.standard", + "carrier_name": "Kindersley Transport", + "service_name": "Standard" + }, + { + "id": "diamondtransportlogistics-477.standard", + "carrier_name": "Diamond Transport Logistics", + "service_name": "Standard" + }, + { + "id": "maritime.dry", + "carrier_name": "Maritime", + "service_name": "Dry" + }, + { + "id": "maritime.frozen", + "carrier_name": "Maritime", + "service_name": "Reefer" + }, + { + "id": "maritime.heat", + "carrier_name": "Maritime", + "service_name": "Heat" + }, + { + "id": "proactiftransportinc-460.standard", + "carrier_name": "ProActif Transport Inc.", + "service_name": "Standard" + }, + { + "id": "rightservicerightchoicetransportationandwarehouse-578.standard", + "carrier_name": "RIGHT SERVICE RIGHT CHOICE TRANSPORTATION AND WAREHOUSE", + "service_name": "Standard" + }, + { + "id": "averittexpress-576.standard", + "carrier_name": "Averitt Express", + "service_name": "Standard" + }, + { + "id": "bitzertruckingltd-591.standard", + "carrier_name": "Bitzer Trucking Ltd", + "service_name": "Standard" + }, + { + "id": "cctcanada-211.standard", + "carrier_name": "CCT Canada", + "service_name": "Standard" + }, + { + "id": "centraltransport-427.standard", + "carrier_name": "Central Transport", + "service_name": "Standard" + }, + { + "id": "saraixpresstruckinginc-336.standard", + "carrier_name": "SARAI XPRESS TRUCKING INC", + "service_name": "Standard" + }, + { + "id": "onroutefreightservicesinc-598.standard", + "carrier_name": "ONROUTE FREIGHT SERVICES INC.", + "service_name": "Standard" + }, + { + "id": "ontargettransportation-283.standard", + "carrier_name": "On Target Transportation", + "service_name": "Standard" + }, + { + "id": "sunstarhaulersinc-590.standard", + "carrier_name": "SUNSTAR HAULERS INC.", + "service_name": "Standard" + }, + { + "id": "transportecononord-495.standard", + "carrier_name": "Transport Econo Nord", + "service_name": "Standard" + }, + { + "id": "allspeed-432.standard", + "carrier_name": "All Speed", + "service_name": "Standard" + }, + { + "id": "canedatransport-189.standard", + "carrier_name": "Caneda Transport", + "service_name": "Standard" + }, + { + "id": "globaltranslogisticsltd-464.standard", + "carrier_name": "GLOBAL TRANS & LOGISTICS LTD", + "service_name": "Standard" + }, + { + "id": "holland.guaranteed-330-pm", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed by 3:30 PM" + }, + { + "id": "holland.guaranteed-9-am", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed by 9:00 AM" + }, + { + "id": "holland.guaranteed-day", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Day" + }, + { + "id": "holland.guaranteed-hour", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Hour" + }, + { + "id": "holland.guaranteed-multi-hour", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Multi Hour" + }, + { + "id": "holland.guaranteed-noon", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed by Noon" + }, + { + "id": "holland.guaranteed-weekend", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Weekend" + }, + { + "id": "holland.inter-regional", + "carrier_name": "Holland Freight", + "service_name": "Inter-Regional" + }, + { + "id": "holland.interline", + "carrier_name": "Holland Freight", + "service_name": "Interline" + }, + { + "id": "holland.regional", + "carrier_name": "Holland Freight", + "service_name": "Regional" + }, + { + "id": "westerncanadaexpress-259.standard", + "carrier_name": "Western Canada Express", + "service_name": "Standard" + }, + { + "id": "roadlinkxpress-553.standard", + "carrier_name": "ROAD LINK XPRESS", + "service_name": "Standard" + }, + { + "id": "stishehwaztransportinc-597.standard", + "carrier_name": "STI - Shehwaz Transport Inc.", + "service_name": "Standard" + }, + { + "id": "jbfexpress-430.standard", + "carrier_name": "JBF Express", + "service_name": "Standard" + }, + { + "id": "mjexpress-377.standard", + "carrier_name": "MJ Express", + "service_name": "Standard" + }, + { + "id": "pdfreight-612.standard", + "carrier_name": "PD Freight", + "service_name": "Standard" + }, + { + "id": "riserstransportinc-523.standard", + "carrier_name": "RISERS TRANSPORT INC.", + "service_name": "Standard" + }, + { + "id": "greenwaycarriers-475.standard", + "carrier_name": "GREENWAY CARRIERS ", + "service_name": "Standard" + }, + { + "id": "kimberlytransportltd-327.standard", + "carrier_name": "Kimberly Transport Ltd", + "service_name": "Standard" + }, + { + "id": "kindersleytransport-263.standard", + "carrier_name": "Kindersley Transport", + "service_name": "Standard" + }, + { + "id": "southeasternfreightlines-573.standard", + "carrier_name": "Southeastern Freight Lines", + "service_name": "Standard" + }, + { + "id": "dayton-freight.standard", + "carrier_name": "Dayton Freight", + "service_name": "Standard" + }, + { + "id": "otxlogisticscanadaltd-414.standard", + "carrier_name": "OTX Logistics Canada Ltd", + "service_name": "Standard" + }, + { + "id": "overlandfreightinternational-534.standard", + "carrier_name": "Overland Freight International", + "service_name": "Standard" + }, + { + "id": "westtransautoinc-367.standard", + "carrier_name": "WestTransAuto Inc.", + "service_name": "Standard" + }, + { + "id": "hollandmotorfreight-371.standard", + "carrier_name": "Holland Motor Freight", + "service_name": "Standard" + }, + { + "id": "lowfreightratecaltd-406.standard", + "carrier_name": "LOW FREIGHT RATE.CA LTD", + "service_name": "Standard" + }, + { + "id": "precisiontrucklines-410.standard", + "carrier_name": "PRECISION TRUCK LINES", + "service_name": "Standard" + }, + { + "id": "sewaenterpriseltd-405.standard", + "carrier_name": "SEWA ENTERPRISE LTD", + "service_name": "Standard" + }, + { + "id": "ab-courier-ltl.ltl-direct", + "carrier_name": "A&B Courier", + "service_name": "Direct (Pallet)" + }, + { + "id": "ab-courier-ltl.ltl-rush", + "carrier_name": "A&B Courier", + "service_name": "Rush (Pallet)" + }, + { + "id": "ab-courier-ltl.ltl-sameday", + "carrier_name": "A&B Courier", + "service_name": "Sameday (Pallet)" + }, + { + "id": "bmptransport-318.standard", + "carrier_name": "BMP Transport", + "service_name": "Standard" + }, + { + "id": "courrierplus-494.standard", + "carrier_name": "Courrier Plus", + "service_name": "Standard" + }, + { + "id": "fedexground-426.standard", + "carrier_name": "FedEx Ground", + "service_name": "Standard" + }, + { + "id": "mototransportation-264.standard", + "carrier_name": "Moto Transportation", + "service_name": "Standard" + }, + { + "id": "acecourier-519.standard", + "carrier_name": "ACE Courier", + "service_name": "Standard" + }, + { + "id": "caneda-189.standard", + "carrier_name": "Caneda", + "service_name": "Standard" + }, + { + "id": "expotrans-518.standard", + "carrier_name": "EXPOTRANS", + "service_name": "Standard" + }, + { + "id": "frontlinecarriersystemsinc-496.standard", + "carrier_name": "Frontline Carrier Systems Inc.", + "service_name": "Standard" + }, + { + "id": "frontlinefreight-492.standard", + "carrier_name": "Frontline Freight", + "service_name": "Standard" + }, + { + "id": "nishantransportinc-423.standard", + "carrier_name": "NISHAN TRANSPORT INC.", + "service_name": "Standard" + }, + { + "id": "transamcarriersinc-482.standard", + "carrier_name": "TRANSAM CARRIERS INC", + "service_name": "Standard" + }, + { + "id": "aarontruckingltd-513.standard", + "carrier_name": "AARON TRUCKING LTD", + "service_name": "Standard" + }, + { + "id": "apexmotorexpress-258.standard", + "carrier_name": "Apex Motor Express", + "service_name": "Standard" + }, + { + "id": "comox.standard", + "carrier_name": "Comox Pacific Express", + "service_name": "Standard" + }, + { + "id": "fleet-optics.standard", + "carrier_name": "Fleet Optics", + "service_name": "Standard" + }, + { + "id": "garrymercertrucking-452.standard", + "carrier_name": "Garry Mercer Trucking", + "service_name": "Standard" + }, + { + "id": "hnmlogisticsinc-436.standard", + "carrier_name": "HNM LOGISTICS INC.", + "service_name": "Standard" + }, + { + "id": "smartexpressltd-488.standard", + "carrier_name": "s.m.a.r.t. Express Ltd.", + "service_name": "Standard" + }, + { + "id": "aaacooper-594.standard", + "carrier_name": "AAA Cooper", + "service_name": "Standard" + }, + { + "id": "abcourier-480.standard", + "carrier_name": "A&B Courier", + "service_name": "Standard" + }, + { + "id": "cretransport-287.standard", + "carrier_name": "CRE Transport", + "service_name": "Standard" + }, + { + "id": "fedexexpress-272.standard", + "carrier_name": "FedEx Express", + "service_name": "Standard" + }, + { + "id": "rangefreightwaysltd-448.standard", + "carrier_name": "Range Freightways Ltd.", + "service_name": "Standard" + }, + { + "id": "recalltransportservicesinc-609.standard", + "carrier_name": "Recall Transport Services Inc.", + "service_name": "Standard" + }, + { + "id": "saraixpresstruckinginc-379.standard", + "carrier_name": "Sarai Xpress Trucking Inc", + "service_name": "Standard" + }, + { + "id": "trans2-293.standard", + "carrier_name": "Trans2", + "service_name": "Standard" + }, + { + "id": "coastlineexpress-536.standard", + "carrier_name": "Coastline Express", + "service_name": "Standard" + }, + { + "id": "d4logisticsinc-505.standard", + "carrier_name": "D4 LOGISTICS INC.", + "service_name": "Standard" + }, + { + "id": "exceltransportation-328.standard", + "carrier_name": "Excel Transportation", + "service_name": "Standard" + }, + { + "id": "purolatorcourier.express", + "carrier_name": "Purolator", + "service_name": "Express" + }, + { + "id": "purolatorcourier.express-box", + "carrier_name": "Purolator", + "service_name": "Express Box" + }, + { + "id": "purolatorcourier.express-box-international", + "carrier_name": "Purolator", + "service_name": "Express Box International" + }, + { + "id": "purolatorcourier.express-box1030am", + "carrier_name": "Purolator", + "service_name": "Express Box 10:30 AM" + }, + { + "id": "purolatorcourier.express-box9am", + "carrier_name": "Purolator", + "service_name": "Express Box 9 AM" + }, + { + "id": "purolatorcourier.express-boxUS", + "carrier_name": "Purolator", + "service_name": "Express Box U.S." + }, + { + "id": "purolatorcourier.express-envelope", + "carrier_name": "Purolator", + "service_name": "Express Envelope" + }, + { + "id": "purolatorcourier.express-envelope-international", + "carrier_name": "Purolator", + "service_name": "Express Envelope International" + }, + { + "id": "purolatorcourier.express-envelope-us", + "carrier_name": "Purolator", + "service_name": "Express Envelope U.S." + }, + { + "id": "purolatorcourier.express-envelope1030am", + "carrier_name": "Purolator", + "service_name": "Express Envelope 10:30 AM" + }, + { + "id": "purolatorcourier.express-envelope9am", + "carrier_name": "Purolator", + "service_name": "Express Envelope 9 AM" + }, + { + "id": "purolatorcourier.express-international", + "carrier_name": "Purolator", + "service_name": "Express International" + }, + { + "id": "purolatorcourier.express-pack", + "carrier_name": "Purolator", + "service_name": "Express Pack" + }, + { + "id": "purolatorcourier.express-pack-international", + "carrier_name": "Purolator", + "service_name": "Express Pack International" + }, + { + "id": "purolatorcourier.express-pack-us", + "carrier_name": "Purolator", + "service_name": "Express Pack U.S." + }, + { + "id": "purolatorcourier.express-pack1030am", + "carrier_name": "Purolator", + "service_name": "Express Pack 10:30 AM" + }, + { + "id": "purolatorcourier.express-pack9am", + "carrier_name": "Purolator", + "service_name": "Express Pack 9 AM" + }, + { + "id": "purolatorcourier.express-us", + "carrier_name": "Purolator", + "service_name": "Express U.S." + }, + { + "id": "purolatorcourier.express-us-1030am", + "carrier_name": "Purolator", + "service_name": "Express U.S. 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-9am", + "carrier_name": "Purolator", + "service_name": "Express U.S. 9 AM" + }, + { + "id": "purolatorcourier.express-us-box1030AM", + "carrier_name": "Purolator", + "service_name": "Express U.S. Box 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-box9AM", + "carrier_name": "Purolator", + "service_name": "Express U.S. Box 9 AM" + }, + { + "id": "purolatorcourier.express-us-envelope1030am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Envelope 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-envelope9am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Envelope 9 AM" + }, + { + "id": "purolatorcourier.express-us-pack1030am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Pack 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-pack9am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Pack 9 AM" + }, + { + "id": "purolatorcourier.express1030AM", + "carrier_name": "Purolator", + "service_name": "Express 10:30 AM" + }, + { + "id": "purolatorcourier.express9AM", + "carrier_name": "Purolator", + "service_name": "Express 9 AM" + }, + { + "id": "purolatorcourier.ground", + "carrier_name": "Purolator", + "service_name": "Ground" + }, + { + "id": "purolatorcourier.ground-us", + "carrier_name": "Purolator", + "service_name": "Ground U.S." + }, + { + "id": "purolatorcourier.standard", + "carrier_name": "Purolator", + "service_name": "Standard" + }, + { + "id": "a1delivery-514.standard", + "carrier_name": "A-1 Delivery", + "service_name": "Standard" + }, + { + "id": "fedex-courier.2-day", + "carrier_name": "FedEx Courier", + "service_name": "2-Day" + }, + { + "id": "fedex-courier.2-day-a-m", + "carrier_name": "FedEx Courier", + "service_name": "2-Day AM" + }, + { + "id": "fedex-courier.express-saver", + "carrier_name": "FedEx Courier", + "service_name": "Express Saver" + }, + { + "id": "fedex-courier.first-overnight", + "carrier_name": "FedEx Courier", + "service_name": "First Overnight" + }, + { + "id": "fedex-courier.ground", + "carrier_name": "FedEx Courier", + "service_name": "Ground" + }, + { + "id": "fedex-courier.international-connect-plus", + "carrier_name": "FedEx Courier", + "service_name": "International Connect Plus" + }, + { + "id": "fedex-courier.international-economy", + "carrier_name": "FedEx Courier", + "service_name": "International Economy" + }, + { + "id": "fedex-courier.international-ground", + "carrier_name": "FedEx Courier", + "service_name": "International Ground" + }, + { + "id": "fedex-courier.international-priority", + "carrier_name": "FedEx Courier", + "service_name": "International Priority" + }, + { + "id": "fedex-courier.international-priority-express", + "carrier_name": "FedEx Courier", + "service_name": "International Priority Express" + }, + { + "id": "fedex-courier.overnight", + "carrier_name": "FedEx Courier", + "service_name": "Overnight" + }, + { + "id": "fedex-courier.priority-overnight", + "carrier_name": "FedEx Courier", + "service_name": "Priority Overnight" + }, + { + "id": "fedex-courier.same-day", + "carrier_name": "FedEx Courier", + "service_name": "Same Day" + }, + { + "id": "spadytransportltd-384.standard", + "carrier_name": "SPADY TRANSPORT LTD", + "service_name": "Standard" + }, + { + "id": "tstapi.intermodal", + "carrier_name": "TST", + "service_name": "Intermodal" + }, + { + "id": "tstapi.standard", + "carrier_name": "TST", + "service_name": "Standard" + }, + { + "id": "spanalaska-544.standard", + "carrier_name": "Span Alaska", + "service_name": "Standard" + }, + { + "id": "sunshinelogistics-321.standard", + "carrier_name": "Sunshine Logistics", + "service_name": "Standard" + }, + { + "id": "yellowlogistics-525.standard", + "carrier_name": "Yellow Logistics", + "service_name": "Standard" + }, + { + "id": "abffreight-455.standard", + "carrier_name": "ABF Freight", + "service_name": "Standard" + }, + { + "id": "fastexact-585.standard", + "carrier_name": "Fast Exact", + "service_name": "Standard" + }, + { + "id": "gardewinegroupinc-424.standard", + "carrier_name": "Gardewine Group Inc.", + "service_name": "Standard" + }, + { + "id": "saia.standard", + "carrier_name": "Saia Motor Freight", + "service_name": "Standard" + }, + { + "id": "roadridertransportltd-417.standard", + "carrier_name": "ROAD RIDER Transport Ltd", + "service_name": "Standard" + }, + { + "id": "cct.expedited", + "carrier_name": "CCT", + "service_name": "Expedited" + }, + { + "id": "cct.intermodal", + "carrier_name": "CCT", + "service_name": "Intermodal" + }, + { + "id": "dependablehawaiianexpress-567.standard", + "carrier_name": "Dependable Hawaiian Express", + "service_name": "Standard" + }, + { + "id": "interpacifictransport-457.standard", + "carrier_name": "Inter-Pacific Transport", + "service_name": "Standard" + }, + { + "id": "oneforfreight-481.standard", + "carrier_name": "ONE For Freight", + "service_name": "Standard" + }, + { + "id": "seawayexpress-431.standard", + "carrier_name": "Seaway Express", + "service_name": "Standard" + }, + { + "id": "allpointsfreightinc-546.standard", + "carrier_name": "ALL POINTS FREIGHT INC.", + "service_name": "Standard" + }, + { + "id": "groupelafrance-434.standard", + "carrier_name": "Groupe Lafrance", + "service_name": "Standard" + }, + { + "id": "hiltontransportation-317.standard", + "carrier_name": "Hilton Transportation", + "service_name": "Standard" + }, + { + "id": "locomoteexpress-538.standard", + "carrier_name": "Locomote Express", + "service_name": "Standard" + }, + { + "id": "sendr-603.standard", + "carrier_name": "SENDR", + "service_name": "Standard" + }, + { + "id": "airinuitcargo-539.standard", + "carrier_name": "Air Inuit Cargo", + "service_name": "Standard" + }, + { + "id": "cmttransportinc-628.standard", + "carrier_name": "C M T TRANSPORT INC.", + "service_name": "Standard" + }, + { + "id": "galaxyfreightline-221.standard", + "carrier_name": "Galaxy Freightline", + "service_name": "Standard" + }, + { + "id": "purolatorfreight-577.standard", + "carrier_name": "Purolator Freight", + "service_name": "Standard" + }, + { + "id": "mcdispatch-467.standard", + "carrier_name": "MC Dispatch", + "service_name": "Standard" + }, + { + "id": "midlandtransport-437.standard", + "carrier_name": "Midland Transport", + "service_name": "Standard" + }, + { + "id": "dukesfreightservices-617.standard", + "carrier_name": "Dukes Freight Services", + "service_name": "Standard" + }, + { + "id": "frontiersupplychainsolutions-451.standard", + "carrier_name": "Frontier Supply Chain Solutions", + "service_name": "Standard" + }, + { + "id": "gls-freight.ground", + "carrier_name": "GLS Freight", + "service_name": "Ground" + }, + { + "id": "loadkingtransportinc-385.standard", + "carrier_name": "LOAD KING TRANSPORT INC", + "service_name": "Standard" + }, + { + "id": "dayrossfreightcanada-559.standard", + "carrier_name": "Day & Ross Freight | Canada", + "service_name": "Standard" + }, + { + "id": "gillcologistics-601.standard", + "carrier_name": "Gillco Logistics", + "service_name": "Standard" + }, + { + "id": "reddaway-402.standard", + "carrier_name": "Reddaway", + "service_name": "Standard" + }, + { + "id": "xpo.standard", + "carrier_name": "XPO", + "service_name": "Standard" + }, + { + "id": "lodextransportltd-572.standard", + "carrier_name": "LODEX TRANSPORT LTD", + "service_name": "Standard" + }, + { + "id": "moto.standard", + "carrier_name": "Moto Transportation Services Corp", + "service_name": "Standard" + }, + { + "id": "schneidernational-501.standard", + "carrier_name": "Schneider National", + "service_name": "Standard" + }, + { + "id": "glsfreight-186.standard", + "carrier_name": "GLS Freight", + "service_name": "Standard" + }, + { + "id": "loadlandlogisticsinc-607.standard", + "carrier_name": "LOAD LAND LOGISTICS INC.", + "service_name": "Standard" + }, + { + "id": "pacificcoastexpress-373.standard", + "carrier_name": "Pacific Coast Express", + "service_name": "Standard" + }, + { + "id": "purolatorcourier-401.standard", + "carrier_name": "Purolator Courier", + "service_name": "Standard" + }, + { + "id": "albrighttruckinginc-454.standard", + "carrier_name": "Albright Trucking Inc.", + "service_name": "Standard" + }, + { + "id": "beyondtransportation-285.standard", + "carrier_name": "Beyond Transportation", + "service_name": "Standard" + }, + { + "id": "dinkaenterprises-630.standard", + "carrier_name": "DINKA Enterprises", + "service_name": "Standard" + }, + { + "id": "gls-us.am-select-8a-12p", + "carrier_name": "GLS US", + "service_name": "AM Select 8a-12p" + }, + { + "id": "gls-us.early-priority-overnight", + "carrier_name": "GLS US", + "service_name": "Early Priority Overnight" + }, + { + "id": "gls-us.early-saturday-delivery", + "carrier_name": "GLS US", + "service_name": "Early Saturday Delivery" + }, + { + "id": "gls-us.evening-select-4p-8p", + "carrier_name": "GLS US", + "service_name": "Evening Select 4p-8p" + }, + { + "id": "gls-us.gls-ground", + "carrier_name": "GLS US", + "service_name": "GLS Ground" + }, + { + "id": "gls-us.noon-priority-overnight-sds–saturday-delivery", + "carrier_name": "GLS US", + "service_name": "Noon Priority Overnight SDS – Saturday Delivery" + }, + { + "id": "gls-us.pm-select-12p-4p", + "carrier_name": "GLS US", + "service_name": "PM Select 12p-4p" + }, + { + "id": "gls-us.priority-overnight", + "carrier_name": "GLS US", + "service_name": "Priority Overnight" + }, + { + "id": "gls-us.saturday-delivery", + "carrier_name": "GLS US", + "service_name": "Saturday Delivery" + }, + { + "id": "wsbellcartage-584.standard", + "carrier_name": "W.S. Bell Cartage", + "service_name": "Standard" + }, + { + "id": "manitoulintransport-440.standard", + "carrier_name": "Manitoulin Transport", + "service_name": "Standard" + }, + { + "id": "arbaztransportincdbakrgtransport-415.standard", + "carrier_name": "ARBAZ TRANSPORT INC. DBA KRG TRANSPORT", + "service_name": "Standard" + }, + { + "id": "garantlogisticsltd-548.standard", + "carrier_name": "GARANT LOGISTICS LTD", + "service_name": "Standard" + }, + { + "id": "highlightmotorgroup-542.standard", + "carrier_name": "HIGHLIGHT MOTOR GROUP", + "service_name": "Standard" + }, + { + "id": "kaynortransport-508.standard", + "carrier_name": "KAYNOR TRANSPORT", + "service_name": "Standard" + }, + { + "id": "rpmtransit-356.standard", + "carrier_name": "RPM Transit", + "service_name": "Standard" + }, + { + "id": "bestbaylogistics-532.standard", + "carrier_name": "BEST BAY LOGISTICS", + "service_name": "Standard" + }, + { + "id": "csatransportation-191.standard", + "carrier_name": "CSA Transportation", + "service_name": "Standard" + }, + { + "id": "himmatlogistics-587.standard", + "carrier_name": "HIMMAT LOGISTICS", + "service_name": "Standard" + }, + { + "id": "pacificnorthwestfreightsytems-560.standard", + "carrier_name": "Pacific Northwest Freight Sytems", + "service_name": "Standard" + }, + { + "id": "bowlinggreenlogistics-466.standard", + "carrier_name": "BOWLING GREEN LOGISTICS", + "service_name": "Standard" + }, + { + "id": "eknaamshippingcorp-512.standard", + "carrier_name": "EK NAAM SHIPPING CORP.", + "service_name": "Standard" + }, + { + "id": "frontline.standard", + "carrier_name": "Frontline", + "service_name": "Standard" + }, + { + "id": "jmtransitinc-439.standard", + "carrier_name": "J.M. Transit Inc.", + "service_name": "Standard" + }, + { + "id": "midland.econoline", + "carrier_name": "MidLand Transport", + "service_name": "Econo Line" + }, + { + "id": "midland.standard", + "carrier_name": "MidLand Transport", + "service_name": "Standard" + }, + { + "id": "mjexpress-380.standard", + "carrier_name": "MJ Express", + "service_name": "Standard" + }, + { + "id": "robusttransportservicesltd-479.standard", + "carrier_name": "ROBUST TRANSPORT SERVICES LTD", + "service_name": "Standard" + }, + { + "id": "aonetransport2007ltd-625.standard", + "carrier_name": "A-One Transport (2007) Ltd.", + "service_name": "Standard" + }, + { + "id": "atlaslogistics-262.standard", + "carrier_name": "Atlas Logistics", + "service_name": "Standard" + }, + { + "id": "gurshanlogistics-486.standard", + "carrier_name": "Gurshan Logistics", + "service_name": "Standard" + }, + { + "id": "jdtransportltd-456.standard", + "carrier_name": "J.D.TRANSPORT LTD", + "service_name": "Standard" + }, + { + "id": "rollsright.standard", + "carrier_name": "Rollsright", + "service_name": "Standard" + }, + { + "id": "speedy.standard", + "carrier_name": "Speedy", + "service_name": "Standard" + }, + { + "id": "ettransport-337.standard", + "carrier_name": "E.T. Transport", + "service_name": "Standard" + }, + { + "id": "fedexfreight-154.standard", + "carrier_name": "FedEx Freight", + "service_name": "Standard" + }, + { + "id": "tstcfexpresscanada-282.standard", + "carrier_name": "TST-CF Express | Canada", + "service_name": "Standard" + }, + { + "id": "suntransportationsystems-476.standard", + "carrier_name": "Sun Transportation Systems", + "service_name": "Standard" + }, + { + "id": "universallogisticssolution-517.standard", + "carrier_name": "UNIVERSAL LOGISTICS SOLUTION", + "service_name": "Standard" + }, + { + "id": "apex.standard", + "carrier_name": "Apex", + "service_name": "Standard" + }, + { + "id": "dayrossfreightcanada-133.standard", + "carrier_name": "Day & Ross Freight | Canada", + "service_name": "Standard" + }, + { + "id": "indocanadiancarriers-386.standard", + "carrier_name": "Indo Canadian Carriers", + "service_name": "Standard" + }, + { + "id": "stitransport-250.standard", + "carrier_name": "STI Transport", + "service_name": "Standard" + }, + { + "id": "stallion.apc-priority-worldwide", + "carrier_name": "Stallion", + "service_name": "APC Priority Worldwide" + }, + { + "id": "stallion.apc-priority-worldwide-tracked", + "carrier_name": "Stallion", + "service_name": "APC Priority Worldwide Tracked" + }, + { + "id": "stallion.economy-usa", + "carrier_name": "Stallion", + "service_name": "Stallion Economy USA" + }, + { + "id": "stallion.express", + "carrier_name": "Stallion", + "service_name": "Stallion Express" + }, + { + "id": "stallion.usps-express-mail", + "carrier_name": "Stallion", + "service_name": "USPS Express Mail" + }, + { + "id": "stallion.usps-first-class-mail", + "carrier_name": "Stallion", + "service_name": "USPS First Class Mail" + }, + { + "id": "stallion.usps-library-mail", + "carrier_name": "Stallion", + "service_name": "USPS Library Mail" + }, + { + "id": "stallion.usps-media-mail", + "carrier_name": "Stallion", + "service_name": "USPS Media Mail" + }, + { + "id": "stallion.usps-parcel-select-ground", + "carrier_name": "Stallion", + "service_name": "USPS Parcel Select Ground" + }, + { + "id": "stallion.usps-priority-mail", + "carrier_name": "Stallion", + "service_name": "USPS Priority Mail" + }, + { + "id": "stallion.usps-priority-mail-express", + "carrier_name": "Stallion", + "service_name": "USPS Priority Mail Express" + }, + { + "id": "transkid.standard", + "carrier_name": "Transkid", + "service_name": "Standard" + }, + { + "id": "versacold-438.standard", + "carrier_name": "VersaCold", + "service_name": "Standard" + }, + { + "id": "vttranssolutionsinc-472.standard", + "carrier_name": "VT TRANS SOLUTIONS INC", + "service_name": "Standard" + }, + { + "id": "bestwaycartage-355.standard", + "carrier_name": "BestWay Cartage", + "service_name": "Standard" + }, + { + "id": "commanderwesttrucking-582.standard", + "carrier_name": "Commander West Trucking", + "service_name": "Standard" + }, + { + "id": "roundthelakesmotorexpress-233.standard", + "carrier_name": "Round the Lakes Motor Express", + "service_name": "Standard" + }, + { + "id": "trafalgarsupplyco-511.standard", + "carrier_name": "Trafalgar Supply Co. ", + "service_name": "Standard" + }, + { + "id": "sunburytransportlimited-478.standard", + "carrier_name": "SUNBURY TRANSPORT LIMITED", + "service_name": "Standard" + }, + { + "id": "winniefreight-549.standard", + "carrier_name": "Winnie Freight", + "service_name": "Standard" + }, + { + "id": "gladiatorriggs-483.standard", + "carrier_name": "GLADIATOR RIGGS", + "service_name": "Standard" + }, + { + "id": "hewingstransportationinc-515.standard", + "carrier_name": "Hewings Transportation Inc.", + "service_name": "Standard" + }, + { + "id": "kbdtransportation-420.standard", + "carrier_name": "KBD TRANSPORTATION ", + "service_name": "Standard" + }, + { + "id": "mopallet.standard", + "carrier_name": "Maritime ", + "service_name": "Pallet Program" + }, + { + "id": "transcomax-504.standard", + "carrier_name": "TranscoMAX", + "service_name": "Standard" + }, + { + "id": "uniteddhillontrucklinesudtl-600.standard", + "carrier_name": "UNITED DHILLON TRUCK LINES (UDTL)", + "service_name": "Standard" + }, + { + "id": "atripcodeliveryservice-279.standard", + "carrier_name": "Atripco Delivery Service", + "service_name": "Standard" + }, + { + "id": "interloadtruckserviceltd-569.standard", + "carrier_name": "INTERLOAD TRUCK SERVICE LTD.", + "service_name": "Standard" + }, + { + "id": "kindersley.expedited", + "carrier_name": "Kindersley", + "service_name": "Expedited" + }, + { + "id": "kindersley.intermodal", + "carrier_name": "Kindersley", + "service_name": "Intermodal" + }, + { + "id": "kindersley.standard", + "carrier_name": "Kindersley", + "service_name": "Regular" + }, + { + "id": "polarisweb.standard", + "carrier_name": "Polaris FPP", + "service_name": "Pallet Program" + }, + { + "id": "alainnormandtransportinc-595.standard", + "carrier_name": "ALAIN NORMAND TRANSPORT INC.", + "service_name": "Standard" + }, + { + "id": "ariesgloballogisticsinc-135.standard", + "carrier_name": "Aries Global Logistics Inc", + "service_name": "Standard" + }, + { + "id": "dhillontransport-550.standard", + "carrier_name": "Dhillon Transport", + "service_name": "Standard" + }, + { + "id": "springcreekcarriersinc-291.standard", + "carrier_name": "Spring Creek Carriers Inc", + "service_name": "Standard" + }, + { + "id": "ilclogistics-315.standard", + "carrier_name": "ILC Logistics", + "service_name": "Standard" + }, + { + "id": "transontarioexpress-248.standard", + "carrier_name": "Trans-Ontario Express", + "service_name": "Standard" + }, + { + "id": "yrc.accelerated", + "carrier_name": "YRC", + "service_name": "Accelerated" + }, + { + "id": "yrc.freight-canada-to-us", + "carrier_name": "YRC", + "service_name": "Canada to US" + }, + { + "id": "yrc.freight-dedicated-equipment", + "carrier_name": "YRC", + "service_name": "Dedicated Equipment" + }, + { + "id": "yrc.standard", + "carrier_name": "YRC", + "service_name": "Standard" + }, + { + "id": "yrc.time-critical-by-5pm", + "carrier_name": "YRC", + "service_name": "Critical by 5 PM" + }, + { + "id": "yrc.time-critical-by-afternoon", + "carrier_name": "YRC", + "service_name": "Critical by Afternoon" + }, + { + "id": "yrc.time-critical-fastest-ground", + "carrier_name": "YRC", + "service_name": "Critical Fastest Ground" + }, + { + "id": "yrc.time-critical-hour-window", + "carrier_name": "YRC", + "service_name": "Critical Hour Window" + }, + { + "id": "b2bfreightwayinc-605.standard", + "carrier_name": "B2B Freightway Inc.", + "service_name": "Standard" + }, + { + "id": "caribootruckterminalsltd-616.standard", + "carrier_name": "Cariboo Truck Terminals Ltd", + "service_name": "Standard" + }, + { + "id": "eximlogisticsinc-421.standard", + "carrier_name": "ExIm Logistics Inc.", + "service_name": "Standard" + }, + { + "id": "ics.ground", + "carrier_name": "ICS", + "service_name": "Ground" + }, + { + "id": "ics.next-day", + "carrier_name": "ICS", + "service_name": "Next day" + }, + { + "id": "tstcfexpresssaia-185.standard", + "carrier_name": "TST-CF Express | SAIA", + "service_name": "Standard" + }, + { + "id": "comoxpacificexpress-257.standard", + "carrier_name": "Comox Pacific Express", + "service_name": "Standard" + }, + { + "id": "galaxyfreightlineinc-183.standard", + "carrier_name": "Galaxy Freightline Inc", + "service_name": "Standard" + }, + { + "id": "samoyedtransport-602.standard", + "carrier_name": "Samoyed Transport", + "service_name": "Standard" + }, + { + "id": "sprinterdeliveryltd-522.standard", + "carrier_name": "Sprinter Delivery Ltd.", + "service_name": "Standard" + }, + { + "id": "gtboltoninc-491.standard", + "carrier_name": "G.T. BOLTON INC.", + "service_name": "Standard" + }, + { + "id": "polarisdirect.standard", + "carrier_name": "Polaris", + "service_name": "Direct" + }, + { + "id": "ups.3day-select", + "carrier_name": "UPS", + "service_name": "3 Day Select" + }, + { + "id": "ups.expedited", + "carrier_name": "UPS", + "service_name": "Expedited" + }, + { + "id": "ups.express", + "carrier_name": "UPS", + "service_name": "Express" + }, + { + "id": "ups.express-early", + "carrier_name": "UPS", + "service_name": "Express Early" + }, + { + "id": "ups.express-saver", + "carrier_name": "UPS", + "service_name": "Express Saver" + }, + { + "id": "ups.ground", + "carrier_name": "UPS", + "service_name": "Ground" + }, + { + "id": "ups.standard", + "carrier_name": "UPS", + "service_name": "Standard" + }, + { + "id": "ups.worldwide-expedited", + "carrier_name": "UPS", + "service_name": "Worldwide Expedited" + }, + { + "id": "ups.worldwide-express", + "carrier_name": "UPS", + "service_name": "Worldwide Express" + }, + { + "id": "ups.worldwide-express-plus", + "carrier_name": "UPS", + "service_name": "Worldwide Express Plus" + }, + { + "id": "ups.worldwide-express-saver", + "carrier_name": "UPS", + "service_name": "Worldwide Express Saver" + }, + { + "id": "argustransportcanada-463.standard", + "carrier_name": "ARGUS Transport Canada", + "service_name": "Standard" + }, + { + "id": "crosscountryfreightsolutions-571.standard", + "carrier_name": "CrossCountry Freight Solutions", + "service_name": "Standard" + }, + { + "id": "geysertransportltd-606.standard", + "carrier_name": "Geyser Transport Ltd", + "service_name": "Standard" + }, + { + "id": "greysertransportltd-606.standard", + "carrier_name": "Greyser Transport Ltd", + "service_name": "Standard" + }, + { + "id": "steelestransportationgroup-580.standard", + "carrier_name": "Steele's Transportation Group", + "service_name": "Standard" + }, + { + "id": "titantranslineinc-450.standard", + "carrier_name": "Titan Transline Inc.", + "service_name": "Standard" + }, + { + "id": "2stopdelivery-393.standard", + "carrier_name": "2 STOP DELIVERY", + "service_name": "Standard" + }, + { + "id": "aduiepyleinc-589.standard", + "carrier_name": "A Duie Pyle, Inc", + "service_name": "Standard" + }, + { + "id": "centralislanddistributors-554.standard", + "carrier_name": "Central Island Distributors", + "service_name": "Standard" + }, + { + "id": "minimaxexpress-418.standard", + "carrier_name": "Minimax Express", + "service_name": "Standard" + }, + { + "id": "dayrosscommerce-266.standard", + "carrier_name": "Day & Ross Commerce", + "service_name": "Standard" + }, + { + "id": "highlightmotorgroup-500.standard", + "carrier_name": "HIGHLIGHT MOTOR GROUP", + "service_name": "Standard" + }, + { + "id": "internordtransportation-461.standard", + "carrier_name": "Inter-Nord Transportation", + "service_name": "Standard" + }, + { + "id": "westmancourier-419.standard", + "carrier_name": "Westman Courier", + "service_name": "Standard" + } + ], + "DEV_SERVICES": [ + { + "id": "kindersley-freight.domestic-expedited", + "carrier_name": "Kindersley Transport", + "service_name": "Domestic Expedited" + }, + { + "id": "kindersley-freight.domestic-rail", + "carrier_name": "Kindersley Transport", + "service_name": "Domestic Rail" + }, + { + "id": "kindersley-freight.domestic-road", + "carrier_name": "Kindersley Transport", + "service_name": "Domestic Road" + }, + { + "id": "kindersley-freight.transborder", + "carrier_name": "Kindersley Transport", + "service_name": "Transborder" + }, + { + "id": "newpennmotorexpress-445.standard", + "carrier_name": "New Penn Motor Express", + "service_name": "Standard" + }, + { + "id": "a10cD2MfJjiOCcRejjgv3cHMyRcRBhE3.standard", + "carrier_name": "Bill's Spot Carrier", + "service_name": "Standard" + }, + { + "id": "apps.intermodal", + "carrier_name": "APPS", + "service_name": "Intermodal" + }, + { + "id": "apps.standard", + "carrier_name": "APPS", + "service_name": "Standard" + }, + { + "id": "dayrosscommerce-266.standard", + "carrier_name": "Day & Ross Commerce", + "service_name": "Standard" + }, + { + "id": "fedex-courier.2-day", + "carrier_name": "FedEx Courier", + "service_name": "2-Day" + }, + { + "id": "fedex-courier.2-day-a-m", + "carrier_name": "FedEx Courier", + "service_name": "2-Day AM" + }, + { + "id": "fedex-courier.express-saver", + "carrier_name": "FedEx Courier", + "service_name": "Express Saver" + }, + { + "id": "fedex-courier.first-overnight", + "carrier_name": "FedEx Courier", + "service_name": "First Overnight" + }, + { + "id": "fedex-courier.ground", + "carrier_name": "FedEx Courier", + "service_name": "Ground" + }, + { + "id": "fedex-courier.international-connect-plus", + "carrier_name": "FedEx Courier", + "service_name": "International Connect Plus" + }, + { + "id": "fedex-courier.international-economy", + "carrier_name": "FedEx Courier", + "service_name": "International Economy" + }, + { + "id": "fedex-courier.international-ground", + "carrier_name": "FedEx Courier", + "service_name": "International Ground" + }, + { + "id": "fedex-courier.international-priority", + "carrier_name": "FedEx Courier", + "service_name": "International Priority" + }, + { + "id": "fedex-courier.international-priority-express", + "carrier_name": "FedEx Courier", + "service_name": "International Priority Express" + }, + { + "id": "fedex-courier.overnight", + "carrier_name": "FedEx Courier", + "service_name": "Overnight" + }, + { + "id": "fedex-courier.priority-overnight", + "carrier_name": "FedEx Courier", + "service_name": "Priority Overnight" + }, + { + "id": "fedex-courier.same-day", + "carrier_name": "FedEx Courier", + "service_name": "Same Day" + }, + { + "id": "fedexfreight-154.standard", + "carrier_name": "FedEx Freight", + "service_name": "Standard" + }, + { + "id": "gsm.air-skip", + "carrier_name": "GTA GSM", + "service_name": "AirSkip" + }, + { + "id": "gsm.air-skip-eco", + "carrier_name": "GTA GSM", + "service_name": "AirSkipEco" + }, + { + "id": "gsm.air-skip-plus", + "carrier_name": "GTA GSM", + "service_name": "AirSkip+" + }, + { + "id": "gsm.armed-secure-air", + "carrier_name": "GTA GSM", + "service_name": "Armed Secure Air" + }, + { + "id": "gsm.armed-secure-ground", + "carrier_name": "GTA GSM", + "service_name": "Armed Secure Ground" + }, + { + "id": "gsm.ground", + "carrier_name": "GTA GSM", + "service_name": "Ground" + }, + { + "id": "gsm.secure-air", + "carrier_name": "GTA GSM", + "service_name": "Secure Air" + }, + { + "id": "gsm.secure-ground", + "carrier_name": "GTA GSM", + "service_name": "Secure Ground" + }, + { + "id": "gsm.zone-skip", + "carrier_name": "GTA GSM", + "service_name": "ZoneSkip" + }, + { + "id": "gsm.zone-skip-plus", + "carrier_name": "GTA GSM", + "service_name": "ZoneSkip+" + }, + { + "id": "dhlexpress.domestic-express", + "carrier_name": "DHL Express", + "service_name": "Domestic Express" + }, + { + "id": "dhlexpress.domestic-express1030am", + "carrier_name": "DHL Express", + "service_name": "Domestic Express 10:30" + }, + { + "id": "dhlexpress.domestic-express9am", + "carrier_name": "DHL Express", + "service_name": "Domestic Express 9:00" + }, + { + "id": "dhlexpress.economy-select", + "carrier_name": "DHL Express", + "service_name": "Economy Select" + }, + { + "id": "dhlexpress.express-easy", + "carrier_name": "DHL Express", + "service_name": "Express Easy" + }, + { + "id": "dhlexpress.express-worldwide", + "carrier_name": "DHL Express", + "service_name": "Express Worldwide" + }, + { + "id": "dhlexpress.express1030am", + "carrier_name": "DHL Express", + "service_name": "Express 10:30" + }, + { + "id": "dhlexpress.express12pm", + "carrier_name": "DHL Express", + "service_name": "Express 12:00" + }, + { + "id": "dhlexpress.express9am", + "carrier_name": "DHL Express", + "service_name": "Express 9:00" + }, + { + "id": "nin.next-day", + "carrier_name": "NIN", + "service_name": "Next Day" + }, + { + "id": "nin.same-day", + "carrier_name": "NIN", + "service_name": "Same Day" + }, + { + "id": "one.standard", + "carrier_name": "ONE Transportation", + "service_name": "Standard" + }, + { + "id": "rollsright.standard", + "carrier_name": "Rollsright", + "service_name": "Standard" + }, + { + "id": "stallion.apc-priority-worldwide", + "carrier_name": "Stallion", + "service_name": "APC Priority Worldwide" + }, + { + "id": "stallion.apc-priority-worldwide-tracked", + "carrier_name": "Stallion", + "service_name": "APC Priority Worldwide Tracked" + }, + { + "id": "stallion.economy-usa", + "carrier_name": "Stallion", + "service_name": "Stallion Economy USA" + }, + { + "id": "stallion.express", + "carrier_name": "Stallion", + "service_name": "Stallion Express" + }, + { + "id": "stallion.usps-express-mail", + "carrier_name": "Stallion", + "service_name": "USPS Express Mail" + }, + { + "id": "stallion.usps-first-class-mail", + "carrier_name": "Stallion", + "service_name": "USPS First Class Mail" + }, + { + "id": "stallion.usps-library-mail", + "carrier_name": "Stallion", + "service_name": "USPS Library Mail" + }, + { + "id": "stallion.usps-media-mail", + "carrier_name": "Stallion", + "service_name": "USPS Media Mail" + }, + { + "id": "stallion.usps-parcel-select-ground", + "carrier_name": "Stallion", + "service_name": "USPS Parcel Select Ground" + }, + { + "id": "stallion.usps-priority-mail", + "carrier_name": "Stallion", + "service_name": "USPS Priority Mail" + }, + { + "id": "stallion.usps-priority-mail-express", + "carrier_name": "Stallion", + "service_name": "USPS Priority Mail Express" + }, + { + "id": "wuPUFbL2xJpG1vd4jHDl0vaXiXZ99WO4.standard", + "carrier_name": "test manager add", + "service_name": "Standard" + }, + { + "id": "apexmotorexpress-258.standard", + "carrier_name": "Apex Motor Express", + "service_name": "Standard" + }, + { + "id": "bettertrucks.ddu", + "carrier_name": "Better Trucks", + "service_name": "DDU" + }, + { + "id": "bettertrucks.express", + "carrier_name": "Better Trucks", + "service_name": "Express" + }, + { + "id": "bettertrucks.next_day", + "carrier_name": "Better Trucks", + "service_name": "Next Day" + }, + { + "id": "bettertrucks.same_day", + "carrier_name": "Better Trucks", + "service_name": "Same Day" + }, + { + "id": "IQ1rjQyWY8EflOBKVyqGM1syqer1O65V.standard", + "carrier_name": "Carrier Ben", + "service_name": "Standard" + }, + { + "id": "kindersley.expedited", + "carrier_name": "Kindersley", + "service_name": "Expedited" + }, + { + "id": "kindersley.intermodal", + "carrier_name": "Kindersley", + "service_name": "Intermodal" + }, + { + "id": "kindersley.standard", + "carrier_name": "Kindersley", + "service_name": "Regular" + }, + { + "id": "speedy.standard", + "carrier_name": "Speedy", + "service_name": "Standard" + }, + { + "id": "vitran.maxx", + "carrier_name": "Vitran", + "service_name": "Maxx" + }, + { + "id": "vitran.priority", + "carrier_name": "Vitran", + "service_name": "Priority" + }, + { + "id": "vitran.regular", + "carrier_name": "Vitran", + "service_name": "Regular" + }, + { + "id": "c5itKPJ6v6s4cmHEhjMDbbp9XD5lKoPR.standard", + "carrier_name": "Bill's Truck Shop", + "service_name": "Standard" + }, + { + "id": "caledoncouriers-294.standard", + "carrier_name": "Caledon Couriers", + "service_name": "Standard" + }, + { + "id": "dayton-freight.standard", + "carrier_name": "Dayton Freight", + "service_name": "Standard" + }, + { + "id": "dj9Lv4FUhkBIG7tdKiWh4n3U2lP2Drc5.standard", + "carrier_name": "testNewCarrierGar", + "service_name": "Standard" + }, + { + "id": "hiway.standard", + "carrier_name": "Hi-Way9", + "service_name": "Standard" + }, + { + "id": "boxknight.next-day", + "carrier_name": "BoxKnight", + "service_name": "Next Day" + }, + { + "id": "boxknight.sameday", + "carrier_name": "BoxKnight", + "service_name": "Same Day" + }, + { + "id": "cct.expedited", + "carrier_name": "CCT", + "service_name": "Expedited" + }, + { + "id": "cct.intermodal", + "carrier_name": "CCT", + "service_name": "Intermodal" + }, + { + "id": "peglobal-511.standard", + "carrier_name": "PE Global", + "service_name": "Standard" + }, + { + "id": "polarisdirect.standard", + "carrier_name": "Polaris", + "service_name": "Direct" + }, + { + "id": "billatransport-203.standard", + "carrier_name": "Billa Transport", + "service_name": "Standard" + }, + { + "id": "purolatorfreight-151.standard", + "carrier_name": "Purolator Freight ", + "service_name": "Standard" + }, + { + "id": "wce.standard", + "carrier_name": "WCE", + "service_name": "Intermodal" + }, + { + "id": "ajWA9sU9dV6U6oSB5GrokBvlzfV2RRf7.standard", + "carrier_name": "Garima-test", + "service_name": "Standard" + }, + { + "id": "c19h151C0I4Sdnp3Mqt0jRLxjTcNtksA.standard", + "carrier_name": "BinduCarrier", + "service_name": "Standard" + }, + { + "id": "FzXhDtSYDgMYP97Zi28GgU4j8QNXBllS.standard", + "carrier_name": "Apex-SPOT", + "service_name": "Standard" + }, + { + "id": "holland.guaranteed-330-pm", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed by 3:30 PM" + }, + { + "id": "holland.guaranteed-9-am", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed by 9:00 AM" + }, + { + "id": "holland.guaranteed-day", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Day" + }, + { + "id": "holland.guaranteed-hour", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Hour" + }, + { + "id": "holland.guaranteed-multi-hour", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Multi Hour" + }, + { + "id": "holland.guaranteed-noon", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed by Noon" + }, + { + "id": "holland.guaranteed-weekend", + "carrier_name": "Holland Freight", + "service_name": "Guaranteed Weekend" + }, + { + "id": "holland.inter-regional", + "carrier_name": "Holland Freight", + "service_name": "Inter-Regional" + }, + { + "id": "holland.interline", + "carrier_name": "Holland Freight", + "service_name": "Interline" + }, + { + "id": "holland.regional", + "carrier_name": "Holland Freight", + "service_name": "Regional" + }, + { + "id": "LfT69HBpfJrjS9wv0tkFVylVxcMwWIVt.standard", + "carrier_name": "test create 2", + "service_name": "Standard" + }, + { + "id": "mopallet.standard", + "carrier_name": "Maritime ", + "service_name": "Pallet Program" + }, + { + "id": "bgxtransportation-361.standard", + "carrier_name": "BGX Transportation", + "service_name": "Standard" + }, + { + "id": "ei8AJgRFI3Xslob8UmFawLq71jhlKyZX.standard", + "carrier_name": "Service Test", + "service_name": "Standard" + }, + { + "id": "vankam.standard", + "carrier_name": "Vankam", + "service_name": "Standard" + }, + { + "id": "AbqB0FuehDpOtTxHzhhEvBs8CRJ44Z2I.standard", + "carrier_name": "Manager Carrier", + "service_name": "Standard" + }, + { + "id": "bbWZeWwm92b0eyQBYnRNT5PUJb7vslCY.standard", + "carrier_name": "1Manager", + "service_name": "Standard" + }, + { + "id": "dhl-ecomm.packet-international", + "carrier_name": "DHL eCommerce", + "service_name": "Package International" + }, + { + "id": "dhl-ecomm.parcel-expedited", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel Expedited" + }, + { + "id": "dhl-ecomm.parcel-expedited-max", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel Expedited Max" + }, + { + "id": "dhl-ecomm.parcel-ground", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel Ground" + }, + { + "id": "dhl-ecomm.parcel-international-direct", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Direct" + }, + { + "id": "dhl-ecomm.parcel-international-direct-priority", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Direct Priority" + }, + { + "id": "dhl-ecomm.parcel-international-direct-standard", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Direct Standard" + }, + { + "id": "dhl-ecomm.parcel-international-standard", + "carrier_name": "DHL eCommerce", + "service_name": "Parcel International Standard" + }, + { + "id": "saia.standard", + "carrier_name": "Saia Motor Freight", + "service_name": "Standard" + }, + { + "id": "Mg5oX7RWPCrENCdFkqaijO3NI0qKLFPt.standard", + "carrier_name": "2garima", + "service_name": "Standard" + }, + { + "id": "moto.standard", + "carrier_name": "Moto Transportation Services Corp", + "service_name": "Standard" + }, + { + "id": "2vlSmNNDnF6OWQFjUTFPlwLpTv0RkgXp.standard", + "carrier_name": "New Carrier1", + "service_name": "Standard" + }, + { + "id": "6D24l95xtm4jFC550GYo0tLEBrjgavVS.standard", + "carrier_name": "Admin Added carrier", + "service_name": "Standard" + }, + { + "id": "ab-courier.canada-1030am", + "carrier_name": "A&B Courier", + "service_name": "Canada 10:30am" + }, + { + "id": "ab-courier.canada-930am", + "carrier_name": "A&B Courier", + "service_name": "Canada 9:30am" + }, + { + "id": "ab-courier.canada-ground", + "carrier_name": "A&B Courier", + "service_name": "Canada Ground" + }, + { + "id": "ab-courier.canada-overnight", + "carrier_name": "A&B Courier", + "service_name": "Canada Overnight" + }, + { + "id": "ab-courier.direct", + "carrier_name": "A&B Courier", + "service_name": "Direct" + }, + { + "id": "ab-courier.four-hour", + "carrier_name": "A&B Courier", + "service_name": "Four Hour" + }, + { + "id": "ab-courier.rush", + "carrier_name": "A&B Courier", + "service_name": "Rush" + }, + { + "id": "ab-courier.sameday", + "carrier_name": "A&B Courier", + "service_name": "Sameday" + }, + { + "id": "ab-courier.usa-ground", + "carrier_name": "A&B Courier", + "service_name": "USA Ground" + }, + { + "id": "daynross.cs", + "carrier_name": "Day & Ross", + "service_name": "CS" + }, + { + "id": "daynross.domestic-standard", + "carrier_name": "Day & Ross", + "service_name": "Domestic Standard" + }, + { + "id": "daynross.transborder-standard", + "carrier_name": "Day & Ross", + "service_name": "Transborder Standard" + }, + { + "id": "dayrossrlc-132.standard", + "carrier_name": "Day & Ross RLC", + "service_name": "Standard" + }, + { + "id": "LtViz90ze09z34gcXmBbnFhSSqvvO6h5.standard", + "carrier_name": "FastfrateTest", + "service_name": "Standard" + }, + { + "id": "B6lmGiW6bT5uYz0ceJwoqduC0QRf51cr.standard", + "carrier_name": "1NewDinesh", + "service_name": "Standard" + }, + { + "id": "fedex.economy", + "carrier_name": "FedEx Freight", + "service_name": "Economy" + }, + { + "id": "fedex.standard", + "carrier_name": "FedEx Freight", + "service_name": "Priority" + }, + { + "id": "VwSa0UuckhcLkEzVoCSkhPJoTygfzeIk.standard", + "carrier_name": "Insurance Testing Carrier", + "service_name": "Standard" + }, + { + "id": "YlhNxO31X2UtvtKauwVLdIo4skgYEtDi.standard", + "carrier_name": "Dino Trucking Inc", + "service_name": "Standard" + }, + { + "id": "anq7q2st2UWtnj2WPWqXtgIgaUa4AZF4.standard", + "carrier_name": "Air lines ", + "service_name": "Standard" + }, + { + "id": "dhlcanada-230.standard", + "carrier_name": "DHL CANADA", + "service_name": "Standard" + }, + { + "id": "fedexexpress-272.standard", + "carrier_name": "FedEx Express", + "service_name": "Standard" + }, + { + "id": "KQfppq3g1UUR3BabBSUvQko4MWDUPnul.standard", + "carrier_name": "FC Carrier", + "service_name": "Standard" + }, + { + "id": "speedytransport-153.standard", + "carrier_name": "Speedy Transport", + "service_name": "Standard" + }, + { + "id": "tstapi.intermodal", + "carrier_name": "TST", + "service_name": "Intermodal" + }, + { + "id": "tstapi.standard", + "carrier_name": "TST", + "service_name": "Standard" + }, + { + "id": "ab-courier-ltl.ltl-direct", + "carrier_name": "A&B Courier", + "service_name": "Direct (Pallet)" + }, + { + "id": "ab-courier-ltl.ltl-rush", + "carrier_name": "A&B Courier", + "service_name": "Rush (Pallet)" + }, + { + "id": "ab-courier-ltl.ltl-sameday", + "carrier_name": "A&B Courier", + "service_name": "Sameday (Pallet)" + }, + { + "id": "accordtransportation-176.standard", + "carrier_name": "Accord Transportation", + "service_name": "Standard" + }, + { + "id": "am0cHEYPS0pZbXDbVXUM6opDv3c4YyxP.standard", + "carrier_name": "testGar", + "service_name": "Standard" + }, + { + "id": "purolatorcourier-401.standard", + "carrier_name": "Purolator Courier", + "service_name": "Standard" + }, + { + "id": "swyft.nextday", + "carrier_name": "Swyft", + "service_name": "Next Day" + }, + { + "id": "swyft.sameday", + "carrier_name": "Swyft", + "service_name": "Same Day" + }, + { + "id": "upscourier-162.standard", + "carrier_name": "UPS Courier", + "service_name": "Standard" + }, + { + "id": "2ya9w4n9GgNbqWlBgKcWro3WYkm0SI2d.standard", + "carrier_name": "SD Carrier", + "service_name": "Standard" + }, + { + "id": "csa.standard", + "carrier_name": "CSA", + "service_name": "Standard" + }, + { + "id": "newpenn.standard", + "carrier_name": "New Penn", + "service_name": "Standard" + }, + { + "id": "spring-gds.spring-direct", + "carrier_name": "Spring GDS", + "service_name": "Spring Direct" + }, + { + "id": "spring-gds.spring-gateway-parcel", + "carrier_name": "Spring GDS", + "service_name": "Spring Gateway Parcel" + }, + { + "id": "spring-gds.spring-packet-plus", + "carrier_name": "Spring GDS", + "service_name": "Spring Packet Plus Registered" + }, + { + "id": "spring-gds.spring-packet-tracked", + "carrier_name": "Spring GDS", + "service_name": "Spring Packet Tracked" + }, + { + "id": "spring-gds.spring-packet-untracked", + "carrier_name": "Spring GDS", + "service_name": "Spring Packet Untracked" + }, + { + "id": "TXbrc3AuAEXSJ9uQnT40gRG0zk41qTml.standard", + "carrier_name": "1Dinesh carrier", + "service_name": "Standard" + }, + { + "id": "6AS1YHCOu0JmUMnb0kEHBAS1blnvdi3C.standard", + "carrier_name": "SushmaCarrier", + "service_name": "Standard" + }, + { + "id": "gls-us.am-select-8a-12p", + "carrier_name": "GLS US", + "service_name": "AM Select 8a-12p" + }, + { + "id": "gls-us.early-priority-overnight", + "carrier_name": "GLS US", + "service_name": "Early Priority Overnight" + }, + { + "id": "gls-us.early-saturday-delivery", + "carrier_name": "GLS US", + "service_name": "Early Saturday Delivery" + }, + { + "id": "gls-us.evening-select-4p-8p", + "carrier_name": "GLS US", + "service_name": "Evening Select 4p-8p" + }, + { + "id": "gls-us.gls-ground", + "carrier_name": "GLS US", + "service_name": "GLS Ground" + }, + { + "id": "gls-us.noon-priority-overnight-sds–saturday-delivery", + "carrier_name": "GLS US", + "service_name": "Noon Priority Overnight SDS – Saturday Delivery" + }, + { + "id": "gls-us.pm-select-12p-4p", + "carrier_name": "GLS US", + "service_name": "PM Select 12p-4p" + }, + { + "id": "gls-us.priority-overnight", + "carrier_name": "GLS US", + "service_name": "Priority Overnight" + }, + { + "id": "gls-us.saturday-delivery", + "carrier_name": "GLS US", + "service_name": "Saturday Delivery" + }, + { + "id": "6XTleMYOSAZrdGo5dkg0AB2FS3E35oMF.standard", + "carrier_name": "Show Demo", + "service_name": "Standard" + }, + { + "id": "abcourier-480.standard", + "carrier_name": "A&B Courier (Manual)", + "service_name": "Standard" + }, + { + "id": "allspeed-432.standard", + "carrier_name": "All Speed", + "service_name": "Standard" + }, + { + "id": "KqwXT5YZbXOvt0PXziMUxkj3J6V1pTsQ.standard", + "carrier_name": "SushmaCarrier", + "service_name": "Standard" + }, + { + "id": "sameday.2-man-delivery-to-entrance", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Entrance - 2 Person" + }, + { + "id": "sameday.2-man-delivery-to-room-of-choice", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Room of Choice - 2 Person" + }, + { + "id": "sameday.2-man-delivery-to-room-of-choice-with-debris-removal", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Two-person delivery to room of choice with debris removal" + }, + { + "id": "sameday.dayr-ecom-urgent-pac", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "eCommerce Urgent Pak" + }, + { + "id": "sameday.delivery-to-entrance", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Entrance" + }, + { + "id": "sameday.delivery-to-room-of-choice", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Room of Choice" + }, + { + "id": "sameday.delivery-to-room-of-choice-with-debris-removal", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Delivery to Room of Choice with Debris Removal" + }, + { + "id": "sameday.ground-daynross-road", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Ground - Road" + }, + { + "id": "sameday.next-day-before-5pm", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Next Day Delivery by 5 PM" + }, + { + "id": "sameday.next-day-before-9am", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Next Day Delivery by 9 AM" + }, + { + "id": "sameday.next-day-delivery-before-noon", + "carrier_name": "Day & Ross Commerce Solutions", + "service_name": "Next Day Delivery Before Noon" + }, + { + "id": "transkid.standard", + "carrier_name": "Transkid", + "service_name": "Standard" + }, + { + "id": "37SyVWjCgJxqehNHTdBaFhz1MQxKK0Vd.standard", + "carrier_name": "2New Spot carrier", + "service_name": "Standard" + }, + { + "id": "atlantistransport-347.standard", + "carrier_name": "Atlantis Transport", + "service_name": "Standard" + }, + { + "id": "excel-transport.standard", + "carrier_name": "Excel Transportation", + "service_name": "Standard" + }, + { + "id": "fleet-optics.standard", + "carrier_name": "Fleet Optics", + "service_name": "Standard" + }, + { + "id": "gardewine.standard", + "carrier_name": "Gardewine", + "service_name": "Standard" + }, + { + "id": "ics.ground", + "carrier_name": "ICS", + "service_name": "Ground" + }, + { + "id": "ics.next-day", + "carrier_name": "ICS", + "service_name": "Next day" + }, + { + "id": "usps.first-class", + "carrier_name": "USPS", + "service_name": "First Class" + }, + { + "id": "usps.ground-advantage", + "carrier_name": "USPS", + "service_name": "Ground Advantage" + }, + { + "id": "usps.parcel-select-ground", + "carrier_name": "USPS", + "service_name": "Parcel Select Ground" + }, + { + "id": "usps.priority-mail", + "carrier_name": "USPS", + "service_name": "Priority Mail" + }, + { + "id": "usps.priority-mail-express", + "carrier_name": "USPS", + "service_name": "Priority Mail Express" + }, + { + "id": "ups.3day-select", + "carrier_name": "UPS", + "service_name": "3 Day Select" + }, + { + "id": "ups.expedited", + "carrier_name": "UPS", + "service_name": "Expedited" + }, + { + "id": "ups.express", + "carrier_name": "UPS", + "service_name": "Express" + }, + { + "id": "ups.express-early", + "carrier_name": "UPS", + "service_name": "Express Early" + }, + { + "id": "ups.express-saver", + "carrier_name": "UPS", + "service_name": "Express Saver" + }, + { + "id": "ups.ground", + "carrier_name": "UPS", + "service_name": "Ground" + }, + { + "id": "ups.standard", + "carrier_name": "UPS", + "service_name": "Standard" + }, + { + "id": "ups.worldwide-expedited", + "carrier_name": "UPS", + "service_name": "Worldwide Expedited" + }, + { + "id": "ups.worldwide-express", + "carrier_name": "UPS", + "service_name": "Worldwide Express" + }, + { + "id": "ups.worldwide-express-plus", + "carrier_name": "UPS", + "service_name": "Worldwide Express Plus" + }, + { + "id": "ups.worldwide-express-saver", + "carrier_name": "UPS", + "service_name": "Worldwide Express Saver" + }, + { + "id": "airpro-255.standard", + "carrier_name": "Air Pro", + "service_name": "Standard" + }, + { + "id": "apex.standard", + "carrier_name": "Apex", + "service_name": "Standard" + }, + { + "id": "frontline.standard", + "carrier_name": "Frontline", + "service_name": "Standard" + }, + { + "id": "nationex.standard", + "carrier_name": "Nationex", + "service_name": "Standard" + }, + { + "id": "qM4cPFVXO20tNUz8fuU2bZCd6s0a6oKE.standard", + "carrier_name": "GL Freight", + "service_name": "Standard" + }, + { + "id": "swiftdeliverysystems-268.standard", + "carrier_name": "Swift Delivery Systems", + "service_name": "Standard" + }, + { + "id": "comox.standard", + "carrier_name": "Comox Pacific Express", + "service_name": "Standard" + }, + { + "id": "h9d2M32kjQDeB0GldPN0AMYvhuEXI45c.standard", + "carrier_name": "New2New carrier ", + "service_name": "Standard" + }, + { + "id": "maritime.dry", + "carrier_name": "Maritime", + "service_name": "Dry" + }, + { + "id": "maritime.frozen", + "carrier_name": "Maritime", + "service_name": "Reefer" + }, + { + "id": "maritime.heat", + "carrier_name": "Maritime", + "service_name": "Heat" + }, + { + "id": "overland.standard", + "carrier_name": "Overland", + "service_name": "Standard" + }, + { + "id": "manitoulintransport-440.standard", + "carrier_name": "Manitoulin Transport", + "service_name": "Standard" + }, + { + "id": "tforcefreight.tforcefreight-guarnteed", + "carrier_name": "TForceFreight", + "service_name": "TForceFreight Guaranteed" + }, + { + "id": "tforcefreight.tforcefreight-ltl", + "carrier_name": "TForceFreight", + "service_name": "TForceFreight LTL" + }, + { + "id": "tforcefreight.tforcefreight-standard", + "carrier_name": "TForceFreight", + "service_name": "TForceFreight Standard" + }, + { + "id": "V44U22d1DwvXrhpvW7UtPrZ4GQQ6x6Hb.standard", + "carrier_name": "11Manager Carriers", + "service_name": "Standard" + }, + { + "id": "yrc.accelerated", + "carrier_name": "YRC", + "service_name": "Accelerated" + }, + { + "id": "yrc.freight-canada-to-us", + "carrier_name": "YRC", + "service_name": "Canada to US" + }, + { + "id": "yrc.freight-dedicated-equipment", + "carrier_name": "YRC", + "service_name": "Dedicated Equipment" + }, + { + "id": "yrc.standard", + "carrier_name": "YRC", + "service_name": "Standard" + }, + { + "id": "yrc.time-critical-by-5pm", + "carrier_name": "YRC", + "service_name": "Critical by 5 PM" + }, + { + "id": "yrc.time-critical-by-afternoon", + "carrier_name": "YRC", + "service_name": "Critical by Afternoon" + }, + { + "id": "yrc.time-critical-fastest-ground", + "carrier_name": "YRC", + "service_name": "Critical Fastest Ground" + }, + { + "id": "yrc.time-critical-hour-window", + "carrier_name": "YRC", + "service_name": "Critical Hour Window" + }, + { + "id": "Zs8TafpKGZ0fx9utJ42E4ZFyLtoRUmzE.standard", + "carrier_name": "BinduTestCarrier", + "service_name": "Standard" + }, + { + "id": "abffreight-455.standard", + "carrier_name": "ABF Freight", + "service_name": "Standard" + }, + { + "id": "dayrosscdn-133.standard", + "carrier_name": "Day & Ross CDN", + "service_name": "Standard" + }, + { + "id": "gMS33dZBLDmtyw0ileP8b0wxytNPUNEe.standard", + "carrier_name": "SPOT Polaris", + "service_name": "Standard" + }, + { + "id": "intelcom.standard", + "carrier_name": "Intelcom", + "service_name": "Standard" + }, + { + "id": "maritimeontario-267.standard", + "carrier_name": "Maritime-Ontario", + "service_name": "Standard" + }, + { + "id": "minimax.standard", + "carrier_name": "Minimax", + "service_name": "Standard" + }, + { + "id": "allmodes-147.standard", + "carrier_name": "All Modes", + "service_name": "Standard" + }, + { + "id": "gls-freight.ground", + "carrier_name": "GLS Freight", + "service_name": "Ground" + }, + { + "id": "kindersley-courier.standard", + "carrier_name": "Kindersley Transport", + "service_name": "Standard" + }, + { + "id": "LfuLpu4OaMgNiVnBFYbNUXxiAyY66z3m.standard", + "carrier_name": "Joshuas super advanced and not sketchy at all spot carrier", + "service_name": "Standard" + }, + { + "id": "midland.econoline", + "carrier_name": "MidLand Transport", + "service_name": "Econo Line" + }, + { + "id": "midland.reefer", + "carrier_name": "MidLand Transport", + "service_name": "Reefer" + }, + { + "id": "midland.standard", + "carrier_name": "MidLand Transport", + "service_name": "Standard" + }, + { + "id": "TKzEkXVCaQIkGU0SqHyix6Lujv1YiCaR.standard", + "carrier_name": "Test carrier", + "service_name": "Standard" + }, + { + "id": "1lFVuiEgI85Be3BmNH9Jc8QKe5DEDVs0.standard", + "carrier_name": "vicky", + "service_name": "Standard" + }, + { + "id": "gY2Ah4O53ACmkb6D75rHLg6eMfzpsIpw.standard", + "carrier_name": "Flex transport", + "service_name": "Standard" + }, + { + "id": "morneau.standard", + "carrier_name": "Morneau Transport", + "service_name": "Standard" + }, + { + "id": "4TBSrW3F8aUzohICK0A0XH2mk25Aipdx.standard", + "carrier_name": "Bill Cartage", + "service_name": "Standard" + }, + { + "id": "nishantransportinc-423.standard", + "carrier_name": "NISHAN TRANSPORT INC.", + "service_name": "Standard" + }, + { + "id": "xpologistics-265.standard", + "carrier_name": "XPO Logistics", + "service_name": "Standard" + }, + { + "id": "Fqrdds8xTJcw2gopMEKjgdNR0jTkxxVm.standard", + "carrier_name": "gartest2Carrier", + "service_name": "Standard" + }, + { + "id": "mBbc7RwNE6CPvx22XiDZ50kdsC2fLNEF.standard", + "carrier_name": "CSS Carrier", + "service_name": "Standard" + }, + { + "id": "courrierplus-494.standard", + "carrier_name": "Courrier Plus", + "service_name": "Standard" + }, + { + "id": "loomis-express.express-0900", + "carrier_name": "Loomis", + "service_name": "Express 9:00" + }, + { + "id": "loomis-express.express-1200", + "carrier_name": "Loomis", + "service_name": "Express 12:00" + }, + { + "id": "loomis-express.express-1800", + "carrier_name": "Loomis", + "service_name": "Express 18:00" + }, + { + "id": "loomis-express.ground", + "carrier_name": "Loomis", + "service_name": "Ground" + }, + { + "id": "purolatorfreight.standard", + "carrier_name": "Purolator Freight", + "service_name": "Standard" + }, + { + "id": "csatransportation-191.standard", + "carrier_name": "CSA Transportation", + "service_name": "Standard" + }, + { + "id": "XiX2uCQlUYTCn4Mi5z3APT4Mi2Xn2x3a.standard", + "carrier_name": "New GLS Freight", + "service_name": "Standard" + }, + { + "id": "fastfrate.express", + "carrier_name": "Fastfrate", + "service_name": "Express" + }, + { + "id": "fastfrate.standard", + "carrier_name": "Fastfrate", + "service_name": "Standard" + }, + { + "id": "martinroytransport-310.standard", + "carrier_name": "Martin Roy Transport", + "service_name": "Standard" + }, + { + "id": "reddaway.guaranteed-3pm", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 3:30 PM" + }, + { + "id": "reddaway.guaranteed-9am", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 9 AM" + }, + { + "id": "reddaway.guaranteed-noon", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 12:00 PM (noon)" + }, + { + "id": "reddaway.guaranteed-weekend", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Weekend" + }, + { + "id": "reddaway.guarenteed-9am", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 9 AM" + }, + { + "id": "reddaway.guarenteed-noon", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Delivery Before 12:00 PM (noon)" + }, + { + "id": "reddaway.interline", + "carrier_name": "Reddaway", + "service_name": "Interline Delivery" + }, + { + "id": "reddaway.multi-hour-window", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Window - Multi-Hour Window" + }, + { + "id": "reddaway.regional-delivery", + "carrier_name": "Reddaway", + "service_name": "Regional Delivery" + }, + { + "id": "reddaway.single-hour-window", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Window - Single-hour Window" + }, + { + "id": "reddaway.single-or-multi-day", + "carrier_name": "Reddaway", + "service_name": "Guaranteed Window - Single or Multi-day Window" + }, + { + "id": "reddaway.standard", + "carrier_name": "Reddaway", + "service_name": "Standard" + }, + { + "id": "xpo.standard", + "carrier_name": "XPO", + "service_name": "Standard" + }, + { + "id": "yrcfreight-330.standard", + "carrier_name": "YRC Freight", + "service_name": "Standard" + }, + { + "id": "amatransinc-251.standard", + "carrier_name": "AMA Trans Inc", + "service_name": "Standard" + }, + { + "id": "canadapost.domestic", + "carrier_name": "Canada Post", + "service_name": "Domestic" + }, + { + "id": "canadapost.expedited-parcel", + "carrier_name": "Canada Post", + "service_name": "Expedited Parcel" + }, + { + "id": "canadapost.expedited-parcel-usa", + "carrier_name": "Canada Post", + "service_name": "Expedited Parcel USA" + }, + { + "id": "canadapost.international", + "carrier_name": "Canada Post", + "service_name": "International" + }, + { + "id": "canadapost.international-parcel-air", + "carrier_name": "Canada Post", + "service_name": "International Parcel Air" + }, + { + "id": "canadapost.international-parcel-surface", + "carrier_name": "Canada Post", + "service_name": "International Parcel Surface" + }, + { + "id": "canadapost.priority", + "carrier_name": "Canada Post", + "service_name": "Priority" + }, + { + "id": "canadapost.priority-ww-envelope-international", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide envelope INT’L" + }, + { + "id": "canadapost.priority-ww-envelope-usa", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide envelope USA" + }, + { + "id": "canadapost.priority-ww-pak-international", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide pak INT’L" + }, + { + "id": "canadapost.priority-ww-pak-usa", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide pak USA" + }, + { + "id": "canadapost.priority-ww-parcel-international", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide parcel INT’L" + }, + { + "id": "canadapost.priority-ww-parcel-usa", + "carrier_name": "Canada Post", + "service_name": "Priority Worldwide parcel USA" + }, + { + "id": "canadapost.regular-parcel", + "carrier_name": "Canada Post", + "service_name": "Regular Parcel" + }, + { + "id": "canadapost.small-packet-international-air", + "carrier_name": "Canada Post", + "service_name": "Small Packet International Air" + }, + { + "id": "canadapost.small-packet-international-surface", + "carrier_name": "Canada Post", + "service_name": "Small Packet International Surface" + }, + { + "id": "canadapost.small-packet-usa-air", + "carrier_name": "Canada Post", + "service_name": "Small Packet USA Air" + }, + { + "id": "canadapost.tracked-packet-international", + "carrier_name": "Canada Post", + "service_name": "Tracked Packet - International" + }, + { + "id": "canadapost.tracked-packet-usa", + "carrier_name": "Canada Post", + "service_name": "Tracked Packet USA" + }, + { + "id": "canadapost.xpresspost", + "carrier_name": "Canada Post", + "service_name": "Xpresspost" + }, + { + "id": "canadapost.xpresspost-international", + "carrier_name": "Canada Post", + "service_name": "Xpresspost International" + }, + { + "id": "canadapost.xpresspost-usa", + "carrier_name": "Canada Post", + "service_name": "Xpresspost USA" + }, + { + "id": "canpar.ground", + "carrier_name": "Canpar", + "service_name": "Ground" + }, + { + "id": "canpar.international", + "carrier_name": "Canpar", + "service_name": "International" + }, + { + "id": "canpar.overnight", + "carrier_name": "Canpar", + "service_name": "Overnight" + }, + { + "id": "canpar.overnight-letter", + "carrier_name": "Canpar", + "service_name": "Overnight Letter" + }, + { + "id": "canpar.overnight-pak", + "carrier_name": "Canpar", + "service_name": "Overnight Pak" + }, + { + "id": "canpar.select", + "carrier_name": "Canpar", + "service_name": "Select" + }, + { + "id": "canpar.select-letter", + "carrier_name": "Canpar", + "service_name": "Select Letter" + }, + { + "id": "canpar.select-pak", + "carrier_name": "Canpar", + "service_name": "Select Pak" + }, + { + "id": "canpar.select-usa", + "carrier_name": "Canpar", + "service_name": "Select U.S.A." + }, + { + "id": "canpar.usa", + "carrier_name": "Canpar", + "service_name": "U.S.A." + }, + { + "id": "canpar.usa-Letter", + "carrier_name": "Canpar", + "service_name": "U.S.A. Letter" + }, + { + "id": "canpar.usa-pak", + "carrier_name": "Canpar", + "service_name": "U.S.A. Pak" + }, + { + "id": "gls.ground", + "carrier_name": "GLS", + "service_name": "Ground" + }, + { + "id": "QzGk6Gz9BPcw0v7zsJcIaTAAXd6X7732.standard", + "carrier_name": "BinduTestCarrier2", + "service_name": "Standard" + }, + { + "id": "w2oXoP88bl44DA3Y4hft8dZoLFDp3KFX.standard", + "carrier_name": "Carrier Sonu", + "service_name": "Standard" + }, + { + "id": "e5966ZlRusUUM61sXUM1QQx0Td17iIan.standard", + "carrier_name": "Dolphin Carrier", + "service_name": "Standard" + }, + { + "id": "polarisweb.standard", + "carrier_name": "Polaris FPP", + "service_name": "Pallet Program" + }, + { + "id": "purolatorcourier.express", + "carrier_name": "Purolator", + "service_name": "Express" + }, + { + "id": "purolatorcourier.express-box", + "carrier_name": "Purolator", + "service_name": "Express Box" + }, + { + "id": "purolatorcourier.express-box-international", + "carrier_name": "Purolator", + "service_name": "Express Box International" + }, + { + "id": "purolatorcourier.express-box1030am", + "carrier_name": "Purolator", + "service_name": "Express Box 10:30 AM" + }, + { + "id": "purolatorcourier.express-box9am", + "carrier_name": "Purolator", + "service_name": "Express Box 9 AM" + }, + { + "id": "purolatorcourier.express-boxUS", + "carrier_name": "Purolator", + "service_name": "Express Box U.S." + }, + { + "id": "purolatorcourier.express-envelope", + "carrier_name": "Purolator", + "service_name": "Express Envelope" + }, + { + "id": "purolatorcourier.express-envelope-international", + "carrier_name": "Purolator", + "service_name": "Express Envelope International" + }, + { + "id": "purolatorcourier.express-envelope-us", + "carrier_name": "Purolator", + "service_name": "Express Envelope U.S." + }, + { + "id": "purolatorcourier.express-envelope1030am", + "carrier_name": "Purolator", + "service_name": "Express Envelope 10:30 AM" + }, + { + "id": "purolatorcourier.express-envelope9am", + "carrier_name": "Purolator", + "service_name": "Express Envelope 9 AM" + }, + { + "id": "purolatorcourier.express-international", + "carrier_name": "Purolator", + "service_name": "Express International" + }, + { + "id": "purolatorcourier.express-pack", + "carrier_name": "Purolator", + "service_name": "Express Pack" + }, + { + "id": "purolatorcourier.express-pack-international", + "carrier_name": "Purolator", + "service_name": "Express Pack International" + }, + { + "id": "purolatorcourier.express-pack-us", + "carrier_name": "Purolator", + "service_name": "Express Pack U.S." + }, + { + "id": "purolatorcourier.express-pack1030am", + "carrier_name": "Purolator", + "service_name": "Express Pack 10:30 AM" + }, + { + "id": "purolatorcourier.express-pack9am", + "carrier_name": "Purolator", + "service_name": "Express Pack 9 AM" + }, + { + "id": "purolatorcourier.express-us", + "carrier_name": "Purolator", + "service_name": "Express U.S." + }, + { + "id": "purolatorcourier.express-us-1030am", + "carrier_name": "Purolator", + "service_name": "Express U.S. 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-9am", + "carrier_name": "Purolator", + "service_name": "Express U.S. 9 AM" + }, + { + "id": "purolatorcourier.express-us-box1030AM", + "carrier_name": "Purolator", + "service_name": "Express U.S. Box 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-box9AM", + "carrier_name": "Purolator", + "service_name": "Express U.S. Box 9 AM" + }, + { + "id": "purolatorcourier.express-us-envelope1030am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Envelope 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-envelope9am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Envelope 9 AM" + }, + { + "id": "purolatorcourier.express-us-pack1030am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Pack 10:30 AM" + }, + { + "id": "purolatorcourier.express-us-pack9am", + "carrier_name": "Purolator", + "service_name": "Express U.S. Pack 9 AM" + }, + { + "id": "purolatorcourier.express1030AM", + "carrier_name": "Purolator", + "service_name": "Express 10:30 AM" + }, + { + "id": "purolatorcourier.express9AM", + "carrier_name": "Purolator", + "service_name": "Express 9 AM" + }, + { + "id": "purolatorcourier.ground", + "carrier_name": "Purolator", + "service_name": "Ground" + }, + { + "id": "purolatorcourier.ground-us", + "carrier_name": "Purolator", + "service_name": "Ground U.S." + }, + { + "id": "purolatorcourier.standard", + "carrier_name": "Purolator", + "service_name": "Standard" + } + ] +} diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/quote.py b/modules/connectors/freightcom/karrio/providers/freightcom/quote.py deleted file mode 100644 index 7704989149..0000000000 --- a/modules/connectors/freightcom/karrio/providers/freightcom/quote.py +++ /dev/null @@ -1,179 +0,0 @@ -from karrio.schemas.freightcom.quote_request import ( - Freightcom, - QuoteRequestType, - FromType, - ToType, - PackagesType, - PackageType, -) -from karrio.schemas.freightcom.quote_reply import QuoteType - -import typing -import karrio.lib as lib -import karrio.core.models as models -import karrio.providers.freightcom.error as provider_error -import karrio.providers.freightcom.units as provider_units -import karrio.providers.freightcom.utils as provider_utils - - -def parse_quote_reply( - _response: lib.Deserializable[lib.Element], settings: provider_utils.Settings -) -> typing.Tuple[typing.List[models.RateDetails], typing.List[models.Message]]: - response = _response.deserialize() - estimates = lib.find_element("Quote", response) - - return ( - [_extract_rate(node, settings) for node in estimates], - provider_error.parse_error_response(response, settings), - ) - - -def _extract_rate( - node: lib.Element, - settings: provider_utils.Settings, -) -> models.RateDetails: - quote = lib.to_object(QuoteType, node) - rate_provider, service, service_name = provider_units.ShippingService.info( - quote.serviceId, - quote.carrierId, - quote.serviceName, - quote.carrierName, - ) - charges = [ - ("Base charge", quote.baseCharge), - ("Fuel surcharge", quote.fuelSurcharge), - *((surcharge.name, surcharge.amount) for surcharge in quote.Surcharge), - ] - - return models.RateDetails( - carrier_name=settings.carrier_name, - carrier_id=settings.carrier_id, - currency=quote.currency, - service=service, - total_charge=lib.to_decimal(quote.totalCharge), - transit_days=quote.transitDays, - extra_charges=[ - models.ChargeDetails( - name=name, - currency="CAD", - amount=lib.to_decimal(amount), - ) - for name, amount in charges - if amount - ], - meta=dict(rate_provider=rate_provider, service_name=service_name), - ) - - -def quote_request( - payload: models.RateRequest, - settings: provider_utils.Settings, -) -> lib.Serializable: - shipper = lib.to_address(payload.shipper) - recipient = lib.to_address(payload.recipient) - packages = lib.to_packages( - payload.parcels, - package_option_type=provider_units.ShippingOption, - required=["weight", "height", "width", "length"], - ) - options = lib.to_shipping_options( - payload.options, - package_options=packages.options, - initializer=provider_units.shipping_options_initializer, - ) - packaging_type = provider_units.FreightPackagingType[ - packages.package_type or "small_box" - ].value - packaging = ( - "Pallet" - if packaging_type in [provider_units.FreightPackagingType.pallet.value] - else "Package" - ) - service = ( - lib.to_services(payload.services, provider_units.ShippingService).first - or provider_units.ShippingService.freightcom_all - ) - - request = Freightcom( - username=settings.username, - password=settings.password, - version="3.1.0", - QuoteRequest=QuoteRequestType( - saturdayPickupRequired=options.freightcom_saturday_pickup_required.state, - homelandSecurity=options.freightcom_homeland_security.state, - pierCharge=None, - exhibitionConventionSite=options.freightcom_exhibition_convention_site.state, - militaryBaseDelivery=options.freightcom_military_base_delivery.state, - customsIn_bondFreight=options.freightcom_customs_in_bond_freight.state, - limitedAccess=options.freightcom_limited_access.state, - excessLength=options.freightcom_excess_length.state, - tailgatePickup=options.freightcom_tailgate_pickup.state, - residentialPickup=options.freightcom_residential_pickup.state, - crossBorderFee=None, - notifyRecipient=options.freightcom_notify_recipient.state, - singleShipment=options.freightcom_single_shipment.state, - tailgateDelivery=options.freightcom_tailgate_delivery.state, - residentialDelivery=options.freightcom_residential_delivery.state, - insuranceType=options.insurance.state is not None, - scheduledShipDate=None, - insideDelivery=options.freightcom_inside_delivery.state, - isSaturdayService=options.freightcom_is_saturday_service.state, - dangerousGoodsType=options.freightcom_dangerous_goods_type.state, - serviceId=service.value, - stackable=options.freightcom_stackable.state, - From=FromType( - id=None, - company=shipper.company_name or " ", - instructions=None, - email=shipper.email, - attention=shipper.person_name, - phone=shipper.phone_number, - tailgateRequired=None, - residential=shipper.residential, - address1=shipper.street, - address2=lib.text(shipper.address_line2), - city=shipper.city, - state=shipper.state_code, - zip=shipper.postal_code, - country=shipper.country_code, - ), - To=ToType( - id=None, - company=recipient.company_name or " ", - notifyRecipient=None, - instructions=None, - email=recipient.email, - attention=recipient.person_name, - phone=recipient.phone_number, - tailgateRequired=None, - residential=recipient.residential, - address1=recipient.street, - address2=lib.text(recipient.address_line2), - city=recipient.city, - state=recipient.state_code, - zip=recipient.postal_code, - country=recipient.country_code, - ), - COD=None, - Packages=PackagesType( - Package=[ - PackageType( - length=provider_utils.ceil(package.length.IN), - width=provider_utils.ceil(package.width.IN), - height=provider_utils.ceil(package.height.IN), - weight=provider_utils.ceil(package.weight.LB), - type_=packaging_type, - freightClass=package.parcel.freight_class, - nmfcCode=None, - insuranceAmount=package.options.insurance.state, - codAmount=package.options.cash_on_delivery.state, - description=package.parcel.description, - ) - for package in packages - ], - type_=packaging, - ), - ), - ) - - return lib.Serializable(request, provider_utils.standard_request_serializer) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py new file mode 100644 index 0000000000..003b0c877e --- /dev/null +++ b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py @@ -0,0 +1,205 @@ +import karrio.schemas.freightcom.rate_request as freightcom +import karrio.schemas.freightcom.rate_response as rating +import typing +import datetime +import karrio.lib as lib +import karrio.core.models as models +import karrio.providers.freightcom.error as error +import karrio.providers.freightcom.utils as provider_utils +import karrio.providers.freightcom.units as provider_units + + +def parse_rate_response( + response: lib.Deserializable[dict], + settings: provider_utils.Settings, +) -> typing.Tuple[typing.List[models.RateDetails], typing.List[models.Message]]: + """Parse Freightcom rate response into Karrio format""" + parsed_response = response.deserialize() + messages = error.parse_error_response(parsed_response, settings) + rates = [_extract_details(rate, settings) for rate in parsed_response.get("rates", [])] + return rates, messages + +def _extract_details( + data: dict, + settings: provider_utils.Settings, +) -> models.RateDetails: + rate = lib.to_object(rating.RateType, data) + + service = provider_units.ShippingService.map( + rate.service_id, + ) + courier = provider_units.ShippingCourier.find(rate.service_id) + + charges = [ + ("Base charge", rate.base.value, rate.base.currency), + *((surcharge.type, surcharge.amount.value, surcharge.amount.currency) for surcharge in rate.surcharges), + *((tax.type, tax.amount.value, tax.amount.currency) for tax in rate.taxes), + ] + + return models.RateDetails( + carrier_id=settings.carrier_id, + carrier_name=settings.carrier_name, + service=service.name_or_key, + total_charge=lib.to_money(int(rate.total.value) / 100), + currency=rate.total.currency, + transit_days=lib.to_int(rate.transit_time_days), + extra_charges=[ + models.ChargeDetails( + name=name, + currency=currency, + amount=lib.to_money(int(amount) / 100), + ) + for name, amount, currency in charges + if charges + ], + meta=dict( + rate_provider=courier.name, + service_name=service.name , + ), + ) + +def rate_request( + payload: models.RateRequest, + settings: provider_utils.Settings, +) -> lib.Serializable: + """Create a Freightcom rate request from Karrio unified request""" + shipper = lib.to_address(payload.shipper) + recipient = lib.to_address(payload.recipient) + packages = lib.to_packages(payload.parcels) + options = lib.to_shipping_options( + payload.options, + package_options=packages.options, + ) + + packaging_type = provider_units.PackagingType.map(packages.package_type or "small_box").value + ship_datetime = lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M", + ) + + request = freightcom.RateRequestType( + services=payload.services or [], + excluded_services=[], + details=freightcom.DetailsType( + origin=freightcom.DestinationType( + name=shipper.company_name or shipper.person_name, + address=freightcom.AddressType( + address_line_1=shipper.address_line1, + address_line_2=shipper.address_line2, + city=shipper.city, + region=shipper.state_code, + country=shipper.country_code, + postal_code=shipper.postal_code, + ), + residential=shipper.residential, + contact_name=shipper.person_name if shipper.company_name else "", + phone_number=freightcom.PhoneNumberType( + number=shipper.phone_number + ) if shipper.phone_number else None, + email_addresses=lib.join(shipper.email), + ), + destination=freightcom.DestinationType( + name=recipient.company_name or recipient.person_name, + address=freightcom.AddressType( + address_line_1=recipient.address_line1, + address_line_2=recipient.address_line2, + city=recipient.city, + region=recipient.state_code, + country=recipient.country_code, + postal_code=recipient.postal_code, + ), + residential=recipient.residential, + contact_name=recipient.person_name, + phone_number=freightcom.PhoneNumberType( + number=recipient.phone_number + ) if recipient.phone_number else None, + email_addresses=lib.join(recipient.email), + ready_at=freightcom.ReadyType( + hour=ship_datetime.hour, + minute=0 + ), + ready_until=freightcom.ReadyType( + hour=17, + minute=0 + ), + signature_requirement="required" if options.signature_confirmation.state else "not-required" + ), + expected_ship_date=freightcom.ExpectedShipDateType( + year=ship_datetime.year, + month=ship_datetime.month, + day=ship_datetime.day, + ), + packaging_type=packaging_type, + packaging_properties=( + freightcom.PackagingPropertiesType( + pallet_type="ltl" if packaging_type == "pallet" else None, + has_stackable_pallets=options.stackable.state if packaging_type == "pallet" else None, + dangerous_goods=options.dangerous_goods.state, + dangerous_goods_details=freightcom.DangerousGoodsDetailsType( + packaging_group=options.dangerous_goods_group.state, + goods_class=options.dangerous_goods_class.state, + ) if options.dangerous_goods.state else None, + pallets=[ + freightcom.PalletType( + measurements=freightcom.PalletMeasurementsType( + weight=freightcom.WeightType( + unit="kg" if parcel.weight_unit.upper() == "KG" else "lb", + value=lib.to_decimal(parcel.weight) + ), + cuboid=freightcom.CuboidType( + unit="cm" if parcel.dimension_unit.upper() == "CM" else "in", + l=lib.to_int(parcel.length), + w=lib.to_int(parcel.width), + h=lib.to_int(parcel.height) + ) + ), + description=parcel.description, + freight_class=options.freight_class.state, + ) for parcel in payload.parcels + ] if packaging_type == "pallet" else [], + packages=[ + freightcom.PackageType( + measurements=freightcom.PackageMeasurementsType( + weight=freightcom.WeightType( + unit="kg" if parcel.weight_unit.upper() == "KG" else "lb", + value=lib.to_decimal(parcel.weight) + ), + cuboid=freightcom.CuboidType( + unit="cm" if parcel.dimension_unit.upper() == "CM" else "in", + l=lib.to_int(parcel.length), + w=lib.to_int(parcel.width), + h=lib.to_int(parcel.height) + ) + ), + description=parcel.description, + ) for parcel in payload.parcels + ] if packaging_type == "package" else [], + courierpaks=[ + freightcom.CourierpakType( + measurements=freightcom.CourierpakMeasurementsType( + weight=freightcom.WeightType( + unit="kg" if parcel.weight_unit.upper() == "KG" else "lb", + value=lib.to_decimal(parcel.weight) + ) + ), + description=parcel.description, + ) for parcel in payload.parcels + ] if packaging_type == "courier-pak" else [], + insurance=freightcom.InsuranceType( + type='carrier', + total_cost=freightcom.TotalCostType( + currency=options.currency.state or "CAD", + value=lib.to_int(options.insurance.state) + ) + ) if options.insurance.state else None, + pallet_service_details=freightcom.PalletServiceDetailsType() if packaging_type == "pallet" else None, + ) + + ), + reference_codes=[payload.reference] if payload.reference else [] + ) + ) + + return lib.Serializable(request, lib.to_dict) + + diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py index d34c0c9408..e23d2c5dae 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py @@ -144,12 +144,12 @@ def shipping_request( ), ) - packaging_type = provider_units.FreightPackagingType.map( + packaging_type = provider_units.PackagingType.map( packages.package_type or "small_box" ).value packaging = ( "Pallet" - if packaging_type in [provider_units.FreightPackagingType.pallet.value] + if packaging_type in [provider_units.PackagingType.pallet.value] else "Package" ) payment = payload.payment or models.Payment() diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/units.py b/modules/connectors/freightcom/karrio/providers/freightcom/units.py index 5b13a7a110..47e8f791ea 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/units.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/units.py @@ -1,10 +1,33 @@ import re +import json +import typing +import pathlib import karrio.lib as lib import karrio.core.units as units +from typing import Dict, List, Union +METADATA_JSON = lib.load_json(pathlib.Path(__file__).resolve().parent / "metadata.json") -class FreightPackagingType(lib.StrEnum): - freightcom_pallet = "Pallet" +FREIGHTCOM_CARRIER_METADATA = [_ for _ in METADATA_JSON["PROD_SERVICES"] + METADATA_JSON["DEV_SERVICES"]] + + + +KARRIO_CARRIER_MAPPING = { + "Freightcom": "freightcom", + "ups_courier": "ups", + "canada_post": "canadapost", + 'fed_ex_courier': "fedex", + 'fed_ex_express': "fedex", + 'fed_ex_freight': "fedex", + 'fed_ex_ground': "fedex", + "dhl_canada": "dhl_express", + "dhl_e_commerce": "dhl_express", +} + + +class PackagingType(lib.StrEnum): + # TODO: review types + freightcom_pallet = "pallet" freightcom_drum = "Drum" freightcom_boxes = "Boxes" freightcom_rolls = "Rolls" @@ -15,19 +38,18 @@ class FreightPackagingType(lib.StrEnum): freightcom_pails = "Pails" freightcom_reels = "Reels" - freightcom_envelope = "Envelope" - freightcom_courier = "Courier" - freightcom_pak = "Pak" - freightcom_package = "Package" + freightcom_envelope = "envelope" + freightcom_courier = "courier-pak" + freightcom_pak = "courier-pak" + freightcom_package = "package" """ Unified Packaging type mapping """ envelope = freightcom_envelope pak = freightcom_pak tube = freightcom_pipes_tubes pallet = freightcom_pallet - small_box = freightcom_boxes - medium_box = freightcom_boxes - large_box = freightcom_boxes + small_box = freightcom_package + medium_box = freightcom_package your_packaging = freightcom_package @@ -40,78 +62,10 @@ class PaymentType(lib.StrEnum): # TODO:: retrieve the complete list of payment credit_card = "Card" -class ShippingService(lib.StrEnum): - freightcom_all = "0" - freightcom_usf_holland = "1911" - freightcom_central_transport = "2029" - freightcom_estes = "2107" - freightcom_canpar_ground = "3400" - freightcom_canpar_select = "3404" - freightcom_canpar_overnight = "3407" - freightcom_dicom_ground = "3700" - freightcom_purolator_ground = "4000" - freightcom_purolator_express = "4003" - freightcom_purolator_express_9_am = "4004" - freightcom_purolator_express_10_30_am = "4005" - freightcom_purolator_ground_us = "4016" - freightcom_purolator_express_us = "4015" - freightcom_purolator_express_us_9_am = "4013" - freightcom_purolator_express_us_10_30_am = "4014" - freightcom_fedex_express_saver = "4100" - freightcom_fedex_ground = "4101" - freightcom_fedex_2day = "4102" - freightcom_fedex_priority_overnight = "4104" - freightcom_fedex_standard_overnight = "4105" - freightcom_fedex_first_overnight = "4106" - freightcom_fedex_international_priority = "4108" - freightcom_fedex_international_economy = "4109" - freightcom_ups_standard = "4600" - freightcom_ups_expedited = "4601" - freightcom_ups_express_saver = "4602" - freightcom_ups_express = "4603" - freightcom_ups_express_early = "4604" - freightcom_ups_3day_select = "4605" - freightcom_ups_worldwide_expedited = "4606" - freightcom_ups_worldwide_express = "4607" - freightcom_ups_worldwide_express_plus = "4608" - freightcom_ups_worldwide_express_saver = "4609" - freightcom_dhl_express_easy = "5202" - freightcom_dhl_express_10_30 = "5208" - freightcom_dhl_express_worldwide = "5211" - freightcom_dhl_express_12_00 = "5215" - freightcom_dhl_economy_select = "5216" - freightcom_dhl_ecommerce_am_service = "5706" - freightcom_dhl_ecommerce_ground_service = "5707" - freightcom_canadapost_regular_parcel = "6301" - freightcom_canadapost_expedited_parcel = "6300" - freightcom_canadapost_xpresspost = "6303" - freightcom_canadapost_priority = "6302" - - @classmethod - def info(cls, serviceId, carrierId, serviceName, carrierName): - carrier_name = CARRIER_IDS.get(str(carrierId)) or carrierName - service = cls.map(str(serviceId)) - formatted_name = re.sub( - r"((?<=[a-z])[A-Z]|(? units.Options: + package_options: units.ShippingOptions = None, +) -> units.ShippingOptions: """ Apply default values to the given options. """ - _options = options.copy() if package_options is not None: - _options.update(package_options.content) + options.update(package_options.content) + + def items_filter(key: str) -> bool: + return key in ShippingOption # type: ignore + + return units.ShippingOptions(options, ShippingOption, items_filter=items_filter) + + +def to_carrier_code(service: str) -> str: + _code = lib.to_snake_case(service['carrier_name']) + return KARRIO_CARRIER_MAPPING.get(_code, _code) + +def to_service_code(service: typing.Dict[str, str]) -> str: + return f"freightcom_{to_carrier_code(service)}_{lib.to_slug(service['service_name'])}" + +def find_courier(search: str): + courier: dict = next( + ( + item + for item in FREIGHTCOM_CARRIER_METADATA + if to_carrier_code(item) == search + or item['carrier_name'] == search + or item['id'] == search + ), + {}, + ) + + if courier: + return ShippingCourier.map(to_carrier_code(courier)) + + return ShippingCourier.map(search) + +def get_carrier_name(carrier_id: str) -> str: + return next( + ( + service['carrier_name'] + for service in METADATA_JSON["PROD_SERVICES"] + if service['id'].split('.')[0] == carrier_id + ), + None + ) + +# FREIGHTCOM_SERVICE_METADATA = { +# lib.to_snake_case(service['service_name']): { +# **service, +# 'carrier': service['id'].split('.')[0].split('-')[0], +# 'carrier_name': service['carrier_name'] +# } +# for service in METADATA_JSON["PROD_SERVICES"] + METADATA_JSON["DEV_SERVICES"] +# } + + +ShippingService = lib.StrEnum( + "ShippingService", + { + to_service_code(service): service['id'] + for service in FREIGHTCOM_CARRIER_METADATA + }, +) +ShippingCourier = lib.StrEnum( + "ShippingCourier", + { + to_carrier_code(service): service['carrier_name'] + for service in FREIGHTCOM_CARRIER_METADATA + }, +) +# RateProvider = lib.StrEnum( +# "RateProvider", +# { +# carrier_id: carrier['name'] +# for carrier_id, carrier in FREIGHTCOM_CARRIER_METADATA.items() +# }, +# ) + + +setattr(ShippingCourier, "find", find_courier) - return units.ShippingOptions(_options, ShippingOption) diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/error.py b/modules/connectors/freightcom/karrio/schemas/freightcom/error.py index 91dd55dbe7..7d58ea5d4e 100644 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/error.py +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/error.py @@ -1,1859 +1,14 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +from attr import s +from typing import Optional +from jstruct import JStruct -# -# Generated Fri Oct 21 12:33:21 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/error.py') -# -# Command line arguments: -# ./vendor/schemas/error.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/error.py" ./vendor/schemas/error.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# -import sys +@s(auto_attribs=True) +class DataType: + details_destination_signature_requirement: Optional[str] = None -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, version=None, ErrorReply=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.ErrorReply = ErrorReply - self.ErrorReply_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_ErrorReply(self): - return self.ErrorReply - - def set_ErrorReply(self, ErrorReply): - self.ErrorReply = ErrorReply - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.ErrorReply is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.ErrorReply is not None: - namespaceprefix_ = ( - self.ErrorReply_nsprefix_ + ":" - if (UseCapturedNS_ and self.ErrorReply_nsprefix_) - else "" - ) - self.ErrorReply.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="ErrorReply", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "ErrorReply": - obj_ = ErrorReplyType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.ErrorReply = obj_ - obj_.original_tagname_ = "ErrorReply" - - -# end class Freightcom - - -class ErrorReplyType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, Error=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.Error = Error - self.Error_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ErrorReplyType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ErrorReplyType.subclass: - return ErrorReplyType.subclass(*args_, **kwargs_) - else: - return ErrorReplyType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Error(self): - return self.Error - - def set_Error(self, Error): - self.Error = Error - - def _hasContent(self): - if self.Error is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ErrorReplyType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ErrorReplyType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ErrorReplyType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ErrorReplyType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ErrorReplyType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ErrorReplyType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ErrorReplyType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.Error is not None: - namespaceprefix_ = ( - self.Error_nsprefix_ + ":" - if (UseCapturedNS_ and self.Error_nsprefix_) - else "" - ) - self.Error.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Error", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Error": - obj_ = ErrorType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Error = obj_ - obj_.original_tagname_ = "Error" - - -# end class ErrorReplyType - - -class ErrorType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, Message=None, valueOf_=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.Message = _cast(None, Message) - self.Message_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ErrorType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ErrorType.subclass: - return ErrorType.subclass(*args_, **kwargs_) - else: - return ErrorType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Message(self): - return self.Message - - def set_Message(self, Message): - self.Message = Message - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ErrorType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ErrorType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ErrorType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ErrorType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ErrorType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="ErrorType" - ): - if self.Message is not None and "Message" not in already_processed: - already_processed.add("Message") - outfile.write( - " Message=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.Message), input_name="Message" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ErrorType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("Message", node) - if value is not None and "Message" not in already_processed: - already_processed.add("Message") - self.Message = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ErrorType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from error import *\n\n") - sys.stdout.write("import error as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/xml/XMLSchema": []} - -__all__ = ["ErrorReplyType", "ErrorType", "Freightcom"] +@s(auto_attribs=True) +class ErrorType: + message: Optional[str] = None + data: Optional[DataType] = JStruct[DataType] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/rate_request.py b/modules/connectors/freightcom/karrio/schemas/freightcom/rate_request.py new file mode 100644 index 0000000000..5ee52b6086 --- /dev/null +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/rate_request.py @@ -0,0 +1,173 @@ +from attr import s +from typing import Optional, List +from jstruct import JStruct, JList + + +@s(auto_attribs=True) +class AddressType: + address_line_1: Optional[str] = None + address_line_2: Optional[str] = None + unit_number: Optional[str] = None + city: Optional[str] = None + region: Optional[str] = None + country: Optional[str] = None + postal_code: Optional[str] = None + + +@s(auto_attribs=True) +class PhoneNumberType: + number: Optional[str] = None + extension: Optional[int] = None + + +@s(auto_attribs=True) +class ReadyType: + hour: Optional[int] = None + minute: Optional[int] = None + + +@s(auto_attribs=True) +class DestinationType: + name: Optional[str] = None + address: Optional[AddressType] = JStruct[AddressType] + residential: Optional[bool] = None + tailgate_required: Optional[bool] = None + instructions: Optional[str] = None + contact_name: Optional[str] = None + phone_number: Optional[PhoneNumberType] = JStruct[PhoneNumberType] + email_addresses: List[str] = [] + receives_email_updates: Optional[bool] = None + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + signature_requirement: Optional[str] = None + + +@s(auto_attribs=True) +class ExpectedShipDateType: + year: Optional[int] = None + month: Optional[int] = None + day: Optional[int] = None + + +@s(auto_attribs=True) +class WeightType: + unit: Optional[str] = None + value: Optional[float] = None + + +@s(auto_attribs=True) +class CourierpakMeasurementsType: + weight: Optional[WeightType] = JStruct[WeightType] + + +@s(auto_attribs=True) +class CourierpakType: + measurements: Optional[CourierpakMeasurementsType] = JStruct[CourierpakMeasurementsType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class DangerousGoodsDetailsType: + packaging_group: Optional[str] = None + goods_class: Optional[str] = None + description: Optional[str] = None + united_nations_number: Optional[str] = None + emergency_contact_name: Optional[str] = None + emergency_contact_phone_number: Optional[PhoneNumberType] = JStruct[PhoneNumberType] + + +@s(auto_attribs=True) +class TotalCostType: + currency: Optional[str] = None + value: Optional[int] = None + + +@s(auto_attribs=True) +class InsuranceType: + type: Optional[str] = None + total_cost: Optional[TotalCostType] = JStruct[TotalCostType] + + +@s(auto_attribs=True) +class CuboidType: + unit: Optional[str] = None + l: Optional[int] = None + w: Optional[int] = None + h: Optional[int] = None + + +@s(auto_attribs=True) +class PackageMeasurementsType: + weight: Optional[WeightType] = JStruct[WeightType] + cuboid: Optional[CuboidType] = JStruct[CuboidType] + + +@s(auto_attribs=True) +class PackageType: + measurements: Optional[PackageMeasurementsType] = JStruct[PackageMeasurementsType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class InBondDetailsType: + type: Optional[str] = None + name: Optional[str] = None + address: Optional[str] = None + contact_method: Optional[str] = None + contact_email_address: Optional[str] = None + contact_phone_number: Optional[PhoneNumberType] = JStruct[PhoneNumberType] + + +@s(auto_attribs=True) +class PalletServiceDetailsType: + limited_access_delivery_type: Optional[str] = None + limited_access_delivery_other_name: Optional[str] = None + in_bond: Optional[bool] = None + in_bond_details: Optional[InBondDetailsType] = JStruct[InBondDetailsType] + appointment_delivery: Optional[bool] = None + protect_from_freeze: Optional[bool] = None + threshold_pickup: Optional[bool] = None + threshold_delivery: Optional[bool] = None + + +@s(auto_attribs=True) +class PalletType: + measurements: Optional[PackageMeasurementsType] = JStruct[PackageMeasurementsType] + description: Optional[str] = None + freight_class: Optional[str] = None + nmfc: Optional[str] = None + contents_type: Optional[str] = None + num_pieces: Optional[int] = None + + +@s(auto_attribs=True) +class PackagingPropertiesType: + pallet_type: Optional[str] = None + has_stackable_pallets: Optional[bool] = None + dangerous_goods: Optional[str] = None + dangerous_goods_details: Optional[DangerousGoodsDetailsType] = JStruct[DangerousGoodsDetailsType] + pallets: List[PalletType] = JList[PalletType] + packages: List[PackageType] = JList[PackageType] + courierpaks: List[CourierpakType] = JList[CourierpakType] + includes_return_label: Optional[bool] = None + special_handling_required: Optional[bool] = None + has_dangerous_goods: Optional[bool] = None + pallet_service_details: Optional[PalletServiceDetailsType] = JStruct[PalletServiceDetailsType] + insurance: Optional[InsuranceType] = JStruct[InsuranceType] + + +@s(auto_attribs=True) +class DetailsType: + origin: Optional[DestinationType] = JStruct[DestinationType] + destination: Optional[DestinationType] = JStruct[DestinationType] + expected_ship_date: Optional[ExpectedShipDateType] = JStruct[ExpectedShipDateType] + packaging_type: Optional[str] = None + packaging_properties: Optional[PackagingPropertiesType] = JStruct[PackagingPropertiesType] + reference_codes: List[str] = [] + + +@s(auto_attribs=True) +class RateRequestType: + services: List[str] = [] + excluded_services: List[str] = [] + details: Optional[DetailsType] = JStruct[DetailsType] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/rate_response.py b/modules/connectors/freightcom/karrio/schemas/freightcom/rate_response.py new file mode 100644 index 0000000000..95a8c5f0b1 --- /dev/null +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/rate_response.py @@ -0,0 +1,49 @@ +from attr import s +from typing import Optional, List +from jstruct import JStruct, JList + + +@s(auto_attribs=True) +class BaseType: + currency: Optional[str] = None + value: Optional[int] = None + + +@s(auto_attribs=True) +class SurchargeType: + type: Optional[str] = None + amount: Optional[BaseType] = JStruct[BaseType] + + +@s(auto_attribs=True) +class ValidUntilType: + year: Optional[int] = None + month: Optional[int] = None + day: Optional[int] = None + + +@s(auto_attribs=True) +class RateType: + carrier_name: Optional[str] = None + service_name: Optional[str] = None + service_id: Optional[str] = None + valid_until: Optional[ValidUntilType] = JStruct[ValidUntilType] + total: Optional[BaseType] = JStruct[BaseType] + base: Optional[BaseType] = JStruct[BaseType] + surcharges: List[SurchargeType] = JList[SurchargeType] + taxes: List[SurchargeType] = JList[SurchargeType] + transit_time_days: Optional[int] = None + transit_time_not_available: Optional[bool] = None + + +@s(auto_attribs=True) +class StatusType: + done: Optional[bool] = None + total: Optional[int] = None + complete: Optional[int] = None + + +@s(auto_attribs=True) +class RateResponseType: + status: Optional[StatusType] = JStruct[StatusType] + rates: List[RateType] = JList[RateType] From 2cb671b2678582ac916c45f535916a2122273fac Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Thu, 23 Jan 2025 16:38:53 -0500 Subject: [PATCH 05/14] Implement Freightcom Ship and Cancel REST API --- modules/connectors/freightcom/generate | 12 +- .../karrio/mappers/freightcom/mapper.py | 43 +- .../karrio/mappers/freightcom/proxy.py | 131 +- .../karrio/providers/freightcom/__init__.py | 15 +- .../karrio/providers/freightcom/error.py | 30 +- .../karrio/providers/freightcom/rate.py | 45 +- .../providers/freightcom/shipment/__init__.py | 9 + .../providers/freightcom/shipment/cancel.py | 31 + .../providers/freightcom/shipment/create.py | 333 + .../karrio/providers/freightcom/shipping.py | 294 - .../karrio/providers/freightcom/units.py | 29 +- .../karrio/providers/freightcom/utils.py | 13 +- .../providers/freightcom/void_shipment.py | 50 - .../{error.py => error_response.py} | 4 +- .../schemas/freightcom/pickup_request.py | 46 + .../karrio/schemas/freightcom/quote_reply.py | 2555 ------- .../schemas/freightcom/quote_request.py | 4522 ------------ .../freightcom/shipment_cancel_reply.py | 2063 ------ .../freightcom/shipment_cancel_request.py | 1915 ----- .../schemas/freightcom/shipping_reply.py | 4236 ----------- .../schemas/freightcom/shipping_request.py | 6197 +---------------- .../schemas/freightcom/shipping_response.py | 224 + .../schemas/freightcom/tracking_response.py | 23 + .../freightcom/schemas/error_response.json | 6 +- .../freightcom/schemas/pickup_request.json | 39 + .../freightcom/schemas/shipping_request.json | 267 + .../freightcom/schemas/shipping_response.json | 228 + .../freightcom/schemas/tracking_response.json | 14 + 28 files changed, 1612 insertions(+), 21762 deletions(-) create mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py create mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py create mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py delete mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/shipping.py delete mode 100644 modules/connectors/freightcom/karrio/providers/freightcom/void_shipment.py rename modules/connectors/freightcom/karrio/schemas/freightcom/{error.py => error_response.py} (72%) create mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/pickup_request.py delete mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/quote_reply.py delete mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/quote_request.py delete mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_reply.py delete mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_request.py delete mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/shipping_reply.py create mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/shipping_response.py create mode 100644 modules/connectors/freightcom/karrio/schemas/freightcom/tracking_response.py create mode 100644 modules/connectors/freightcom/schemas/pickup_request.json create mode 100644 modules/connectors/freightcom/schemas/shipping_request.json create mode 100644 modules/connectors/freightcom/schemas/shipping_response.json create mode 100644 modules/connectors/freightcom/schemas/tracking_response.json diff --git a/modules/connectors/freightcom/generate b/modules/connectors/freightcom/generate index 8a128cd13d..2f09af4468 100755 --- a/modules/connectors/freightcom/generate +++ b/modules/connectors/freightcom/generate @@ -14,10 +14,8 @@ quicktype() { quicktype --src="${SCHEMAS}/rate_request.json" --out="${LIB_MODULES}/rate_request.py" quicktype --src="${SCHEMAS}/rate_response.json" --out="${LIB_MODULES}/rate_response.py" -quicktype --src="${SCHEMAS}/error_response.json" --out="${LIB_MODULES}/error.py" - -# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_request.py" $SCHEMAS/shipping_request.xsd -# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipping_reply.py" $SCHEMAS/shipping_reply.xsd -# generateDS --no-namespace-defs -o "${LIB_MODULES}/error.py" $SCHEMAS/error.xsd -# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_request.py" $SCHEMAS/shipment_cancel_request.xsd -# generateDS --no-namespace-defs -o "${LIB_MODULES}/shipment_cancel_reply.py" $SCHEMAS/shipment_cancel_reply.xsd +quicktype --src="${SCHEMAS}/error_response.json" --out="${LIB_MODULES}/error_response.py" +quicktype --src="${SCHEMAS}/shipping_request.json" --out="${LIB_MODULES}/shipping_request.py" +quicktype --src="${SCHEMAS}/shipping_response.json" --out="${LIB_MODULES}/shipping_response.py" +quicktype --src="${SCHEMAS}/pickup_request.json" --out="${LIB_MODULES}/pickup_request.py" +quicktype --src="${SCHEMAS}/tracking_response.json" --out="${LIB_MODULES}/tracking_response.py" diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py b/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py index 61bc514b4c..684a75b0b9 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py @@ -2,23 +2,8 @@ from karrio.api.mapper import Mapper as BaseMapper from karrio.mappers.freightcom.settings import Settings from karrio.core.utils.serializable import Deserializable, Serializable -from karrio.core.models import ( - RateRequest, - ShipmentRequest, - ShipmentDetails, - RateDetails, - Message, - ShipmentCancelRequest, - ConfirmationDetails, -) -from karrio.providers.freightcom import ( - parse_rate_response, - rate_request, - parse_shipping_reply, - shipping_request, - shipment_cancel_request, - parse_shipment_cancel_reply, -) +import karrio.core.models as models +import karrio.providers.freightcom as provider class Mapper(BaseMapper): @@ -26,30 +11,30 @@ class Mapper(BaseMapper): # Request Mappers - def create_rate_request(self, payload: RateRequest) -> Serializable: - return rate_request(payload, self.settings) + def create_rate_request(self, payload: models.RateRequest) -> Serializable: + return provider.rate_request(payload, self.settings) - def create_shipment_request(self, payload: ShipmentRequest) -> Serializable: - return shipping_request(payload, self.settings) + def create_shipment_request(self, payload: models.ShipmentRequest) -> Serializable: + return provider.create_shipment_request(payload, self.settings) def create_cancel_shipment_request( - self, payload: ShipmentCancelRequest + self, payload: models.ShipmentCancelRequest ) -> Serializable: - return shipment_cancel_request(payload, self.settings) + return provider.shipment_cancel_request(payload, self.settings) # Response Parsers def parse_rate_response( self, response: Deserializable - ) -> Tuple[List[RateDetails], List[Message]]: - return parse_rate_response(response, self.settings) + ) -> Tuple[List[models.RateDetails], List[models.Message]]: + return provider.parse_rate_response(response, self.settings) def parse_shipment_response( self, response: Deserializable - ) -> Tuple[ShipmentDetails, List[Message]]: - return parse_shipping_reply(response, self.settings) + ) -> Tuple[models.ShipmentDetails, List[models.Message]]: + return provider.parse_shipment_response(response, self.settings) def parse_cancel_shipment_response( self, response: Deserializable - ) -> Tuple[ConfirmationDetails, List[Message]]: - return parse_shipment_cancel_reply(response, self.settings) + ) -> Tuple[models.ConfirmationDetails, List[models.Message]]: + return provider.parse_shipment_cancel_response(response, self.settings) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py index 419220f55a..9cdb10abdd 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py @@ -11,92 +11,97 @@ class Proxy(proxy.Proxy): MAX_RETRIES = 10 POLL_INTERVAL = 2 # seconds - def get_rates(self, request: lib.Serializable) -> lib.Deserializable[str]: + def get_rates(self, request: lib.Serializable) -> lib.Deserializable: # Step 1: Submit rate request and get quote ID - response = lib.request( - url=f"{self.settings.server_url}/rate", - data=lib.to_json(request.serialize()), - trace=self.trace_as("json"), - method="POST", - headers={ - "Accept": "application/json", - "Content-Type": "application/json", - "Authorization": f"{self.settings.api_key}", - }, + response = self._send_request( + path="/rate", request=lib.Serializable(request.value, lib.to_json) ) - res = lib.Deserializable(response, lib.to_dict) - rate_id = res.deserialize().get('request_id') + rate_id = lib.to_dict(response).get('request_id') if not rate_id: - return res + return lib.Deserializable(response, lib.to_dict) # Step 2: Poll for rate results for _ in range(self.MAX_RETRIES): - quote_response = lib.request( - url=f"{self.settings.server_url}/rate/{rate_id}", - trace=self.trace_as("json"), - method="GET", - headers={ - "Accept": "application/json", - "Content-Type": "application/json", - "Authorization": f"{self.settings.api_key}", - }, + status_res = self._send_request( + path=f"/rate/{rate_id}", + method="GET" ) - status_res = lib.Deserializable(quote_response, lib.to_dict) - status = status_res.deserialize().get('status', {}).get('done', False) + status = lib.to_dict(status_res).get('status', {}).get('done', False) if status: # Quote is complete - return status_res + return lib.Deserializable(status_res, lib.to_dict) time.sleep(self.POLL_INTERVAL) # If we exceed max retries return lib.Deserializable({ - 'error': 'Rate calculation timed out' + 'message': 'Rate calculation timed out' }, lib.to_dict) - def create_shipment(self, request: lib.Serializable) -> lib.Deserializable[str]: - response = lib.request( - url=f"{self.settings.server_url}/v2/shipments", - data=lib.to_json(request.serialize()), - trace=self.trace_as("json"), - method="POST", - headers={ - "Accept": "application/json", - "Content-Type": "application/json", - "Authorization": f"Bearer {self.settings.api_key}", - }, - ) + def create_shipment(self, request: lib.Serializable) -> lib.Deserializable: + + response = self._send_request( + path="/shipment", request=lib.Serializable(request.value, lib.to_json) + ) + + shipment_id = lib.to_dict(response).get('id') + if not shipment_id: + return lib.Deserializable(response, lib.to_dict) + + + # Step 2: retry because api return empty bytes if done to fast + time.sleep(1) + for _ in range(self.MAX_RETRIES): + + shipment_response = self._send_request(path=f"/shipment/{shipment_id}", method="GET") + shipment_res = lib.failsafe(lambda :lib.to_dict(shipment_response)) or lib.decode(shipment_response) + + if shipment_res: # is complete + return lib.Deserializable(shipment_res, lib.to_dict, request.ctx) + + time.sleep(self.POLL_INTERVAL) + + # If we exceed max retries + return lib.Deserializable({ + 'message': 'timed out' + }, lib.to_dict) - return lib.Deserializable(response, lib.to_dict) def get_tracking(self, request: lib.Serializable) -> lib.Deserializable[str]: - tracking_id = request.serialize()["tracking_id"] - response = lib.request( - url=f"{self.settings.server_url}/v2/track/{tracking_id}", - trace=self.trace_as("json"), - method="GET", - headers={ - "Accept": "application/json", - "Content-Type": "application/json", - "Authorization": f"Bearer {self.settings.api_key}", - }, - ) + response = self._send_request(path=f"/shipment/{request.serialize()}/tracking-events") return lib.Deserializable(response, lib.to_dict) - def cancel_shipment(self, request: lib.Serializable) -> lib.Deserializable[str]: - tracking_id = request.serialize()["tracking_id"] - response = lib.request( - url=f"{self.settings.server_url}/v2/track/{tracking_id}", - trace=self.trace_as("json"), - method="GET", - headers={ - "Accept": "application/json", - "Content-Type": "application/json", - "Authorization": f"Bearer {self.settings.api_key}", - }, + # TODO: not sure how this can be a dynamic unit Enum, and cached for now i hard code the id in the ship request + def get_payments_methods(self, request: lib.Serializable) -> lib.Deserializable[str]: + response = self._send_request( + path="/finance/payment-methods", + method="GET" ) - return lib.Deserializable(response, lib.to_dict) + + def cancel_shipment(self, request: lib.Serializable) -> lib.Deserializable: + response = self._send_request( + path=f"/shipment/{request.serialize()}", method="DELETE" + ) + return lib.Deserializable(response if any(response) else "{}", lib.to_dict) + + def _send_request( + self, path: str, request: lib.Serializable = None, method: str = "POST" + ) -> str: + + data: dict = dict(data=request.serialize()) if request is not None else dict() + return lib.request( + **{ + "url": f"{self.settings.server_url}{path}", + "trace": self.trace_as("json"), + "method": method, + "headers": { + "Content-Type": "application/json", + "Authorization": self.settings.api_key, + }, + **data, + } + ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py b/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py index 86744b8550..1e1d8bd406 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py @@ -1,6 +1,13 @@ + from karrio.providers.freightcom.rate import parse_rate_response, rate_request -from karrio.providers.freightcom.shipping import ( - parse_shipping_reply, - shipping_request, +from karrio.providers.freightcom.shipment import ( + parse_shipment_response, + create_shipment_request, + parse_shipment_cancel_response, + shipment_cancel_request, ) -from karrio.providers.freightcom.void_shipment import shipment_cancel_request, parse_shipment_cancel_reply + +# from karrio.providers.eshipper.tracking import ( +# parse_tracking_response, +# tracking_request, +# ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/error.py b/modules/connectors/freightcom/karrio/providers/freightcom/error.py index 83787fe884..acc0222409 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/error.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/error.py @@ -1,9 +1,7 @@ import typing -import karrio.lib as lib import karrio.core.models as models import karrio.providers.freightcom.utils as provider_utils - def parse_error_response( response: dict, settings: provider_utils.Settings, @@ -13,40 +11,16 @@ def parse_error_response( errors = [ *[_ for _ in responses if _.get("message")], - # *sum( - # [ - # [dict(code="warning", message=__) for __ in _.get("warnings")] - # for _ in responses - # if _.get("warnings") - # ], - # [], - # ), - # *sum( - # [ - # [ - # dict( - # code="error", - # message=order["message"] - # ) - # for order in _.get("order", []) - # if "message" in order and order["message"].startswith("Error") - # ] - # for _ in responses - # ], - # [], - # ) ] + return [ models.Message( carrier_id=settings.carrier_id, carrier_name=settings.carrier_name, - code=error.get("code"), message=error.get("message"), details={ **kwargs, - "type": error.get("type"), - "fieldErrors": error.get("fieldErrors"), - "thirdPartyMessage": error.get("thirdPartyMessage"), + **(error.get('data', {})) }, ) for error in errors diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py index 003b0c877e..617b35e25b 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py @@ -53,8 +53,8 @@ def _extract_details( if charges ], meta=dict( - rate_provider=courier.name, - service_name=service.name , + rate_provider=courier.name_or_key, + service_name=service.name_or_key , ), ) @@ -78,7 +78,7 @@ def rate_request( ) request = freightcom.RateRequestType( - services=payload.services or [], + services=[provider_units.ShippingService.map(service).value_or_key for service in payload.services], excluded_services=[], details=freightcom.DetailsType( origin=freightcom.DestinationType( @@ -141,49 +141,49 @@ def rate_request( ) if options.dangerous_goods.state else None, pallets=[ freightcom.PalletType( - measurements=freightcom.PalletMeasurementsType( + measurements=freightcom.PackageMeasurementsType( weight=freightcom.WeightType( - unit="kg" if parcel.weight_unit.upper() == "KG" else "lb", - value=lib.to_decimal(parcel.weight) + unit="kg", + value=parcel.weight.KG ), cuboid=freightcom.CuboidType( - unit="cm" if parcel.dimension_unit.upper() == "CM" else "in", - l=lib.to_int(parcel.length), - w=lib.to_int(parcel.width), - h=lib.to_int(parcel.height) + unit="cm", + l=parcel.length.CM, + w=parcel.width.CM, + h=parcel.height.CM ) ), description=parcel.description, freight_class=options.freight_class.state, - ) for parcel in payload.parcels + ) for parcel in packages ] if packaging_type == "pallet" else [], packages=[ freightcom.PackageType( measurements=freightcom.PackageMeasurementsType( weight=freightcom.WeightType( - unit="kg" if parcel.weight_unit.upper() == "KG" else "lb", - value=lib.to_decimal(parcel.weight) + unit="kg", + value=parcel.weight.KG ), cuboid=freightcom.CuboidType( - unit="cm" if parcel.dimension_unit.upper() == "CM" else "in", - l=lib.to_int(parcel.length), - w=lib.to_int(parcel.width), - h=lib.to_int(parcel.height) + unit="cm", + l=parcel.length.CM, + w=parcel.width.CM, + h=parcel.height.CM ) ), description=parcel.description, - ) for parcel in payload.parcels + ) for parcel in packages ] if packaging_type == "package" else [], courierpaks=[ freightcom.CourierpakType( measurements=freightcom.CourierpakMeasurementsType( weight=freightcom.WeightType( - unit="kg" if parcel.weight_unit.upper() == "KG" else "lb", - value=lib.to_decimal(parcel.weight) - ) + unit="kg", + value=parcel.weight.KG + ), ), description=parcel.description, - ) for parcel in payload.parcels + ) for parcel in packages ] if packaging_type == "courier-pak" else [], insurance=freightcom.InsuranceType( type='carrier', @@ -199,7 +199,6 @@ def rate_request( reference_codes=[payload.reference] if payload.reference else [] ) ) - return lib.Serializable(request, lib.to_dict) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py new file mode 100644 index 0000000000..ee61d33cbc --- /dev/null +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py @@ -0,0 +1,9 @@ +from karrio.providers.freightcom.shipment.create import ( + parse_shipment_response, + create_shipment_request, +) + +from karrio.providers.freightcom.shipment.cancel import ( + parse_shipment_cancel_response, + shipment_cancel_request, +) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py new file mode 100644 index 0000000000..41352e30f9 --- /dev/null +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py @@ -0,0 +1,31 @@ +import typing +import karrio.lib as lib +import karrio.core.models as models +import karrio.providers.freightcom.error as error +import karrio.providers.freightcom.utils as provider_utils + + +def parse_shipment_cancel_response( + _response: lib.Deserializable[dict], + settings: provider_utils.Settings, +) -> typing.Tuple[models.ConfirmationDetails, typing.List[models.Message]]: + response = _response.deserialize() + messages = error.parse_error_response(response, settings) + success = not any(messages) + + confirmation = ( + models.ConfirmationDetails( + carrier_id=settings.carrier_id, + carrier_name=settings.carrier_name, + operation="Cancel Shipment", + success=success, + ) + if success + else None + ) + + return confirmation, messages + + +def shipment_cancel_request(payload: models.ShipmentCancelRequest, _) -> lib.Serializable: + return lib.Serializable(payload.shipment_identifier) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py new file mode 100644 index 0000000000..12a6e80952 --- /dev/null +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py @@ -0,0 +1,333 @@ +import karrio.schemas.freightcom.shipping_request as freightcom +import karrio.schemas.freightcom.shipping_response as shipping +import typing +import datetime +import uuid +import karrio.lib as lib +import karrio.core.models as models +import karrio.providers.freightcom.error as error +import karrio.providers.freightcom.utils as provider_utils +import karrio.providers.freightcom.units as provider_units + + +def parse_shipment_response( + _response: lib.Deserializable[dict], + settings: provider_utils.Settings, +) -> typing.Tuple[models.ShipmentDetails, typing.List[models.Message]]: + """Parse Freightcom shipping response into Karrio format""" + response = _response.deserialize() + messages = error.parse_error_response(response, settings) + + # shipment = lib.to_multi_piece_shipment( + # [ + # (index, _extract_details(data, data.get("shipmentId"), settings)) + # for index, data in enumerate(response.get("labels", [])) + # ] + # ) + # + + shipment = _extract_details(response.get("shipment", {}), settings, ctx=_response.ctx) if "shipment" in response else None + return shipment, messages + + +def _extract_details( + data: dict, + settings: provider_utils.Settings, + ctx: dict, +) -> models.ShipmentDetails: + shipment = lib.to_object(shipping.ShipmentType, data) + label_type = "ZPL" if ctx["label_type"] == "ZPL" else "PDF" + label_url = [_.url for _ in shipment.labels if _.format == label_type.lower() and _.size == "a6" and not _.padded] + label = provider_utils.download_label(label_url[0]) if label_url else None + tracking_numbers = ( + [ + shipment.primary_tracking_number + ] + + [ + tn for tn in shipment.tracking_numbers + if tn != shipment.primary_tracking_number + ] + ) + + rate = shipment.rate + service = provider_units.ShippingService.map( + rate.service_id, + ) + + courier = provider_units.ShippingCourier.find(rate.service_id) + + return models.ShipmentDetails( + carrier_id=settings.carrier_id, + carrier_name=settings.carrier_name, + tracking_number=shipment.primary_tracking_number, + shipment_identifier=shipment.id, + label_type=label_type, + docs=models.Documents(label=label), + meta=dict( + carrier_tracking_link=shipment.tracking_url, + tracking_numbers=tracking_numbers, + rate_provider=courier.name_or_key, + service_name=service.name_or_key, + freightcom_service_id=rate.service_id, + freightcom_unique_id=shipment.unique_id, + + ) + ) + + +def create_shipment_request( + payload: models.ShipmentRequest, + settings: provider_utils.Settings, +) -> lib.Serializable: + + + shipper = lib.to_address(payload.shipper) + recipient = lib.to_address(payload.recipient) + packages = lib.to_packages(payload.parcels) + options = lib.to_shipping_options( + payload.options, + package_options=packages.options, + initializer=provider_units.shipping_options_initializer, + ) + + packaging_type = provider_units.PackagingType.map( + packages.package_type or "small_box" + ).value + + is_intl = shipper.country_code != recipient.country_code + customs = lib.to_customs_info( + payload.customs, + shipper=payload.shipper, + recipient=payload.recipient, + weight_unit=packages.weight_unit, + default_to=( + models.Customs( + commodities=( + packages.items + if any(packages.items) + else [ + models.Commodity( + quantity=1, + sku=f"000{index}", + weight=pkg.weight.value, + weight_unit=pkg.weight_unit.value, + description=pkg.parcel.content, + ) + for index, pkg in enumerate(packages, start=1) + ] + ) + ) + if is_intl + else None + ), + ) + + # TODO: need to know how to make this to get the payment_method ID, it's unique on each account, and not sure where this code belongs + + # payment_methods_response = proxy.get_payments_methods(lib.Serializable(None)) + # payment_methods = payment_methods_response.deserialize() + # + # # Get requested payment type or default to net_terms + # requested_type = (payload.payment.type + # if payload and payload.payment and payload.payment.type + # else provider_units.PaymentMethodType.map().value) + # + # # Filter payment methods by type + # filtered_methods = [ + # method for method in payment_methods + # if method.get('type') == provider_units.PaymentMethodType.map( + # options.freightcom_payment_method or "net_terms" + # ) + # ] + + # payment_method_id = filtered_methods[0].get('id') if filtered_methods else payment_methods[0].get('id') + # + # if not payment_method_id: + # raise Exception("No payment method found") + payment_method_id = '3PQtJaY49gIWzEVJ5DZrP8VP0vH1ZgWU' + + + request = freightcom.ShippingRequestType( + unique_id=str(uuid.uuid4()), + payment_method_id=payment_method_id, + service_id=provider_units.ShippingService.map(payload.service).value_or_key, + details=freightcom.ShippingRequestDetailsType( + origin=freightcom.DestinationType( + name=shipper.company_name or shipper.person_name, + address=freightcom.AddressType( + address_line_1=shipper.address_line1, + address_line_2=shipper.address_line2, + city=shipper.city, + region=shipper.state_code, + country=shipper.country_code, + postal_code=shipper.postal_code, + ), + residential=shipper.residential, + contact_name=shipper.person_name if shipper.company_name else "", + phone_number=freightcom.NumberType( + number=shipper.phone_number + ) if shipper.phone_number else None, + email_addresses=[shipper.email] if shipper.email else [], + ), + destination=freightcom.DestinationType( + name=recipient.company_name or recipient.person_name, + address=freightcom.AddressType( + address_line_1=recipient.address_line1, + address_line_2=recipient.address_line2, + city=recipient.city, + region=recipient.state_code, + country=recipient.country_code, + postal_code=recipient.postal_code, + ), + residential=recipient.residential, + contact_name=recipient.person_name, + phone_number=freightcom.NumberType( + number=recipient.phone_number + ) if recipient.phone_number else None, + email_addresses=[recipient.email] if recipient.email else [], + ready_at=freightcom.ReadyType( + hour=lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M" + ).hour, + minute=0 + ), + ready_until=freightcom.ReadyType( + hour=17, + minute=0 + ), + signature_requirement="required" if options.signature_confirmation.state else "not-required" + ), + expected_ship_date=freightcom.DateType( + year=lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M" + ).year, + month=lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M" + ).month, + day=lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M" + ).day, + ), + packaging_type=packaging_type, + packaging_properties=freightcom.PackagingPropertiesType( + pallet_type="ltl" if packaging_type == "pallet" else None, + has_stackable_pallets=options.stackable.state if packaging_type == "pallet" else None, + dangerous_goods=options.dangerous_goods.state, + dangerous_goods_details=freightcom.DangerousGoodsDetailsType( + packaging_group=options.dangerous_goods_group.state, + goods_class=options.dangerous_goods_class.state, + ) if options.dangerous_goods.state else None, + pallets=[ + freightcom.PalletType( + measurements=freightcom.PackageMeasurementsType( + weight=freightcom.WeightType( + unit="kg", + value=parcel.weight.KG + ), + cuboid=freightcom.CuboidType( + unit="cm", + l=parcel.length.CM, + w=parcel.width.CM, + h=parcel.height.CM + ) + ), + description=parcel.description or "N/A", + freight_class=options.freight_class.state, + ) for parcel in packages + ] if packaging_type == "pallet" else [], + packages=[ + freightcom.PackageType( + measurements=freightcom.PackageMeasurementsType( + weight=freightcom.WeightType( + unit="kg", + value=parcel.weight.KG + ), + cuboid=freightcom.CuboidType( + unit="cm", + l=parcel.length.CM, + w=parcel.width.CM, + h=parcel.height.CM + ) + ), + description=parcel.description or "N/A", + ) for parcel in packages + ] if packaging_type == "package" else [], + courierpaks=[ + freightcom.CourierpakType( + measurements=freightcom.CourierpakMeasurementsType( + weight=freightcom.WeightType( + unit="kg", + value=parcel.weight.KG + ), + ), + description=parcel.description or "N/A", + ) for parcel in packages + ] if packaging_type == "courier-pak" else [], + ), + reference_codes=[payload.reference] if payload.reference else [] + ), + customs_invoice=( + freightcom.CustomsInvoiceType( + source="details", + broker=freightcom.BrokerType( + use_carrier=True, + ), + details=freightcom.CustomsInvoiceDetailsType( + products=[ + freightcom.ProductType( + product_name=item.description, + weight=freightcom.WeightType( + unit="kg" if item.weight_unit.upper() == "KG" else "lb", + value=lib.to_decimal(item.weight) + ), + hs_code=item.hs_code, + country_of_origin=item.origin_country, + num_units=item.quantity, + unit_price=freightcom.TotalCostType( + currency=item.value_currency, + value=str(item.value_amount) + ), + description=item.description + ) for item in customs.commodities + ], + tax_recipient=freightcom.TaxRecipientType( + type=provider_units.PaymentType.map( + customs.duty.paid_by + ).value + or "shipper", + name=customs.duty_billing_address.company_name or customs.duty.person_name, + address=freightcom.AddressType( + address_line_1=customs.duty_billing_address.address_line1, + address_line_2=customs.duty_billing_address.address_line2, + city=customs.duty_billing_address.city, + region=customs.duty_billing_address.state_code, + country=customs.duty_billing_address.country_code, + postal_code=customs.duty_billing_address.postal_code, + ), + phone_number=freightcom.NumberType( + number=customs.duty_billing_address.phone_number + ), + reason_for_export=provider_units.CustomsContentType.map( + customs.content_type + ).value, + ) + ) + ) + if customs and customs.commodities + else None + ), + #TODO: validate if we need to do pickup in the ship request + # pickup_details=freightcom.PickupDetailsType( + # + # ) + ) + + return lib.Serializable( + request, + lib.to_dict, + dict(label_type=payload.label_type or "PDF") + ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py deleted file mode 100644 index e23d2c5dae..0000000000 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipping.py +++ /dev/null @@ -1,294 +0,0 @@ -from karrio.schemas.freightcom.shipping_request import ( - Freightcom, - ShippingRequestType, - FromType, - ToType, - PackagesType, - PackageType, - PaymentType as RequestPaymentType, - CODType, - CODReturnAddressType, - ContactType, - ReferenceType, - CustomsInvoiceType, - ItemType, - BillToType, -) -from karrio.schemas.freightcom.shipping_reply import ( - ShippingReplyType, - QuoteType, -) - -import typing -import karrio.lib as lib -import karrio.core.models as models -import karrio.providers.freightcom.error as provider_error -import karrio.providers.freightcom.units as provider_units -import karrio.providers.freightcom.utils as provider_utils - - -def parse_shipping_reply( - _response: lib.Deserializable[lib.Element], - settings: provider_utils.Settings, -) -> typing.Tuple[models.ShipmentDetails, typing.List[models.Message]]: - response = _response.deserialize() - shipping_node = lib.find_element("ShippingReply", response, first=True) - shipment = ( - _extract_shipment(shipping_node, settings) - if shipping_node is not None - else None - ) - - return shipment, provider_error.parse_error_response(response, settings) - - -def _extract_shipment( - node: lib.Element, - settings: provider_utils.Settings, -) -> models.ShipmentDetails: - shipping = lib.to_object(ShippingReplyType, node) - quote: QuoteType = shipping.Quote or QuoteType() - - tracking_number = getattr( - next(iter(shipping.Package), None), "trackingNumber", None - ) - rate_provider, service, service_name = provider_units.ShippingService.info( - quote.serviceId, quote.carrierId, quote.serviceName, quote.carrierName - ) - invoice = dict(invoice=shipping.CustomsInvoice) if shipping.CustomsInvoice else {} - charges = [ - ("Base charge", quote.baseCharge), - ("Fuel surcharge", quote.fuelSurcharge), - *((surcharge.name, surcharge.amount) for surcharge in quote.Surcharge), - ] - - return models.ShipmentDetails( - carrier_name=settings.carrier_name, - carrier_id=settings.carrier_id, - tracking_number=tracking_number, - shipment_identifier=shipping.Order.id, - selected_rate=( - models.RateDetails( - carrier_name=settings.carrier_name, - carrier_id=settings.carrier_id, - service=service, - currency=quote.currency, - total_charge=lib.to_decimal(quote.totalCharge), - transit_days=quote.transitDays, - extra_charges=[ - models.ChargeDetails( - name=name, - currency="CAD", - amount=lib.to_decimal(amount), - ) - for name, amount in charges - if amount - ], - meta=dict(rate_provider=rate_provider, service_name=service_name), - ) - if shipping.Quote is not None - else None - ), - docs=models.Documents(label=shipping.Labels, **invoice), - meta=dict( - rate_provider=rate_provider, - service_name=service_name, - tracking_url=shipping.TrackingURL, - ), - ) - - -def shipping_request( - payload: models.ShipmentRequest, - settings: provider_utils.Settings, -) -> lib.Serializable: - shipper = lib.to_address(payload.shipper) - recipient = lib.to_address(payload.recipient) - service = provider_units.ShippingService.map(payload.service).value_or_key - packages = lib.to_packages( - payload.parcels, - package_option_type=provider_units.ShippingOption, - required=["weight", "height", "width", "length"], - ) - options = lib.to_shipping_options( - payload.options, - package_options=packages.options, - initializer=provider_units.shipping_options_initializer, - ) - - is_intl = shipper.country_code != recipient.country_code - customs = lib.to_customs_info( - payload.customs, - shipper=payload.shipper, - recipient=payload.recipient, - weight_unit=packages.weight_unit, - default_to=( - models.Customs( - commodities=( - packages.items - if any(packages.items) - else [ - models.Commodity( - quantity=1, - sku=f"000{index}", - weight=pkg.weight.value, - weight_unit=pkg.weight_unit.value, - description=pkg.parcel.content, - ) - for index, pkg in enumerate(packages, start=1) - ] - ) - ) - if is_intl - else None - ), - ) - - packaging_type = provider_units.PackagingType.map( - packages.package_type or "small_box" - ).value - packaging = ( - "Pallet" - if packaging_type in [provider_units.PackagingType.pallet.value] - else "Package" - ) - payment = payload.payment or models.Payment() - payment_type = ( - provider_units.PaymentType[payment.paid_by] if payload.payment else None - ) - - request = Freightcom( - version="3.1.0", - username=settings.username, - password=settings.password, - ShippingRequest=ShippingRequestType( - saturdayPickupRequired=options.freightcom_saturday_pickup_required.state, - homelandSecurity=options.freightcom_homeland_security.state, - pierCharge=None, - exhibitionConventionSite=options.freightcom_exhibition_convention_site.state, - militaryBaseDelivery=options.freightcom_military_base_delivery.state, - customsIn_bondFreight=options.freightcom_customs_in_bond_freight.state, - limitedAccess=options.freightcom_limited_access.state, - excessLength=options.freightcom_excess_length.state, - tailgatePickup=options.freightcom_tailgate_pickup.state, - residentialPickup=options.freightcom_residential_pickup.state, - crossBorderFee=None, - notifyRecipient=options.freightcom_notify_recipient.state, - singleShipment=options.freightcom_single_shipment.state, - tailgateDelivery=options.freightcom_tailgate_delivery.state, - residentialDelivery=options.freightcom_residential_delivery.state, - insuranceType=(options.insurance.state is not None), - scheduledShipDate=None, - insideDelivery=options.freightcom_inside_delivery.state, - isSaturdayService=options.freightcom_is_saturday_service.state, - dangerousGoodsType=options.freightcom_dangerous_goods_type.state, - serviceId=service, - stackable=options.freightcom_stackable.state, - From=FromType( - id=None, - company=shipper.company_name, - instructions=None, - email=shipper.email, - attention=shipper.person_name, - phone=shipper.phone_number, - tailgateRequired=None, - residential=shipper.residential, - address1=shipper.street, - address2=lib.text(shipper.address_line2), - city=shipper.city, - state=shipper.state_code, - zip=shipper.postal_code, - country=shipper.country_code, - ), - To=ToType( - id=None, - company=recipient.company_name, - notifyRecipient=None, - instructions=None, - email=recipient.email, - attention=recipient.person_name, - phone=recipient.phone_number, - tailgateRequired=None, - residential=recipient.residential, - address1=recipient.street, - address2=lib.text(recipient.address_line2), - city=recipient.city, - state=recipient.state_code, - zip=recipient.postal_code, - country=recipient.country_code, - ), - COD=( - CODType( - paymentType=provider_units.PaymentType.recipient.value, - CODReturnAddress=CODReturnAddressType( - codCompany=recipient.company_name, - codName=recipient.person_name, - codAddress1=lib.text(recipient.address_line1), - codCity=recipient.city, - codStateCode=recipient.state_code, - codZip=recipient.postal_code, - codCountry=recipient.country_code, - ), - ) - if options.cash_on_delivery.state is not None - else None - ), - Packages=PackagesType( - Package=[ - PackageType( - length=provider_utils.ceil(package.length.IN), - width=provider_utils.ceil(package.width.IN), - height=provider_utils.ceil(package.height.IN), - weight=provider_utils.ceil(package.weight.LB), - type_=packaging_type, - freightClass=package.parcel.freight_class, - nmfcCode=None, - insuranceAmount=package.options.insurance.state, - codAmount=package.options.cash_on_delivery.state, - description=package.parcel.description, - ) - for package in packages - ], - type_=packaging, - ), - Payment=(RequestPaymentType(type_=payment_type) if payment_type else None), - Reference=( - [ReferenceType(name="REF", code=payload.reference)] - if payload.reference != "" - else None - ), - CustomsInvoice=( - CustomsInvoiceType( - BillTo=BillToType( - company=customs.duty_billing_address.company_name, - name=customs.duty_billing_address.person_name, - address1=customs.duty_billing_address.address_line, - city=customs.duty_billing_address.city, - state=customs.duty_billing_address.state_code, - zip=customs.duty_billing_address.postal_code, - country=customs.duty_billing_address.country_code, - ), - Contact=ContactType( - name=customs.duty_billing_address.person_name, - phone=customs.duty_billing_address.phone_number, - ), - Item=[ - ItemType( - code=(item.hs_code or item.sku or "0000"), - description=lib.text( - item.description or item.title or "item" - ), - originCountry=(item.origin_country or shipper.country_code), - unitPrice=item.value_amount, - quantity=(item.quantity or 1), - ) - for item in customs.commodities - ], - ) - if payload.customs - else None - ), - ), - ) - - return lib.Serializable(request, provider_utils.standard_request_serializer) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/units.py b/modules/connectors/freightcom/karrio/providers/freightcom/units.py index 47e8f791ea..7ad92b770c 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/units.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/units.py @@ -1,10 +1,7 @@ -import re -import json import typing import pathlib import karrio.lib as lib import karrio.core.units as units -from typing import Dict, List, Union METADATA_JSON = lib.load_json(pathlib.Path(__file__).resolve().parent / "metadata.json") @@ -53,16 +50,29 @@ class PackagingType(lib.StrEnum): your_packaging = freightcom_package -class PaymentType(lib.StrEnum): # TODO:: retrieve the complete list of payment types - check = "Check" +class PaymentMethodType(lib.StrEnum): + net_terms = "net-terms" + credit_card = "credit-card" - sender = "Sender" - recipient = "Recipient" - third_party = "Third Party" - credit_card = "Card" +class PaymentType(lib.StrEnum): # TODO:: retrieve the complete list of payment types + sender = "shipper" + recipient = "receiver" + third_party = "other" +class CustomsContentType(lib.StrEnum): + sale = "commercially-sold-goods" + gift = "gift" + sample = "commercial-sample" + repair = "repair-warranty" + return_merchandise = "return-shipment" + other = "other" + """ Unified Content type mapping """ + documents = other + merchandise = sale +# class PaymentMethodID(lib.StrEnum): +# "" class ShippingOption(lib.Enum): freightcom_signature_required = lib.OptionEnum("signatureRequired", bool) @@ -87,6 +97,7 @@ class ShippingOption(lib.Enum): freightcom_is_saturday_service = lib.OptionEnum("isSaturdayService", bool) freightcom_dangerous_goods_type = lib.OptionEnum("dangerousGoodsType", bool) freightcom_stackable = lib.OptionEnum("stackable", bool) + freightcom_payment_method = lib.OptionEnum("payment_method", str) """ Unified Option type mapping """ saturday_delivery = freightcom_saturday_pickup_required diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index e682f195e5..7159fc43ea 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -1,7 +1,8 @@ -import math +import base64 from typing import Optional +import math from karrio.core import Settings as BaseSettings -from karrio.core.utils import XP +from karrio.lib import request class Settings(BaseSettings): @@ -27,10 +28,10 @@ def server_url(self): def carrier_name(self): return "freightcom" - -def standard_request_serializer(element) -> str: - return XP.export( - element, namespacedef_='xmlns="http://www.freightcom.net/XMLSchema"' +def download_label(file_url: str) -> str: + return request( + decoder=lambda b: base64.encodebytes(b).decode("utf-8"), + url=file_url, ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/void_shipment.py b/modules/connectors/freightcom/karrio/providers/freightcom/void_shipment.py deleted file mode 100644 index 1200d25fdc..0000000000 --- a/modules/connectors/freightcom/karrio/providers/freightcom/void_shipment.py +++ /dev/null @@ -1,50 +0,0 @@ -from typing import List, Tuple -from karrio.schemas.freightcom.shipment_cancel_request import ( - ShipmentCancelRequestType, - Freightcom, - OrderType, -) -from karrio.core.models import ShipmentCancelRequest, ConfirmationDetails, Message -from karrio.core.utils import ( - Element, - Serializable, -) -from karrio.providers.freightcom.error import parse_error_response -from karrio.providers.freightcom.utils import Settings, standard_request_serializer -import karrio.lib as lib - - -def parse_shipment_cancel_reply( - _response: lib.Deserializable[Element], - settings: Settings, -) -> Tuple[ConfirmationDetails, List[Message]]: - response = _response.deserialize() - errors = parse_error_response(response, settings) - success = len(errors) == 0 - confirmation: ConfirmationDetails = ( - ConfirmationDetails( - carrier_id=settings.carrier_id, - carrier_name=settings.carrier_name, - success=success, - operation="Cancel Shipment", - ) - if success - else None - ) - - return confirmation, errors - - -def shipment_cancel_request( - payload: ShipmentCancelRequest, settings: Settings -) -> Serializable: - request = Freightcom( - username=settings.username, - password=settings.password, - version="3.1.0", - ShipmentCancelRequest=ShipmentCancelRequestType( - Order=OrderType(orderId=payload.shipment_identifier) - ), - ) - - return Serializable(request, standard_request_serializer) diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/error.py b/modules/connectors/freightcom/karrio/schemas/freightcom/error_response.py similarity index 72% rename from modules/connectors/freightcom/karrio/schemas/freightcom/error.py rename to modules/connectors/freightcom/karrio/schemas/freightcom/error_response.py index 7d58ea5d4e..bdfac46fff 100644 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/error.py +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/error_response.py @@ -5,10 +5,10 @@ @s(auto_attribs=True) class DataType: - details_destination_signature_requirement: Optional[str] = None + services: Optional[str] = None @s(auto_attribs=True) -class ErrorType: +class ErrorResponseType: message: Optional[str] = None data: Optional[DataType] = JStruct[DataType] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/pickup_request.py b/modules/connectors/freightcom/karrio/schemas/freightcom/pickup_request.py new file mode 100644 index 0000000000..8b059a5901 --- /dev/null +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/pickup_request.py @@ -0,0 +1,46 @@ +from attr import s +from typing import Optional +from jstruct import JStruct + + +@s(auto_attribs=True) +class DateType: + year: Optional[int] = None + month: Optional[int] = None + day: Optional[int] = None + + +@s(auto_attribs=True) +class ReadyType: + hour: Optional[int] = None + minute: Optional[int] = None + + +@s(auto_attribs=True) +class DispatchDetailsType: + date: Optional[DateType] = JStruct[DateType] + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + + +@s(auto_attribs=True) +class ContactPhoneNumberType: + number: Optional[str] = None + extension: Optional[int] = None + + +@s(auto_attribs=True) +class PickupDetailsType: + pre_scheduled_pickup: Optional[bool] = None + date: Optional[DateType] = JStruct[DateType] + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + pickup_location: Optional[str] = None + contact_name: Optional[str] = None + contact_phone_number: Optional[ContactPhoneNumberType] = JStruct[ContactPhoneNumberType] + + +@s(auto_attribs=True) +class PickupRequestType: + pickup_details: Optional[PickupDetailsType] = JStruct[PickupDetailsType] + dispatch_details: Optional[DispatchDetailsType] = JStruct[DispatchDetailsType] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/quote_reply.py b/modules/connectors/freightcom/karrio/schemas/freightcom/quote_reply.py deleted file mode 100644 index d7448ed712..0000000000 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/quote_reply.py +++ /dev/null @@ -1,2555 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# Generated Fri Oct 21 12:33:20 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/quote_reply.py') -# -# Command line arguments: -# ./vendor/schemas/quote_reply.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/quote_reply.py" ./vendor/schemas/quote_reply.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# - -import sys - -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, version=None, QuoteReply=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.QuoteReply = QuoteReply - self.QuoteReply_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_QuoteReply(self): - return self.QuoteReply - - def set_QuoteReply(self, QuoteReply): - self.QuoteReply = QuoteReply - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.QuoteReply is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.QuoteReply is not None: - namespaceprefix_ = ( - self.QuoteReply_nsprefix_ + ":" - if (UseCapturedNS_ and self.QuoteReply_nsprefix_) - else "" - ) - self.QuoteReply.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="QuoteReply", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "QuoteReply": - obj_ = QuoteReplyType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.QuoteReply = obj_ - obj_.original_tagname_ = "QuoteReply" - - -# end class Freightcom - - -class QuoteReplyType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, Quote=None, CarrierErrorMessage=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - if Quote is None: - self.Quote = [] - else: - self.Quote = Quote - self.Quote_nsprefix_ = None - self.CarrierErrorMessage = CarrierErrorMessage - self.CarrierErrorMessage_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, QuoteReplyType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if QuoteReplyType.subclass: - return QuoteReplyType.subclass(*args_, **kwargs_) - else: - return QuoteReplyType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Quote(self): - return self.Quote - - def set_Quote(self, Quote): - self.Quote = Quote - - def add_Quote(self, value): - self.Quote.append(value) - - def insert_Quote_at(self, index, value): - self.Quote.insert(index, value) - - def replace_Quote_at(self, index, value): - self.Quote[index] = value - - def get_CarrierErrorMessage(self): - return self.CarrierErrorMessage - - def set_CarrierErrorMessage(self, CarrierErrorMessage): - self.CarrierErrorMessage = CarrierErrorMessage - - def _hasContent(self): - if self.Quote or self.CarrierErrorMessage is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteReplyType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("QuoteReplyType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "QuoteReplyType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="QuoteReplyType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="QuoteReplyType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="QuoteReplyType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteReplyType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - for Quote_ in self.Quote: - namespaceprefix_ = ( - self.Quote_nsprefix_ + ":" - if (UseCapturedNS_ and self.Quote_nsprefix_) - else "" - ) - Quote_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Quote", - pretty_print=pretty_print, - ) - if self.CarrierErrorMessage is not None: - namespaceprefix_ = ( - self.CarrierErrorMessage_nsprefix_ + ":" - if (UseCapturedNS_ and self.CarrierErrorMessage_nsprefix_) - else "" - ) - self.CarrierErrorMessage.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="CarrierErrorMessage", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Quote": - obj_ = QuoteType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Quote.append(obj_) - obj_.original_tagname_ = "Quote" - elif nodeName_ == "CarrierErrorMessage": - obj_ = CarrierErrorMessageType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.CarrierErrorMessage = obj_ - obj_.original_tagname_ = "CarrierErrorMessage" - - -# end class QuoteReplyType - - -class QuoteType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - carrierId=None, - carrierName=None, - serviceId=None, - serviceName=None, - modeTransport=None, - transitDays=None, - currency=None, - baseCharge=None, - fuelSurcharge=None, - totalCharge=None, - cubedWeight=None, - Surcharge=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.carrierId = _cast(int, carrierId) - self.carrierId_nsprefix_ = None - self.carrierName = _cast(None, carrierName) - self.carrierName_nsprefix_ = None - self.serviceId = _cast(int, serviceId) - self.serviceId_nsprefix_ = None - self.serviceName = _cast(None, serviceName) - self.serviceName_nsprefix_ = None - self.modeTransport = _cast(None, modeTransport) - self.modeTransport_nsprefix_ = None - self.transitDays = _cast(int, transitDays) - self.transitDays_nsprefix_ = None - self.currency = _cast(None, currency) - self.currency_nsprefix_ = None - self.baseCharge = _cast(float, baseCharge) - self.baseCharge_nsprefix_ = None - self.fuelSurcharge = _cast(float, fuelSurcharge) - self.fuelSurcharge_nsprefix_ = None - self.totalCharge = _cast(float, totalCharge) - self.totalCharge_nsprefix_ = None - self.cubedWeight = _cast(float, cubedWeight) - self.cubedWeight_nsprefix_ = None - if Surcharge is None: - self.Surcharge = [] - else: - self.Surcharge = Surcharge - self.Surcharge_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, QuoteType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if QuoteType.subclass: - return QuoteType.subclass(*args_, **kwargs_) - else: - return QuoteType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Surcharge(self): - return self.Surcharge - - def set_Surcharge(self, Surcharge): - self.Surcharge = Surcharge - - def add_Surcharge(self, value): - self.Surcharge.append(value) - - def insert_Surcharge_at(self, index, value): - self.Surcharge.insert(index, value) - - def replace_Surcharge_at(self, index, value): - self.Surcharge[index] = value - - def get_carrierId(self): - return self.carrierId - - def set_carrierId(self, carrierId): - self.carrierId = carrierId - - def get_carrierName(self): - return self.carrierName - - def set_carrierName(self, carrierName): - self.carrierName = carrierName - - def get_serviceId(self): - return self.serviceId - - def set_serviceId(self, serviceId): - self.serviceId = serviceId - - def get_serviceName(self): - return self.serviceName - - def set_serviceName(self, serviceName): - self.serviceName = serviceName - - def get_modeTransport(self): - return self.modeTransport - - def set_modeTransport(self, modeTransport): - self.modeTransport = modeTransport - - def get_transitDays(self): - return self.transitDays - - def set_transitDays(self, transitDays): - self.transitDays = transitDays - - def get_currency(self): - return self.currency - - def set_currency(self, currency): - self.currency = currency - - def get_baseCharge(self): - return self.baseCharge - - def set_baseCharge(self, baseCharge): - self.baseCharge = baseCharge - - def get_fuelSurcharge(self): - return self.fuelSurcharge - - def set_fuelSurcharge(self, fuelSurcharge): - self.fuelSurcharge = fuelSurcharge - - def get_totalCharge(self): - return self.totalCharge - - def set_totalCharge(self, totalCharge): - self.totalCharge = totalCharge - - def get_cubedWeight(self): - return self.cubedWeight - - def set_cubedWeight(self, cubedWeight): - self.cubedWeight = cubedWeight - - def _hasContent(self): - if self.Surcharge: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("QuoteType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "QuoteType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="QuoteType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="QuoteType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="QuoteType" - ): - if self.carrierId is not None and "carrierId" not in already_processed: - already_processed.add("carrierId") - outfile.write( - ' carrierId="%s"' - % self.gds_format_integer(self.carrierId, input_name="carrierId") - ) - if self.carrierName is not None and "carrierName" not in already_processed: - already_processed.add("carrierName") - outfile.write( - " carrierName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.carrierName), input_name="carrierName" - ) - ), - ) - ) - if self.serviceId is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - outfile.write( - ' serviceId="%s"' - % self.gds_format_integer(self.serviceId, input_name="serviceId") - ) - if self.serviceName is not None and "serviceName" not in already_processed: - already_processed.add("serviceName") - outfile.write( - " serviceName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.serviceName), input_name="serviceName" - ) - ), - ) - ) - if self.modeTransport is not None and "modeTransport" not in already_processed: - already_processed.add("modeTransport") - outfile.write( - " modeTransport=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.modeTransport), input_name="modeTransport" - ) - ), - ) - ) - if self.transitDays is not None and "transitDays" not in already_processed: - already_processed.add("transitDays") - outfile.write( - ' transitDays="%s"' - % self.gds_format_integer(self.transitDays, input_name="transitDays") - ) - if self.currency is not None and "currency" not in already_processed: - already_processed.add("currency") - outfile.write( - " currency=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.currency), input_name="currency" - ) - ), - ) - ) - if self.baseCharge is not None and "baseCharge" not in already_processed: - already_processed.add("baseCharge") - outfile.write( - ' baseCharge="%s"' - % self.gds_format_float(self.baseCharge, input_name="baseCharge") - ) - if self.fuelSurcharge is not None and "fuelSurcharge" not in already_processed: - already_processed.add("fuelSurcharge") - outfile.write( - ' fuelSurcharge="%s"' - % self.gds_format_float(self.fuelSurcharge, input_name="fuelSurcharge") - ) - if self.totalCharge is not None and "totalCharge" not in already_processed: - already_processed.add("totalCharge") - outfile.write( - ' totalCharge="%s"' - % self.gds_format_float(self.totalCharge, input_name="totalCharge") - ) - if self.cubedWeight is not None and "cubedWeight" not in already_processed: - already_processed.add("cubedWeight") - outfile.write( - ' cubedWeight="%s"' - % self.gds_format_float(self.cubedWeight, input_name="cubedWeight") - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - for Surcharge_ in self.Surcharge: - namespaceprefix_ = ( - self.Surcharge_nsprefix_ + ":" - if (UseCapturedNS_ and self.Surcharge_nsprefix_) - else "" - ) - Surcharge_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Surcharge", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("carrierId", node) - if value is not None and "carrierId" not in already_processed: - already_processed.add("carrierId") - self.carrierId = self.gds_parse_integer(value, node, "carrierId") - value = find_attr_value_("carrierName", node) - if value is not None and "carrierName" not in already_processed: - already_processed.add("carrierName") - self.carrierName = value - value = find_attr_value_("serviceId", node) - if value is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - self.serviceId = self.gds_parse_integer(value, node, "serviceId") - value = find_attr_value_("serviceName", node) - if value is not None and "serviceName" not in already_processed: - already_processed.add("serviceName") - self.serviceName = value - value = find_attr_value_("modeTransport", node) - if value is not None and "modeTransport" not in already_processed: - already_processed.add("modeTransport") - self.modeTransport = value - value = find_attr_value_("transitDays", node) - if value is not None and "transitDays" not in already_processed: - already_processed.add("transitDays") - self.transitDays = self.gds_parse_integer(value, node, "transitDays") - value = find_attr_value_("currency", node) - if value is not None and "currency" not in already_processed: - already_processed.add("currency") - self.currency = value - value = find_attr_value_("baseCharge", node) - if value is not None and "baseCharge" not in already_processed: - already_processed.add("baseCharge") - value = self.gds_parse_float(value, node, "baseCharge") - self.baseCharge = value - value = find_attr_value_("fuelSurcharge", node) - if value is not None and "fuelSurcharge" not in already_processed: - already_processed.add("fuelSurcharge") - value = self.gds_parse_float(value, node, "fuelSurcharge") - self.fuelSurcharge = value - value = find_attr_value_("totalCharge", node) - if value is not None and "totalCharge" not in already_processed: - already_processed.add("totalCharge") - value = self.gds_parse_float(value, node, "totalCharge") - self.totalCharge = value - value = find_attr_value_("cubedWeight", node) - if value is not None and "cubedWeight" not in already_processed: - already_processed.add("cubedWeight") - value = self.gds_parse_float(value, node, "cubedWeight") - self.cubedWeight = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Surcharge": - obj_ = SurchargeType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Surcharge.append(obj_) - obj_.original_tagname_ = "Surcharge" - - -# end class QuoteType - - -class SurchargeType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - id=None, - name=None, - amount=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.name = _cast(None, name) - self.name_nsprefix_ = None - self.amount = _cast(float, amount) - self.amount_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, SurchargeType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if SurchargeType.subclass: - return SurchargeType.subclass(*args_, **kwargs_) - else: - return SurchargeType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_name(self): - return self.name - - def set_name(self, name): - self.name = name - - def get_amount(self): - return self.amount - - def set_amount(self, amount): - self.amount = amount - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="SurchargeType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("SurchargeType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "SurchargeType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="SurchargeType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="SurchargeType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="SurchargeType", - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - if self.name is not None and "name" not in already_processed: - already_processed.add("name") - outfile.write( - " name=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.name), input_name="name" - ) - ), - ) - ) - if self.amount is not None and "amount" not in already_processed: - already_processed.add("amount") - outfile.write( - ' amount="%s"' % self.gds_format_float(self.amount, input_name="amount") - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="SurchargeType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - value = find_attr_value_("name", node) - if value is not None and "name" not in already_processed: - already_processed.add("name") - self.name = value - value = find_attr_value_("amount", node) - if value is not None and "amount" not in already_processed: - already_processed.add("amount") - value = self.gds_parse_float(value, node, "amount") - self.amount = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class SurchargeType - - -class CarrierErrorMessageType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - size=None, - errorMessage0=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.size = _cast(int, size) - self.size_nsprefix_ = None - self.errorMessage0 = _cast(None, errorMessage0) - self.errorMessage0_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, CarrierErrorMessageType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CarrierErrorMessageType.subclass: - return CarrierErrorMessageType.subclass(*args_, **kwargs_) - else: - return CarrierErrorMessageType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_size(self): - return self.size - - def set_size(self, size): - self.size = size - - def get_errorMessage0(self): - return self.errorMessage0 - - def set_errorMessage0(self, errorMessage0): - self.errorMessage0 = errorMessage0 - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CarrierErrorMessageType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CarrierErrorMessageType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CarrierErrorMessageType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="CarrierErrorMessageType", - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CarrierErrorMessageType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="CarrierErrorMessageType", - ): - if self.size is not None and "size" not in already_processed: - already_processed.add("size") - outfile.write( - ' size="%s"' % self.gds_format_integer(self.size, input_name="size") - ) - if self.errorMessage0 is not None and "errorMessage0" not in already_processed: - already_processed.add("errorMessage0") - outfile.write( - " errorMessage0=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.errorMessage0), input_name="errorMessage0" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CarrierErrorMessageType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("size", node) - if value is not None and "size" not in already_processed: - already_processed.add("size") - self.size = self.gds_parse_integer(value, node, "size") - value = find_attr_value_("errorMessage0", node) - if value is not None and "errorMessage0" not in already_processed: - already_processed.add("errorMessage0") - self.errorMessage0 = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class CarrierErrorMessageType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from quote_reply import *\n\n") - sys.stdout.write("import quote_reply as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/xml/XMLSchema": []} - -__all__ = [ - "CarrierErrorMessageType", - "Freightcom", - "QuoteReplyType", - "QuoteType", - "SurchargeType", -] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/quote_request.py b/modules/connectors/freightcom/karrio/schemas/freightcom/quote_request.py deleted file mode 100644 index 1d0ee26009..0000000000 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/quote_request.py +++ /dev/null @@ -1,4522 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# Generated Fri Oct 21 12:33:20 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/quote_request.py') -# -# Command line arguments: -# ./vendor/schemas/quote_request.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/quote_request.py" ./vendor/schemas/quote_request.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# - -import sys - -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - username=None, - password=None, - version=None, - QuoteRequest=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.username = _cast(None, username) - self.username_nsprefix_ = None - self.password = _cast(None, password) - self.password_nsprefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.QuoteRequest = QuoteRequest - self.QuoteRequest_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_QuoteRequest(self): - return self.QuoteRequest - - def set_QuoteRequest(self, QuoteRequest): - self.QuoteRequest = QuoteRequest - - def get_username(self): - return self.username - - def set_username(self, username): - self.username = username - - def get_password(self): - return self.password - - def set_password(self, password): - self.password = password - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.QuoteRequest is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.username is not None and "username" not in already_processed: - already_processed.add("username") - outfile.write( - " username=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.username), input_name="username" - ) - ), - ) - ) - if self.password is not None and "password" not in already_processed: - already_processed.add("password") - outfile.write( - " password=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.password), input_name="password" - ) - ), - ) - ) - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.QuoteRequest is not None: - namespaceprefix_ = ( - self.QuoteRequest_nsprefix_ + ":" - if (UseCapturedNS_ and self.QuoteRequest_nsprefix_) - else "" - ) - self.QuoteRequest.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="QuoteRequest", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("username", node) - if value is not None and "username" not in already_processed: - already_processed.add("username") - self.username = value - value = find_attr_value_("password", node) - if value is not None and "password" not in already_processed: - already_processed.add("password") - self.password = value - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "QuoteRequest": - obj_ = QuoteRequestType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.QuoteRequest = obj_ - obj_.original_tagname_ = "QuoteRequest" - - -# end class Freightcom - - -class QuoteRequestType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - saturdayPickupRequired=None, - homelandSecurity=None, - pierCharge=None, - exhibitionConventionSite=None, - militaryBaseDelivery=None, - customsIn_bondFreight=None, - limitedAccess=None, - excessLength=None, - tailgatePickup=None, - residentialPickup=None, - crossBorderFee=None, - notifyRecipient=None, - singleShipment=None, - tailgateDelivery=None, - residentialDelivery=None, - insuranceType=None, - scheduledShipDate=None, - insideDelivery=None, - isSaturdayService=None, - dangerousGoodsType=None, - serviceId=None, - stackable=None, - From=None, - To=None, - COD=None, - Packages=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.saturdayPickupRequired = _cast(None, saturdayPickupRequired) - self.saturdayPickupRequired_nsprefix_ = None - self.homelandSecurity = _cast(None, homelandSecurity) - self.homelandSecurity_nsprefix_ = None - self.pierCharge = _cast(None, pierCharge) - self.pierCharge_nsprefix_ = None - self.exhibitionConventionSite = _cast(None, exhibitionConventionSite) - self.exhibitionConventionSite_nsprefix_ = None - self.militaryBaseDelivery = _cast(None, militaryBaseDelivery) - self.militaryBaseDelivery_nsprefix_ = None - self.customsIn_bondFreight = _cast(None, customsIn_bondFreight) - self.customsIn_bondFreight_nsprefix_ = None - self.limitedAccess = _cast(None, limitedAccess) - self.limitedAccess_nsprefix_ = None - self.excessLength = _cast(None, excessLength) - self.excessLength_nsprefix_ = None - self.tailgatePickup = _cast(None, tailgatePickup) - self.tailgatePickup_nsprefix_ = None - self.residentialPickup = _cast(None, residentialPickup) - self.residentialPickup_nsprefix_ = None - self.crossBorderFee = _cast(None, crossBorderFee) - self.crossBorderFee_nsprefix_ = None - self.notifyRecipient = _cast(None, notifyRecipient) - self.notifyRecipient_nsprefix_ = None - self.singleShipment = _cast(None, singleShipment) - self.singleShipment_nsprefix_ = None - self.tailgateDelivery = _cast(None, tailgateDelivery) - self.tailgateDelivery_nsprefix_ = None - self.residentialDelivery = _cast(None, residentialDelivery) - self.residentialDelivery_nsprefix_ = None - self.insuranceType = _cast(None, insuranceType) - self.insuranceType_nsprefix_ = None - self.scheduledShipDate = _cast(None, scheduledShipDate) - self.scheduledShipDate_nsprefix_ = None - self.insideDelivery = _cast(None, insideDelivery) - self.insideDelivery_nsprefix_ = None - self.isSaturdayService = _cast(None, isSaturdayService) - self.isSaturdayService_nsprefix_ = None - self.dangerousGoodsType = _cast(None, dangerousGoodsType) - self.dangerousGoodsType_nsprefix_ = None - self.serviceId = _cast(int, serviceId) - self.serviceId_nsprefix_ = None - self.stackable = _cast(None, stackable) - self.stackable_nsprefix_ = None - self.From = From - self.From_nsprefix_ = None - self.To = To - self.To_nsprefix_ = None - self.COD = COD - self.COD_nsprefix_ = None - self.Packages = Packages - self.Packages_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, QuoteRequestType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if QuoteRequestType.subclass: - return QuoteRequestType.subclass(*args_, **kwargs_) - else: - return QuoteRequestType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_From(self): - return self.From - - def set_From(self, From): - self.From = From - - def get_To(self): - return self.To - - def set_To(self, To): - self.To = To - - def get_COD(self): - return self.COD - - def set_COD(self, COD): - self.COD = COD - - def get_Packages(self): - return self.Packages - - def set_Packages(self, Packages): - self.Packages = Packages - - def get_saturdayPickupRequired(self): - return self.saturdayPickupRequired - - def set_saturdayPickupRequired(self, saturdayPickupRequired): - self.saturdayPickupRequired = saturdayPickupRequired - - def get_homelandSecurity(self): - return self.homelandSecurity - - def set_homelandSecurity(self, homelandSecurity): - self.homelandSecurity = homelandSecurity - - def get_pierCharge(self): - return self.pierCharge - - def set_pierCharge(self, pierCharge): - self.pierCharge = pierCharge - - def get_exhibitionConventionSite(self): - return self.exhibitionConventionSite - - def set_exhibitionConventionSite(self, exhibitionConventionSite): - self.exhibitionConventionSite = exhibitionConventionSite - - def get_militaryBaseDelivery(self): - return self.militaryBaseDelivery - - def set_militaryBaseDelivery(self, militaryBaseDelivery): - self.militaryBaseDelivery = militaryBaseDelivery - - def get_customsIn_bondFreight(self): - return self.customsIn_bondFreight - - def set_customsIn_bondFreight(self, customsIn_bondFreight): - self.customsIn_bondFreight = customsIn_bondFreight - - def get_limitedAccess(self): - return self.limitedAccess - - def set_limitedAccess(self, limitedAccess): - self.limitedAccess = limitedAccess - - def get_excessLength(self): - return self.excessLength - - def set_excessLength(self, excessLength): - self.excessLength = excessLength - - def get_tailgatePickup(self): - return self.tailgatePickup - - def set_tailgatePickup(self, tailgatePickup): - self.tailgatePickup = tailgatePickup - - def get_residentialPickup(self): - return self.residentialPickup - - def set_residentialPickup(self, residentialPickup): - self.residentialPickup = residentialPickup - - def get_crossBorderFee(self): - return self.crossBorderFee - - def set_crossBorderFee(self, crossBorderFee): - self.crossBorderFee = crossBorderFee - - def get_notifyRecipient(self): - return self.notifyRecipient - - def set_notifyRecipient(self, notifyRecipient): - self.notifyRecipient = notifyRecipient - - def get_singleShipment(self): - return self.singleShipment - - def set_singleShipment(self, singleShipment): - self.singleShipment = singleShipment - - def get_tailgateDelivery(self): - return self.tailgateDelivery - - def set_tailgateDelivery(self, tailgateDelivery): - self.tailgateDelivery = tailgateDelivery - - def get_residentialDelivery(self): - return self.residentialDelivery - - def set_residentialDelivery(self, residentialDelivery): - self.residentialDelivery = residentialDelivery - - def get_insuranceType(self): - return self.insuranceType - - def set_insuranceType(self, insuranceType): - self.insuranceType = insuranceType - - def get_scheduledShipDate(self): - return self.scheduledShipDate - - def set_scheduledShipDate(self, scheduledShipDate): - self.scheduledShipDate = scheduledShipDate - - def get_insideDelivery(self): - return self.insideDelivery - - def set_insideDelivery(self, insideDelivery): - self.insideDelivery = insideDelivery - - def get_isSaturdayService(self): - return self.isSaturdayService - - def set_isSaturdayService(self, isSaturdayService): - self.isSaturdayService = isSaturdayService - - def get_dangerousGoodsType(self): - return self.dangerousGoodsType - - def set_dangerousGoodsType(self, dangerousGoodsType): - self.dangerousGoodsType = dangerousGoodsType - - def get_serviceId(self): - return self.serviceId - - def set_serviceId(self, serviceId): - self.serviceId = serviceId - - def get_stackable(self): - return self.stackable - - def set_stackable(self, stackable): - self.stackable = stackable - - def _hasContent(self): - if ( - self.From is not None - or self.To is not None - or self.COD is not None - or self.Packages is not None - ): - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteRequestType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("QuoteRequestType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "QuoteRequestType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="QuoteRequestType", - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="QuoteRequestType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="QuoteRequestType", - ): - if ( - self.saturdayPickupRequired is not None - and "saturdayPickupRequired" not in already_processed - ): - already_processed.add("saturdayPickupRequired") - outfile.write( - " saturdayPickupRequired=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.saturdayPickupRequired), - input_name="saturdayPickupRequired", - ) - ), - ) - ) - if ( - self.homelandSecurity is not None - and "homelandSecurity" not in already_processed - ): - already_processed.add("homelandSecurity") - outfile.write( - " homelandSecurity=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.homelandSecurity), - input_name="homelandSecurity", - ) - ), - ) - ) - if self.pierCharge is not None and "pierCharge" not in already_processed: - already_processed.add("pierCharge") - outfile.write( - " pierCharge=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.pierCharge), input_name="pierCharge" - ) - ), - ) - ) - if ( - self.exhibitionConventionSite is not None - and "exhibitionConventionSite" not in already_processed - ): - already_processed.add("exhibitionConventionSite") - outfile.write( - " exhibitionConventionSite=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.exhibitionConventionSite), - input_name="exhibitionConventionSite", - ) - ), - ) - ) - if ( - self.militaryBaseDelivery is not None - and "militaryBaseDelivery" not in already_processed - ): - already_processed.add("militaryBaseDelivery") - outfile.write( - " militaryBaseDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.militaryBaseDelivery), - input_name="militaryBaseDelivery", - ) - ), - ) - ) - if ( - self.customsIn_bondFreight is not None - and "customsIn_bondFreight" not in already_processed - ): - already_processed.add("customsIn_bondFreight") - outfile.write( - " customsIn-bondFreight=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.customsIn_bondFreight), - input_name="customsIn-bondFreight", - ) - ), - ) - ) - if self.limitedAccess is not None and "limitedAccess" not in already_processed: - already_processed.add("limitedAccess") - outfile.write( - " limitedAccess=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.limitedAccess), input_name="limitedAccess" - ) - ), - ) - ) - if self.excessLength is not None and "excessLength" not in already_processed: - already_processed.add("excessLength") - outfile.write( - " excessLength=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.excessLength), input_name="excessLength" - ) - ), - ) - ) - if ( - self.tailgatePickup is not None - and "tailgatePickup" not in already_processed - ): - already_processed.add("tailgatePickup") - outfile.write( - " tailgatePickup=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgatePickup), - input_name="tailgatePickup", - ) - ), - ) - ) - if ( - self.residentialPickup is not None - and "residentialPickup" not in already_processed - ): - already_processed.add("residentialPickup") - outfile.write( - " residentialPickup=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residentialPickup), - input_name="residentialPickup", - ) - ), - ) - ) - if ( - self.crossBorderFee is not None - and "crossBorderFee" not in already_processed - ): - already_processed.add("crossBorderFee") - outfile.write( - " crossBorderFee=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.crossBorderFee), - input_name="crossBorderFee", - ) - ), - ) - ) - if ( - self.notifyRecipient is not None - and "notifyRecipient" not in already_processed - ): - already_processed.add("notifyRecipient") - outfile.write( - " notifyRecipient=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.notifyRecipient), - input_name="notifyRecipient", - ) - ), - ) - ) - if ( - self.singleShipment is not None - and "singleShipment" not in already_processed - ): - already_processed.add("singleShipment") - outfile.write( - " singleShipment=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.singleShipment), - input_name="singleShipment", - ) - ), - ) - ) - if ( - self.tailgateDelivery is not None - and "tailgateDelivery" not in already_processed - ): - already_processed.add("tailgateDelivery") - outfile.write( - " tailgateDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgateDelivery), - input_name="tailgateDelivery", - ) - ), - ) - ) - if ( - self.residentialDelivery is not None - and "residentialDelivery" not in already_processed - ): - already_processed.add("residentialDelivery") - outfile.write( - " residentialDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residentialDelivery), - input_name="residentialDelivery", - ) - ), - ) - ) - if self.insuranceType is not None and "insuranceType" not in already_processed: - already_processed.add("insuranceType") - outfile.write( - " insuranceType=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.insuranceType), input_name="insuranceType" - ) - ), - ) - ) - if ( - self.scheduledShipDate is not None - and "scheduledShipDate" not in already_processed - ): - already_processed.add("scheduledShipDate") - outfile.write( - " scheduledShipDate=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.scheduledShipDate), - input_name="scheduledShipDate", - ) - ), - ) - ) - if ( - self.insideDelivery is not None - and "insideDelivery" not in already_processed - ): - already_processed.add("insideDelivery") - outfile.write( - " insideDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.insideDelivery), - input_name="insideDelivery", - ) - ), - ) - ) - if ( - self.isSaturdayService is not None - and "isSaturdayService" not in already_processed - ): - already_processed.add("isSaturdayService") - outfile.write( - " isSaturdayService=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.isSaturdayService), - input_name="isSaturdayService", - ) - ), - ) - ) - if ( - self.dangerousGoodsType is not None - and "dangerousGoodsType" not in already_processed - ): - already_processed.add("dangerousGoodsType") - outfile.write( - " dangerousGoodsType=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.dangerousGoodsType), - input_name="dangerousGoodsType", - ) - ), - ) - ) - if self.serviceId is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - outfile.write( - ' serviceId="%s"' - % self.gds_format_integer(self.serviceId, input_name="serviceId") - ) - if self.stackable is not None and "stackable" not in already_processed: - already_processed.add("stackable") - outfile.write( - " stackable=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.stackable), input_name="stackable" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteRequestType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.From is not None: - namespaceprefix_ = ( - self.From_nsprefix_ + ":" - if (UseCapturedNS_ and self.From_nsprefix_) - else "" - ) - self.From.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="From", - pretty_print=pretty_print, - ) - if self.To is not None: - namespaceprefix_ = ( - self.To_nsprefix_ + ":" - if (UseCapturedNS_ and self.To_nsprefix_) - else "" - ) - self.To.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="To", - pretty_print=pretty_print, - ) - if self.COD is not None: - namespaceprefix_ = ( - self.COD_nsprefix_ + ":" - if (UseCapturedNS_ and self.COD_nsprefix_) - else "" - ) - self.COD.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="COD", - pretty_print=pretty_print, - ) - if self.Packages is not None: - namespaceprefix_ = ( - self.Packages_nsprefix_ + ":" - if (UseCapturedNS_ and self.Packages_nsprefix_) - else "" - ) - self.Packages.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Packages", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("saturdayPickupRequired", node) - if value is not None and "saturdayPickupRequired" not in already_processed: - already_processed.add("saturdayPickupRequired") - self.saturdayPickupRequired = value - value = find_attr_value_("homelandSecurity", node) - if value is not None and "homelandSecurity" not in already_processed: - already_processed.add("homelandSecurity") - self.homelandSecurity = value - value = find_attr_value_("pierCharge", node) - if value is not None and "pierCharge" not in already_processed: - already_processed.add("pierCharge") - self.pierCharge = value - value = find_attr_value_("exhibitionConventionSite", node) - if value is not None and "exhibitionConventionSite" not in already_processed: - already_processed.add("exhibitionConventionSite") - self.exhibitionConventionSite = value - value = find_attr_value_("militaryBaseDelivery", node) - if value is not None and "militaryBaseDelivery" not in already_processed: - already_processed.add("militaryBaseDelivery") - self.militaryBaseDelivery = value - value = find_attr_value_("customsIn-bondFreight", node) - if value is not None and "customsIn-bondFreight" not in already_processed: - already_processed.add("customsIn-bondFreight") - self.customsIn_bondFreight = value - value = find_attr_value_("limitedAccess", node) - if value is not None and "limitedAccess" not in already_processed: - already_processed.add("limitedAccess") - self.limitedAccess = value - value = find_attr_value_("excessLength", node) - if value is not None and "excessLength" not in already_processed: - already_processed.add("excessLength") - self.excessLength = value - value = find_attr_value_("tailgatePickup", node) - if value is not None and "tailgatePickup" not in already_processed: - already_processed.add("tailgatePickup") - self.tailgatePickup = value - value = find_attr_value_("residentialPickup", node) - if value is not None and "residentialPickup" not in already_processed: - already_processed.add("residentialPickup") - self.residentialPickup = value - value = find_attr_value_("crossBorderFee", node) - if value is not None and "crossBorderFee" not in already_processed: - already_processed.add("crossBorderFee") - self.crossBorderFee = value - value = find_attr_value_("notifyRecipient", node) - if value is not None and "notifyRecipient" not in already_processed: - already_processed.add("notifyRecipient") - self.notifyRecipient = value - value = find_attr_value_("singleShipment", node) - if value is not None and "singleShipment" not in already_processed: - already_processed.add("singleShipment") - self.singleShipment = value - value = find_attr_value_("tailgateDelivery", node) - if value is not None and "tailgateDelivery" not in already_processed: - already_processed.add("tailgateDelivery") - self.tailgateDelivery = value - value = find_attr_value_("residentialDelivery", node) - if value is not None and "residentialDelivery" not in already_processed: - already_processed.add("residentialDelivery") - self.residentialDelivery = value - value = find_attr_value_("insuranceType", node) - if value is not None and "insuranceType" not in already_processed: - already_processed.add("insuranceType") - self.insuranceType = value - value = find_attr_value_("scheduledShipDate", node) - if value is not None and "scheduledShipDate" not in already_processed: - already_processed.add("scheduledShipDate") - self.scheduledShipDate = value - value = find_attr_value_("insideDelivery", node) - if value is not None and "insideDelivery" not in already_processed: - already_processed.add("insideDelivery") - self.insideDelivery = value - value = find_attr_value_("isSaturdayService", node) - if value is not None and "isSaturdayService" not in already_processed: - already_processed.add("isSaturdayService") - self.isSaturdayService = value - value = find_attr_value_("dangerousGoodsType", node) - if value is not None and "dangerousGoodsType" not in already_processed: - already_processed.add("dangerousGoodsType") - self.dangerousGoodsType = value - value = find_attr_value_("serviceId", node) - if value is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - self.serviceId = self.gds_parse_integer(value, node, "serviceId") - value = find_attr_value_("stackable", node) - if value is not None and "stackable" not in already_processed: - already_processed.add("stackable") - self.stackable = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "From": - obj_ = FromType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.From = obj_ - obj_.original_tagname_ = "From" - elif nodeName_ == "To": - obj_ = ToType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.To = obj_ - obj_.original_tagname_ = "To" - elif nodeName_ == "COD": - obj_ = CODType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.COD = obj_ - obj_.original_tagname_ = "COD" - elif nodeName_ == "Packages": - obj_ = PackagesType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Packages = obj_ - obj_.original_tagname_ = "Packages" - - -# end class QuoteRequestType - - -class FromType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - id=None, - company=None, - instructions=None, - email=None, - attention=None, - phone=None, - tailgateRequired=None, - residential=None, - address1=None, - address2=None, - city=None, - state=None, - country=None, - zip=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.company = _cast(None, company) - self.company_nsprefix_ = None - self.instructions = _cast(None, instructions) - self.instructions_nsprefix_ = None - self.email = _cast(None, email) - self.email_nsprefix_ = None - self.attention = _cast(None, attention) - self.attention_nsprefix_ = None - self.phone = _cast(None, phone) - self.phone_nsprefix_ = None - self.tailgateRequired = _cast(None, tailgateRequired) - self.tailgateRequired_nsprefix_ = None - self.residential = _cast(None, residential) - self.residential_nsprefix_ = None - self.address1 = _cast(None, address1) - self.address1_nsprefix_ = None - self.address2 = _cast(None, address2) - self.address2_nsprefix_ = None - self.city = _cast(None, city) - self.city_nsprefix_ = None - self.state = _cast(None, state) - self.state_nsprefix_ = None - self.country = _cast(None, country) - self.country_nsprefix_ = None - self.zip = _cast(None, zip) - self.zip_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, FromType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if FromType.subclass: - return FromType.subclass(*args_, **kwargs_) - else: - return FromType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_company(self): - return self.company - - def set_company(self, company): - self.company = company - - def get_instructions(self): - return self.instructions - - def set_instructions(self, instructions): - self.instructions = instructions - - def get_email(self): - return self.email - - def set_email(self, email): - self.email = email - - def get_attention(self): - return self.attention - - def set_attention(self, attention): - self.attention = attention - - def get_phone(self): - return self.phone - - def set_phone(self, phone): - self.phone = phone - - def get_tailgateRequired(self): - return self.tailgateRequired - - def set_tailgateRequired(self, tailgateRequired): - self.tailgateRequired = tailgateRequired - - def get_residential(self): - return self.residential - - def set_residential(self, residential): - self.residential = residential - - def get_address1(self): - return self.address1 - - def set_address1(self, address1): - self.address1 = address1 - - def get_address2(self): - return self.address2 - - def set_address2(self, address2): - self.address2 = address2 - - def get_city(self): - return self.city - - def set_city(self, city): - self.city = city - - def get_state(self): - return self.state - - def set_state(self, state): - self.state = state - - def get_country(self): - return self.country - - def set_country(self, country): - self.country = country - - def get_zip(self): - return self.zip - - def set_zip(self, zip): - self.zip = zip - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="FromType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("FromType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "FromType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="FromType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="FromType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="FromType" - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - if self.company is not None and "company" not in already_processed: - already_processed.add("company") - outfile.write( - " company=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.company), input_name="company" - ) - ), - ) - ) - if self.instructions is not None and "instructions" not in already_processed: - already_processed.add("instructions") - outfile.write( - " instructions=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.instructions), input_name="instructions" - ) - ), - ) - ) - if self.email is not None and "email" not in already_processed: - already_processed.add("email") - outfile.write( - " email=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.email), input_name="email" - ) - ), - ) - ) - if self.attention is not None and "attention" not in already_processed: - already_processed.add("attention") - outfile.write( - " attention=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.attention), input_name="attention" - ) - ), - ) - ) - if self.phone is not None and "phone" not in already_processed: - already_processed.add("phone") - outfile.write( - " phone=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.phone), input_name="phone" - ) - ), - ) - ) - if ( - self.tailgateRequired is not None - and "tailgateRequired" not in already_processed - ): - already_processed.add("tailgateRequired") - outfile.write( - " tailgateRequired=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgateRequired), - input_name="tailgateRequired", - ) - ), - ) - ) - if self.residential is not None and "residential" not in already_processed: - already_processed.add("residential") - outfile.write( - " residential=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residential), input_name="residential" - ) - ), - ) - ) - if self.address1 is not None and "address1" not in already_processed: - already_processed.add("address1") - outfile.write( - " address1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address1), input_name="address1" - ) - ), - ) - ) - if self.address2 is not None and "address2" not in already_processed: - already_processed.add("address2") - outfile.write( - " address2=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address2), input_name="address2" - ) - ), - ) - ) - if self.city is not None and "city" not in already_processed: - already_processed.add("city") - outfile.write( - " city=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.city), input_name="city" - ) - ), - ) - ) - if self.state is not None and "state" not in already_processed: - already_processed.add("state") - outfile.write( - " state=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.state), input_name="state" - ) - ), - ) - ) - if self.country is not None and "country" not in already_processed: - already_processed.add("country") - outfile.write( - " country=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.country), input_name="country" - ) - ), - ) - ) - if self.zip is not None and "zip" not in already_processed: - already_processed.add("zip") - outfile.write( - " zip=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.zip), input_name="zip") - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="FromType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - value = find_attr_value_("company", node) - if value is not None and "company" not in already_processed: - already_processed.add("company") - self.company = value - value = find_attr_value_("instructions", node) - if value is not None and "instructions" not in already_processed: - already_processed.add("instructions") - self.instructions = value - value = find_attr_value_("email", node) - if value is not None and "email" not in already_processed: - already_processed.add("email") - self.email = value - value = find_attr_value_("attention", node) - if value is not None and "attention" not in already_processed: - already_processed.add("attention") - self.attention = value - value = find_attr_value_("phone", node) - if value is not None and "phone" not in already_processed: - already_processed.add("phone") - self.phone = value - value = find_attr_value_("tailgateRequired", node) - if value is not None and "tailgateRequired" not in already_processed: - already_processed.add("tailgateRequired") - self.tailgateRequired = value - value = find_attr_value_("residential", node) - if value is not None and "residential" not in already_processed: - already_processed.add("residential") - self.residential = value - value = find_attr_value_("address1", node) - if value is not None and "address1" not in already_processed: - already_processed.add("address1") - self.address1 = value - value = find_attr_value_("address2", node) - if value is not None and "address2" not in already_processed: - already_processed.add("address2") - self.address2 = value - value = find_attr_value_("city", node) - if value is not None and "city" not in already_processed: - already_processed.add("city") - self.city = value - value = find_attr_value_("state", node) - if value is not None and "state" not in already_processed: - already_processed.add("state") - self.state = value - value = find_attr_value_("country", node) - if value is not None and "country" not in already_processed: - already_processed.add("country") - self.country = value - value = find_attr_value_("zip", node) - if value is not None and "zip" not in already_processed: - already_processed.add("zip") - self.zip = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class FromType - - -class ToType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - id=None, - company=None, - notifyRecipient=None, - instructions=None, - email=None, - attention=None, - phone=None, - tailgateRequired=None, - residential=None, - address1=None, - address2=None, - city=None, - state=None, - zip=None, - country=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.company = _cast(None, company) - self.company_nsprefix_ = None - self.notifyRecipient = _cast(None, notifyRecipient) - self.notifyRecipient_nsprefix_ = None - self.instructions = _cast(None, instructions) - self.instructions_nsprefix_ = None - self.email = _cast(None, email) - self.email_nsprefix_ = None - self.attention = _cast(None, attention) - self.attention_nsprefix_ = None - self.phone = _cast(None, phone) - self.phone_nsprefix_ = None - self.tailgateRequired = _cast(None, tailgateRequired) - self.tailgateRequired_nsprefix_ = None - self.residential = _cast(None, residential) - self.residential_nsprefix_ = None - self.address1 = _cast(None, address1) - self.address1_nsprefix_ = None - self.address2 = _cast(None, address2) - self.address2_nsprefix_ = None - self.city = _cast(None, city) - self.city_nsprefix_ = None - self.state = _cast(None, state) - self.state_nsprefix_ = None - self.zip = _cast(None, zip) - self.zip_nsprefix_ = None - self.country = _cast(None, country) - self.country_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ToType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ToType.subclass: - return ToType.subclass(*args_, **kwargs_) - else: - return ToType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_company(self): - return self.company - - def set_company(self, company): - self.company = company - - def get_notifyRecipient(self): - return self.notifyRecipient - - def set_notifyRecipient(self, notifyRecipient): - self.notifyRecipient = notifyRecipient - - def get_instructions(self): - return self.instructions - - def set_instructions(self, instructions): - self.instructions = instructions - - def get_email(self): - return self.email - - def set_email(self, email): - self.email = email - - def get_attention(self): - return self.attention - - def set_attention(self, attention): - self.attention = attention - - def get_phone(self): - return self.phone - - def set_phone(self, phone): - self.phone = phone - - def get_tailgateRequired(self): - return self.tailgateRequired - - def set_tailgateRequired(self, tailgateRequired): - self.tailgateRequired = tailgateRequired - - def get_residential(self): - return self.residential - - def set_residential(self, residential): - self.residential = residential - - def get_address1(self): - return self.address1 - - def set_address1(self, address1): - self.address1 = address1 - - def get_address2(self): - return self.address2 - - def set_address2(self, address2): - self.address2 = address2 - - def get_city(self): - return self.city - - def set_city(self, city): - self.city = city - - def get_state(self): - return self.state - - def set_state(self, state): - self.state = state - - def get_zip(self): - return self.zip - - def set_zip(self, zip): - self.zip = zip - - def get_country(self): - return self.country - - def set_country(self, country): - self.country = country - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ToType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ToType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ToType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ToType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ToType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="ToType" - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - if self.company is not None and "company" not in already_processed: - already_processed.add("company") - outfile.write( - " company=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.company), input_name="company" - ) - ), - ) - ) - if ( - self.notifyRecipient is not None - and "notifyRecipient" not in already_processed - ): - already_processed.add("notifyRecipient") - outfile.write( - " notifyRecipient=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.notifyRecipient), - input_name="notifyRecipient", - ) - ), - ) - ) - if self.instructions is not None and "instructions" not in already_processed: - already_processed.add("instructions") - outfile.write( - " instructions=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.instructions), input_name="instructions" - ) - ), - ) - ) - if self.email is not None and "email" not in already_processed: - already_processed.add("email") - outfile.write( - " email=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.email), input_name="email" - ) - ), - ) - ) - if self.attention is not None and "attention" not in already_processed: - already_processed.add("attention") - outfile.write( - " attention=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.attention), input_name="attention" - ) - ), - ) - ) - if self.phone is not None and "phone" not in already_processed: - already_processed.add("phone") - outfile.write( - " phone=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.phone), input_name="phone" - ) - ), - ) - ) - if ( - self.tailgateRequired is not None - and "tailgateRequired" not in already_processed - ): - already_processed.add("tailgateRequired") - outfile.write( - " tailgateRequired=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgateRequired), - input_name="tailgateRequired", - ) - ), - ) - ) - if self.residential is not None and "residential" not in already_processed: - already_processed.add("residential") - outfile.write( - " residential=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residential), input_name="residential" - ) - ), - ) - ) - if self.address1 is not None and "address1" not in already_processed: - already_processed.add("address1") - outfile.write( - " address1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address1), input_name="address1" - ) - ), - ) - ) - if self.address2 is not None and "address2" not in already_processed: - already_processed.add("address2") - outfile.write( - " address2=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address2), input_name="address2" - ) - ), - ) - ) - if self.city is not None and "city" not in already_processed: - already_processed.add("city") - outfile.write( - " city=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.city), input_name="city" - ) - ), - ) - ) - if self.state is not None and "state" not in already_processed: - already_processed.add("state") - outfile.write( - " state=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.state), input_name="state" - ) - ), - ) - ) - if self.zip is not None and "zip" not in already_processed: - already_processed.add("zip") - outfile.write( - " zip=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.zip), input_name="zip") - ), - ) - ) - if self.country is not None and "country" not in already_processed: - already_processed.add("country") - outfile.write( - " country=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.country), input_name="country" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ToType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - value = find_attr_value_("company", node) - if value is not None and "company" not in already_processed: - already_processed.add("company") - self.company = value - value = find_attr_value_("notifyRecipient", node) - if value is not None and "notifyRecipient" not in already_processed: - already_processed.add("notifyRecipient") - self.notifyRecipient = value - value = find_attr_value_("instructions", node) - if value is not None and "instructions" not in already_processed: - already_processed.add("instructions") - self.instructions = value - value = find_attr_value_("email", node) - if value is not None and "email" not in already_processed: - already_processed.add("email") - self.email = value - value = find_attr_value_("attention", node) - if value is not None and "attention" not in already_processed: - already_processed.add("attention") - self.attention = value - value = find_attr_value_("phone", node) - if value is not None and "phone" not in already_processed: - already_processed.add("phone") - self.phone = value - value = find_attr_value_("tailgateRequired", node) - if value is not None and "tailgateRequired" not in already_processed: - already_processed.add("tailgateRequired") - self.tailgateRequired = value - value = find_attr_value_("residential", node) - if value is not None and "residential" not in already_processed: - already_processed.add("residential") - self.residential = value - value = find_attr_value_("address1", node) - if value is not None and "address1" not in already_processed: - already_processed.add("address1") - self.address1 = value - value = find_attr_value_("address2", node) - if value is not None and "address2" not in already_processed: - already_processed.add("address2") - self.address2 = value - value = find_attr_value_("city", node) - if value is not None and "city" not in already_processed: - already_processed.add("city") - self.city = value - value = find_attr_value_("state", node) - if value is not None and "state" not in already_processed: - already_processed.add("state") - self.state = value - value = find_attr_value_("zip", node) - if value is not None and "zip" not in already_processed: - already_processed.add("zip") - self.zip = value - value = find_attr_value_("country", node) - if value is not None and "country" not in already_processed: - already_processed.add("country") - self.country = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ToType - - -class CODType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, paymentType=None, CODReturnAddress=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.paymentType = _cast(None, paymentType) - self.paymentType_nsprefix_ = None - self.CODReturnAddress = CODReturnAddress - self.CODReturnAddress_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, CODType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CODType.subclass: - return CODType.subclass(*args_, **kwargs_) - else: - return CODType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_CODReturnAddress(self): - return self.CODReturnAddress - - def set_CODReturnAddress(self, CODReturnAddress): - self.CODReturnAddress = CODReturnAddress - - def get_paymentType(self): - return self.paymentType - - def set_paymentType(self, paymentType): - self.paymentType = paymentType - - def _hasContent(self): - if self.CODReturnAddress is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CODType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CODType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="CODType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CODType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="CODType" - ): - if self.paymentType is not None and "paymentType" not in already_processed: - already_processed.add("paymentType") - outfile.write( - " paymentType=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.paymentType), input_name="paymentType" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.CODReturnAddress is not None: - namespaceprefix_ = ( - self.CODReturnAddress_nsprefix_ + ":" - if (UseCapturedNS_ and self.CODReturnAddress_nsprefix_) - else "" - ) - self.CODReturnAddress.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="CODReturnAddress", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("paymentType", node) - if value is not None and "paymentType" not in already_processed: - already_processed.add("paymentType") - self.paymentType = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "CODReturnAddress": - obj_ = CODReturnAddressType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.CODReturnAddress = obj_ - obj_.original_tagname_ = "CODReturnAddress" - - -# end class CODType - - -class CODReturnAddressType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - codCompany=None, - codName=None, - codAddress1=None, - codCity=None, - codStateCode=None, - codZip=None, - codCountry=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.codCompany = _cast(None, codCompany) - self.codCompany_nsprefix_ = None - self.codName = _cast(None, codName) - self.codName_nsprefix_ = None - self.codAddress1 = _cast(None, codAddress1) - self.codAddress1_nsprefix_ = None - self.codCity = _cast(None, codCity) - self.codCity_nsprefix_ = None - self.codStateCode = _cast(None, codStateCode) - self.codStateCode_nsprefix_ = None - self.codZip = _cast(None, codZip) - self.codZip_nsprefix_ = None - self.codCountry = _cast(None, codCountry) - self.codCountry_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, CODReturnAddressType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CODReturnAddressType.subclass: - return CODReturnAddressType.subclass(*args_, **kwargs_) - else: - return CODReturnAddressType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_codCompany(self): - return self.codCompany - - def set_codCompany(self, codCompany): - self.codCompany = codCompany - - def get_codName(self): - return self.codName - - def set_codName(self, codName): - self.codName = codName - - def get_codAddress1(self): - return self.codAddress1 - - def set_codAddress1(self, codAddress1): - self.codAddress1 = codAddress1 - - def get_codCity(self): - return self.codCity - - def set_codCity(self, codCity): - self.codCity = codCity - - def get_codStateCode(self): - return self.codStateCode - - def set_codStateCode(self, codStateCode): - self.codStateCode = codStateCode - - def get_codZip(self): - return self.codZip - - def set_codZip(self, codZip): - self.codZip = codZip - - def get_codCountry(self): - return self.codCountry - - def set_codCountry(self, codCountry): - self.codCountry = codCountry - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODReturnAddressType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CODReturnAddressType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CODReturnAddressType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="CODReturnAddressType", - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CODReturnAddressType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="CODReturnAddressType", - ): - if self.codCompany is not None and "codCompany" not in already_processed: - already_processed.add("codCompany") - outfile.write( - " codCompany=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codCompany), input_name="codCompany" - ) - ), - ) - ) - if self.codName is not None and "codName" not in already_processed: - already_processed.add("codName") - outfile.write( - " codName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codName), input_name="codName" - ) - ), - ) - ) - if self.codAddress1 is not None and "codAddress1" not in already_processed: - already_processed.add("codAddress1") - outfile.write( - " codAddress1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codAddress1), input_name="codAddress1" - ) - ), - ) - ) - if self.codCity is not None and "codCity" not in already_processed: - already_processed.add("codCity") - outfile.write( - " codCity=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codCity), input_name="codCity" - ) - ), - ) - ) - if self.codStateCode is not None and "codStateCode" not in already_processed: - already_processed.add("codStateCode") - outfile.write( - " codStateCode=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codStateCode), input_name="codStateCode" - ) - ), - ) - ) - if self.codZip is not None and "codZip" not in already_processed: - already_processed.add("codZip") - outfile.write( - " codZip=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codZip), input_name="codZip" - ) - ), - ) - ) - if self.codCountry is not None and "codCountry" not in already_processed: - already_processed.add("codCountry") - outfile.write( - " codCountry=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codCountry), input_name="codCountry" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODReturnAddressType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("codCompany", node) - if value is not None and "codCompany" not in already_processed: - already_processed.add("codCompany") - self.codCompany = value - value = find_attr_value_("codName", node) - if value is not None and "codName" not in already_processed: - already_processed.add("codName") - self.codName = value - value = find_attr_value_("codAddress1", node) - if value is not None and "codAddress1" not in already_processed: - already_processed.add("codAddress1") - self.codAddress1 = value - value = find_attr_value_("codCity", node) - if value is not None and "codCity" not in already_processed: - already_processed.add("codCity") - self.codCity = value - value = find_attr_value_("codStateCode", node) - if value is not None and "codStateCode" not in already_processed: - already_processed.add("codStateCode") - self.codStateCode = value - value = find_attr_value_("codZip", node) - if value is not None and "codZip" not in already_processed: - already_processed.add("codZip") - self.codZip = value - value = find_attr_value_("codCountry", node) - if value is not None and "codCountry" not in already_processed: - already_processed.add("codCountry") - self.codCountry = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class CODReturnAddressType - - -class PackagesType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, type_=None, Package=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.type_ = _cast(None, type_) - self.type__nsprefix_ = None - if Package is None: - self.Package = [] - else: - self.Package = Package - self.Package_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PackagesType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PackagesType.subclass: - return PackagesType.subclass(*args_, **kwargs_) - else: - return PackagesType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Package(self): - return self.Package - - def set_Package(self, Package): - self.Package = Package - - def add_Package(self, value): - self.Package.append(value) - - def insert_Package_at(self, index, value): - self.Package.insert(index, value) - - def replace_Package_at(self, index, value): - self.Package[index] = value - - def get_type(self): - return self.type_ - - def set_type(self, type_): - self.type_ = type_ - - def _hasContent(self): - if self.Package: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackagesType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PackagesType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PackagesType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PackagesType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PackagesType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="PackagesType", - ): - if self.type_ is not None and "type_" not in already_processed: - already_processed.add("type_") - outfile.write( - " type=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.type_), input_name="type" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackagesType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - for Package_ in self.Package: - namespaceprefix_ = ( - self.Package_nsprefix_ + ":" - if (UseCapturedNS_ and self.Package_nsprefix_) - else "" - ) - Package_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Package", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("type", node) - if value is not None and "type" not in already_processed: - already_processed.add("type") - self.type_ = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Package": - obj_ = PackageType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Package.append(obj_) - obj_.original_tagname_ = "Package" - - -# end class PackagesType - - -class PackageType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - length=None, - width=None, - height=None, - weight=None, - type_=None, - freightClass=None, - nmfcCode=None, - insuranceAmount=None, - codAmount=None, - description=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.length = _cast(int, length) - self.length_nsprefix_ = None - self.width = _cast(int, width) - self.width_nsprefix_ = None - self.height = _cast(int, height) - self.height_nsprefix_ = None - self.weight = _cast(int, weight) - self.weight_nsprefix_ = None - self.type_ = _cast(None, type_) - self.type__nsprefix_ = None - self.freightClass = _cast(int, freightClass) - self.freightClass_nsprefix_ = None - self.nmfcCode = _cast(None, nmfcCode) - self.nmfcCode_nsprefix_ = None - self.insuranceAmount = _cast(float, insuranceAmount) - self.insuranceAmount_nsprefix_ = None - self.codAmount = _cast(float, codAmount) - self.codAmount_nsprefix_ = None - self.description = _cast(None, description) - self.description_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PackageType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PackageType.subclass: - return PackageType.subclass(*args_, **kwargs_) - else: - return PackageType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_length(self): - return self.length - - def set_length(self, length): - self.length = length - - def get_width(self): - return self.width - - def set_width(self, width): - self.width = width - - def get_height(self): - return self.height - - def set_height(self, height): - self.height = height - - def get_weight(self): - return self.weight - - def set_weight(self, weight): - self.weight = weight - - def get_type(self): - return self.type_ - - def set_type(self, type_): - self.type_ = type_ - - def get_freightClass(self): - return self.freightClass - - def set_freightClass(self, freightClass): - self.freightClass = freightClass - - def get_nmfcCode(self): - return self.nmfcCode - - def set_nmfcCode(self, nmfcCode): - self.nmfcCode = nmfcCode - - def get_insuranceAmount(self): - return self.insuranceAmount - - def set_insuranceAmount(self, insuranceAmount): - self.insuranceAmount = insuranceAmount - - def get_codAmount(self): - return self.codAmount - - def set_codAmount(self, codAmount): - self.codAmount = codAmount - - def get_description(self): - return self.description - - def set_description(self, description): - self.description = description - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackageType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PackageType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PackageType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PackageType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PackageType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="PackageType", - ): - if self.length is not None and "length" not in already_processed: - already_processed.add("length") - outfile.write( - ' length="%s"' - % self.gds_format_integer(self.length, input_name="length") - ) - if self.width is not None and "width" not in already_processed: - already_processed.add("width") - outfile.write( - ' width="%s"' % self.gds_format_integer(self.width, input_name="width") - ) - if self.height is not None and "height" not in already_processed: - already_processed.add("height") - outfile.write( - ' height="%s"' - % self.gds_format_integer(self.height, input_name="height") - ) - if self.weight is not None and "weight" not in already_processed: - already_processed.add("weight") - outfile.write( - ' weight="%s"' - % self.gds_format_integer(self.weight, input_name="weight") - ) - if self.type_ is not None and "type_" not in already_processed: - already_processed.add("type_") - outfile.write( - " type=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.type_), input_name="type" - ) - ), - ) - ) - if self.freightClass is not None and "freightClass" not in already_processed: - already_processed.add("freightClass") - outfile.write( - ' freightClass="%s"' - % self.gds_format_integer(self.freightClass, input_name="freightClass") - ) - if self.nmfcCode is not None and "nmfcCode" not in already_processed: - already_processed.add("nmfcCode") - outfile.write( - " nmfcCode=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.nmfcCode), input_name="nmfcCode" - ) - ), - ) - ) - if ( - self.insuranceAmount is not None - and "insuranceAmount" not in already_processed - ): - already_processed.add("insuranceAmount") - outfile.write( - ' insuranceAmount="%s"' - % self.gds_format_float( - self.insuranceAmount, input_name="insuranceAmount" - ) - ) - if self.codAmount is not None and "codAmount" not in already_processed: - already_processed.add("codAmount") - outfile.write( - ' codAmount="%s"' - % self.gds_format_float(self.codAmount, input_name="codAmount") - ) - if self.description is not None and "description" not in already_processed: - already_processed.add("description") - outfile.write( - " description=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.description), input_name="description" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackageType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("length", node) - if value is not None and "length" not in already_processed: - already_processed.add("length") - self.length = self.gds_parse_integer(value, node, "length") - value = find_attr_value_("width", node) - if value is not None and "width" not in already_processed: - already_processed.add("width") - self.width = self.gds_parse_integer(value, node, "width") - value = find_attr_value_("height", node) - if value is not None and "height" not in already_processed: - already_processed.add("height") - self.height = self.gds_parse_integer(value, node, "height") - value = find_attr_value_("weight", node) - if value is not None and "weight" not in already_processed: - already_processed.add("weight") - self.weight = self.gds_parse_integer(value, node, "weight") - value = find_attr_value_("type", node) - if value is not None and "type" not in already_processed: - already_processed.add("type") - self.type_ = value - value = find_attr_value_("freightClass", node) - if value is not None and "freightClass" not in already_processed: - already_processed.add("freightClass") - self.freightClass = self.gds_parse_integer(value, node, "freightClass") - value = find_attr_value_("nmfcCode", node) - if value is not None and "nmfcCode" not in already_processed: - already_processed.add("nmfcCode") - self.nmfcCode = value - value = find_attr_value_("insuranceAmount", node) - if value is not None and "insuranceAmount" not in already_processed: - already_processed.add("insuranceAmount") - value = self.gds_parse_float(value, node, "insuranceAmount") - self.insuranceAmount = value - value = find_attr_value_("codAmount", node) - if value is not None and "codAmount" not in already_processed: - already_processed.add("codAmount") - value = self.gds_parse_float(value, node, "codAmount") - self.codAmount = value - value = find_attr_value_("description", node) - if value is not None and "description" not in already_processed: - already_processed.add("description") - self.description = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class PackageType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from quote_request import *\n\n") - sys.stdout.write("import quote_request as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/XMLSchema": []} - -__all__ = [ - "CODReturnAddressType", - "CODType", - "Freightcom", - "FromType", - "PackageType", - "PackagesType", - "QuoteRequestType", - "ToType", -] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_reply.py b/modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_reply.py deleted file mode 100644 index c1c5aff29a..0000000000 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_reply.py +++ /dev/null @@ -1,2063 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# Generated Fri Oct 21 12:33:21 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/shipment_cancel_reply.py') -# -# Command line arguments: -# ./vendor/schemas/shipment_cancel_reply.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/shipment_cancel_reply.py" ./vendor/schemas/shipment_cancel_reply.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# - -import sys - -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, version=None, ShipmentCancelReply=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.ShipmentCancelReply = ShipmentCancelReply - self.ShipmentCancelReply_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_ShipmentCancelReply(self): - return self.ShipmentCancelReply - - def set_ShipmentCancelReply(self, ShipmentCancelReply): - self.ShipmentCancelReply = ShipmentCancelReply - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.ShipmentCancelReply is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.ShipmentCancelReply is not None: - namespaceprefix_ = ( - self.ShipmentCancelReply_nsprefix_ + ":" - if (UseCapturedNS_ and self.ShipmentCancelReply_nsprefix_) - else "" - ) - self.ShipmentCancelReply.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="ShipmentCancelReply", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "ShipmentCancelReply": - obj_ = ShipmentCancelReplyType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.ShipmentCancelReply = obj_ - obj_.original_tagname_ = "ShipmentCancelReply" - - -# end class Freightcom - - -class ShipmentCancelReplyType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, Order=None, Status=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.Order = Order - self.Order_nsprefix_ = None - self.Status = Status - self.Status_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, ShipmentCancelReplyType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ShipmentCancelReplyType.subclass: - return ShipmentCancelReplyType.subclass(*args_, **kwargs_) - else: - return ShipmentCancelReplyType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Order(self): - return self.Order - - def set_Order(self, Order): - self.Order = Order - - def get_Status(self): - return self.Status - - def set_Status(self, Status): - self.Status = Status - - def _hasContent(self): - if self.Order is not None or self.Status is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShipmentCancelReplyType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ShipmentCancelReplyType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ShipmentCancelReplyType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="ShipmentCancelReplyType", - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ShipmentCancelReplyType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ShipmentCancelReplyType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShipmentCancelReplyType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.Order is not None: - namespaceprefix_ = ( - self.Order_nsprefix_ + ":" - if (UseCapturedNS_ and self.Order_nsprefix_) - else "" - ) - self.Order.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Order", - pretty_print=pretty_print, - ) - if self.Status is not None: - namespaceprefix_ = ( - self.Status_nsprefix_ + ":" - if (UseCapturedNS_ and self.Status_nsprefix_) - else "" - ) - self.Status.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Status", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Order": - obj_ = OrderType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Order = obj_ - obj_.original_tagname_ = "Order" - elif nodeName_ == "Status": - obj_ = StatusType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Status = obj_ - obj_.original_tagname_ = "Status" - - -# end class ShipmentCancelReplyType - - -class OrderType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, orderId=None, message=None, valueOf_=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.orderId = _cast(int, orderId) - self.orderId_nsprefix_ = None - self.message = _cast(None, message) - self.message_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, OrderType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if OrderType.subclass: - return OrderType.subclass(*args_, **kwargs_) - else: - return OrderType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_orderId(self): - return self.orderId - - def set_orderId(self, orderId): - self.orderId = orderId - - def get_message(self): - return self.message - - def set_message(self, message): - self.message = message - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="OrderType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("OrderType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "OrderType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="OrderType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="OrderType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="OrderType" - ): - if self.orderId is not None and "orderId" not in already_processed: - already_processed.add("orderId") - outfile.write( - ' orderId="%s"' - % self.gds_format_integer(self.orderId, input_name="orderId") - ) - if self.message is not None and "message" not in already_processed: - already_processed.add("message") - outfile.write( - " message=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.message), input_name="message" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="OrderType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("orderId", node) - if value is not None and "orderId" not in already_processed: - already_processed.add("orderId") - self.orderId = self.gds_parse_integer(value, node, "orderId") - value = find_attr_value_("message", node) - if value is not None and "message" not in already_processed: - already_processed.add("message") - self.message = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class OrderType - - -class StatusType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, statusId=None, valueOf_=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.statusId = _cast(int, statusId) - self.statusId_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, StatusType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if StatusType.subclass: - return StatusType.subclass(*args_, **kwargs_) - else: - return StatusType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_statusId(self): - return self.statusId - - def set_statusId(self, statusId): - self.statusId = statusId - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="StatusType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("StatusType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "StatusType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="StatusType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="StatusType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="StatusType" - ): - if self.statusId is not None and "statusId" not in already_processed: - already_processed.add("statusId") - outfile.write( - ' statusId="%s"' - % self.gds_format_integer(self.statusId, input_name="statusId") - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="StatusType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("statusId", node) - if value is not None and "statusId" not in already_processed: - already_processed.add("statusId") - self.statusId = self.gds_parse_integer(value, node, "statusId") - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class StatusType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from shipment_cancel_reply import *\n\n") - sys.stdout.write("import shipment_cancel_reply as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/XMLSchema": []} - -__all__ = ["Freightcom", "OrderType", "ShipmentCancelReplyType", "StatusType"] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_request.py b/modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_request.py deleted file mode 100644 index f3a61689b1..0000000000 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/shipment_cancel_request.py +++ /dev/null @@ -1,1915 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# Generated Fri Oct 21 12:33:21 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/shipment_cancel_request.py') -# -# Command line arguments: -# ./vendor/schemas/shipment_cancel_request.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/shipment_cancel_request.py" ./vendor/schemas/shipment_cancel_request.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# - -import sys - -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - username=None, - password=None, - version=None, - ShipmentCancelRequest=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.username = _cast(None, username) - self.username_nsprefix_ = None - self.password = _cast(None, password) - self.password_nsprefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.ShipmentCancelRequest = ShipmentCancelRequest - self.ShipmentCancelRequest_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_ShipmentCancelRequest(self): - return self.ShipmentCancelRequest - - def set_ShipmentCancelRequest(self, ShipmentCancelRequest): - self.ShipmentCancelRequest = ShipmentCancelRequest - - def get_username(self): - return self.username - - def set_username(self, username): - self.username = username - - def get_password(self): - return self.password - - def set_password(self, password): - self.password = password - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.ShipmentCancelRequest is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.username is not None and "username" not in already_processed: - already_processed.add("username") - outfile.write( - " username=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.username), input_name="username" - ) - ), - ) - ) - if self.password is not None and "password" not in already_processed: - already_processed.add("password") - outfile.write( - " password=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.password), input_name="password" - ) - ), - ) - ) - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.ShipmentCancelRequest is not None: - namespaceprefix_ = ( - self.ShipmentCancelRequest_nsprefix_ + ":" - if (UseCapturedNS_ and self.ShipmentCancelRequest_nsprefix_) - else "" - ) - self.ShipmentCancelRequest.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="ShipmentCancelRequest", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("username", node) - if value is not None and "username" not in already_processed: - already_processed.add("username") - self.username = value - value = find_attr_value_("password", node) - if value is not None and "password" not in already_processed: - already_processed.add("password") - self.password = value - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "ShipmentCancelRequest": - obj_ = ShipmentCancelRequestType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.ShipmentCancelRequest = obj_ - obj_.original_tagname_ = "ShipmentCancelRequest" - - -# end class Freightcom - - -class ShipmentCancelRequestType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, Order=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.Order = Order - self.Order_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, ShipmentCancelRequestType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ShipmentCancelRequestType.subclass: - return ShipmentCancelRequestType.subclass(*args_, **kwargs_) - else: - return ShipmentCancelRequestType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Order(self): - return self.Order - - def set_Order(self, Order): - self.Order = Order - - def _hasContent(self): - if self.Order is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShipmentCancelRequestType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ShipmentCancelRequestType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ShipmentCancelRequestType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="ShipmentCancelRequestType", - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ShipmentCancelRequestType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ShipmentCancelRequestType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShipmentCancelRequestType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.Order is not None: - namespaceprefix_ = ( - self.Order_nsprefix_ + ":" - if (UseCapturedNS_ and self.Order_nsprefix_) - else "" - ) - self.Order.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Order", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Order": - obj_ = OrderType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Order = obj_ - obj_.original_tagname_ = "Order" - - -# end class ShipmentCancelRequestType - - -class OrderType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, orderId=None, valueOf_=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.orderId = _cast(int, orderId) - self.orderId_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, OrderType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if OrderType.subclass: - return OrderType.subclass(*args_, **kwargs_) - else: - return OrderType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_orderId(self): - return self.orderId - - def set_orderId(self, orderId): - self.orderId = orderId - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="OrderType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("OrderType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "OrderType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="OrderType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="OrderType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="OrderType" - ): - if self.orderId is not None and "orderId" not in already_processed: - already_processed.add("orderId") - outfile.write( - ' orderId="%s"' - % self.gds_format_integer(self.orderId, input_name="orderId") - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="OrderType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("orderId", node) - if value is not None and "orderId" not in already_processed: - already_processed.add("orderId") - self.orderId = self.gds_parse_integer(value, node, "orderId") - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class OrderType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from shipment_cancel_request import *\n\n") - sys.stdout.write("import shipment_cancel_request as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/XMLSchema": []} - -__all__ = ["Freightcom", "OrderType", "ShipmentCancelRequestType"] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_reply.py b/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_reply.py deleted file mode 100644 index 5e22828b58..0000000000 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_reply.py +++ /dev/null @@ -1,4236 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# Generated Fri Oct 21 12:33:20 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/shipping_reply.py') -# -# Command line arguments: -# ./vendor/schemas/shipping_reply.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/shipping_reply.py" ./vendor/schemas/shipping_reply.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# - -import sys - -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, version=None, ShippingReply=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.ShippingReply = ShippingReply - self.ShippingReply_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_ShippingReply(self): - return self.ShippingReply - - def set_ShippingReply(self, ShippingReply): - self.ShippingReply = ShippingReply - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.ShippingReply is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.ShippingReply is not None: - namespaceprefix_ = ( - self.ShippingReply_nsprefix_ + ":" - if (UseCapturedNS_ and self.ShippingReply_nsprefix_) - else "" - ) - self.ShippingReply.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="ShippingReply", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "ShippingReply": - obj_ = ShippingReplyType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.ShippingReply = obj_ - obj_.original_tagname_ = "ShippingReply" - - -# end class Freightcom - - -class ShippingReplyType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - Order=None, - Carrier=None, - Reference=None, - Package=None, - Pickup=None, - TrackingURL=None, - Labels=None, - CustomsInvoice=None, - LabelData=None, - Quote=None, - BillingAddress=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.Order = Order - self.Order_nsprefix_ = None - self.Carrier = Carrier - self.Carrier_nsprefix_ = None - self.Reference = Reference - self.Reference_nsprefix_ = None - if Package is None: - self.Package = [] - else: - self.Package = Package - self.Package_nsprefix_ = None - self.Pickup = Pickup - self.Pickup_nsprefix_ = None - self.TrackingURL = TrackingURL - self.TrackingURL_nsprefix_ = None - self.Labels = Labels - self.Labels_nsprefix_ = None - self.CustomsInvoice = CustomsInvoice - self.CustomsInvoice_nsprefix_ = None - self.LabelData = LabelData - self.LabelData_nsprefix_ = None - self.Quote = Quote - self.Quote_nsprefix_ = None - self.BillingAddress = BillingAddress - self.BillingAddress_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ShippingReplyType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ShippingReplyType.subclass: - return ShippingReplyType.subclass(*args_, **kwargs_) - else: - return ShippingReplyType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Order(self): - return self.Order - - def set_Order(self, Order): - self.Order = Order - - def get_Carrier(self): - return self.Carrier - - def set_Carrier(self, Carrier): - self.Carrier = Carrier - - def get_Reference(self): - return self.Reference - - def set_Reference(self, Reference): - self.Reference = Reference - - def get_Package(self): - return self.Package - - def set_Package(self, Package): - self.Package = Package - - def add_Package(self, value): - self.Package.append(value) - - def insert_Package_at(self, index, value): - self.Package.insert(index, value) - - def replace_Package_at(self, index, value): - self.Package[index] = value - - def get_Pickup(self): - return self.Pickup - - def set_Pickup(self, Pickup): - self.Pickup = Pickup - - def get_TrackingURL(self): - return self.TrackingURL - - def set_TrackingURL(self, TrackingURL): - self.TrackingURL = TrackingURL - - def get_Labels(self): - return self.Labels - - def set_Labels(self, Labels): - self.Labels = Labels - - def get_CustomsInvoice(self): - return self.CustomsInvoice - - def set_CustomsInvoice(self, CustomsInvoice): - self.CustomsInvoice = CustomsInvoice - - def get_LabelData(self): - return self.LabelData - - def set_LabelData(self, LabelData): - self.LabelData = LabelData - - def get_Quote(self): - return self.Quote - - def set_Quote(self, Quote): - self.Quote = Quote - - def get_BillingAddress(self): - return self.BillingAddress - - def set_BillingAddress(self, BillingAddress): - self.BillingAddress = BillingAddress - - def _hasContent(self): - if ( - self.Order is not None - or self.Carrier is not None - or self.Reference is not None - or self.Package - or self.Pickup is not None - or self.TrackingURL is not None - or self.Labels is not None - or self.CustomsInvoice is not None - or self.LabelData is not None - or self.Quote is not None - or self.BillingAddress is not None - ): - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShippingReplyType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ShippingReplyType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ShippingReplyType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="ShippingReplyType", - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ShippingReplyType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ShippingReplyType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShippingReplyType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.Order is not None: - namespaceprefix_ = ( - self.Order_nsprefix_ + ":" - if (UseCapturedNS_ and self.Order_nsprefix_) - else "" - ) - self.Order.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Order", - pretty_print=pretty_print, - ) - if self.Carrier is not None: - namespaceprefix_ = ( - self.Carrier_nsprefix_ + ":" - if (UseCapturedNS_ and self.Carrier_nsprefix_) - else "" - ) - self.Carrier.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Carrier", - pretty_print=pretty_print, - ) - if self.Reference is not None: - namespaceprefix_ = ( - self.Reference_nsprefix_ + ":" - if (UseCapturedNS_ and self.Reference_nsprefix_) - else "" - ) - self.Reference.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Reference", - pretty_print=pretty_print, - ) - for Package_ in self.Package: - namespaceprefix_ = ( - self.Package_nsprefix_ + ":" - if (UseCapturedNS_ and self.Package_nsprefix_) - else "" - ) - Package_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Package", - pretty_print=pretty_print, - ) - if self.Pickup is not None: - namespaceprefix_ = ( - self.Pickup_nsprefix_ + ":" - if (UseCapturedNS_ and self.Pickup_nsprefix_) - else "" - ) - self.Pickup.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Pickup", - pretty_print=pretty_print, - ) - if self.TrackingURL is not None: - namespaceprefix_ = ( - self.TrackingURL_nsprefix_ + ":" - if (UseCapturedNS_ and self.TrackingURL_nsprefix_) - else "" - ) - showIndent(outfile, level, pretty_print) - outfile.write( - "<%sTrackingURL>%s%s" - % ( - namespaceprefix_, - self.gds_encode( - self.gds_format_string( - quote_xml(self.TrackingURL), input_name="TrackingURL" - ) - ), - namespaceprefix_, - eol_, - ) - ) - if self.Labels is not None: - namespaceprefix_ = ( - self.Labels_nsprefix_ + ":" - if (UseCapturedNS_ and self.Labels_nsprefix_) - else "" - ) - showIndent(outfile, level, pretty_print) - outfile.write( - "<%sLabels>%s%s" - % ( - namespaceprefix_, - self.gds_encode( - self.gds_format_string( - quote_xml(self.Labels), input_name="Labels" - ) - ), - namespaceprefix_, - eol_, - ) - ) - if self.CustomsInvoice is not None: - namespaceprefix_ = ( - self.CustomsInvoice_nsprefix_ + ":" - if (UseCapturedNS_ and self.CustomsInvoice_nsprefix_) - else "" - ) - showIndent(outfile, level, pretty_print) - outfile.write( - "<%sCustomsInvoice>%s%s" - % ( - namespaceprefix_, - self.gds_encode( - self.gds_format_string( - quote_xml(self.CustomsInvoice), input_name="CustomsInvoice" - ) - ), - namespaceprefix_, - eol_, - ) - ) - if self.LabelData is not None: - namespaceprefix_ = ( - self.LabelData_nsprefix_ + ":" - if (UseCapturedNS_ and self.LabelData_nsprefix_) - else "" - ) - self.LabelData.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="LabelData", - pretty_print=pretty_print, - ) - if self.Quote is not None: - namespaceprefix_ = ( - self.Quote_nsprefix_ + ":" - if (UseCapturedNS_ and self.Quote_nsprefix_) - else "" - ) - self.Quote.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Quote", - pretty_print=pretty_print, - ) - if self.BillingAddress is not None: - namespaceprefix_ = ( - self.BillingAddress_nsprefix_ + ":" - if (UseCapturedNS_ and self.BillingAddress_nsprefix_) - else "" - ) - self.BillingAddress.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="BillingAddress", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Order": - obj_ = OrderType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Order = obj_ - obj_.original_tagname_ = "Order" - elif nodeName_ == "Carrier": - obj_ = CarrierType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Carrier = obj_ - obj_.original_tagname_ = "Carrier" - elif nodeName_ == "Reference": - obj_ = ReferenceType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Reference = obj_ - obj_.original_tagname_ = "Reference" - elif nodeName_ == "Package": - obj_ = PackageType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Package.append(obj_) - obj_.original_tagname_ = "Package" - elif nodeName_ == "Pickup": - obj_ = PickupType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Pickup = obj_ - obj_.original_tagname_ = "Pickup" - elif nodeName_ == "TrackingURL": - value_ = child_.text - value_ = self.gds_parse_string(value_, node, "TrackingURL") - value_ = self.gds_validate_string(value_, node, "TrackingURL") - self.TrackingURL = value_ - self.TrackingURL_nsprefix_ = child_.prefix - elif nodeName_ == "Labels": - value_ = child_.text - value_ = self.gds_parse_string(value_, node, "Labels") - value_ = self.gds_validate_string(value_, node, "Labels") - self.Labels = value_ - self.Labels_nsprefix_ = child_.prefix - elif nodeName_ == "CustomsInvoice": - value_ = child_.text - value_ = self.gds_parse_string(value_, node, "CustomsInvoice") - value_ = self.gds_validate_string(value_, node, "CustomsInvoice") - self.CustomsInvoice = value_ - self.CustomsInvoice_nsprefix_ = child_.prefix - elif nodeName_ == "LabelData": - obj_ = LabelDataType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.LabelData = obj_ - obj_.original_tagname_ = "LabelData" - elif nodeName_ == "Quote": - obj_ = QuoteType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Quote = obj_ - obj_.original_tagname_ = "Quote" - elif nodeName_ == "BillingAddress": - obj_ = BillingAddressType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.BillingAddress = obj_ - obj_.original_tagname_ = "BillingAddress" - - -# end class ShippingReplyType - - -class OrderType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, id=None, valueOf_=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, OrderType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if OrderType.subclass: - return OrderType.subclass(*args_, **kwargs_) - else: - return OrderType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="OrderType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("OrderType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "OrderType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="OrderType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="OrderType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="OrderType" - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="OrderType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class OrderType - - -class CarrierType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - carrierName=None, - serviceName=None, - SCAC=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.carrierName = _cast(None, carrierName) - self.carrierName_nsprefix_ = None - self.serviceName = _cast(None, serviceName) - self.serviceName_nsprefix_ = None - self.SCAC = _cast(None, SCAC) - self.SCAC_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, CarrierType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CarrierType.subclass: - return CarrierType.subclass(*args_, **kwargs_) - else: - return CarrierType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_carrierName(self): - return self.carrierName - - def set_carrierName(self, carrierName): - self.carrierName = carrierName - - def get_serviceName(self): - return self.serviceName - - def set_serviceName(self, serviceName): - self.serviceName = serviceName - - def get_SCAC(self): - return self.SCAC - - def set_SCAC(self, SCAC): - self.SCAC = SCAC - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CarrierType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CarrierType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CarrierType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="CarrierType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CarrierType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="CarrierType", - ): - if self.carrierName is not None and "carrierName" not in already_processed: - already_processed.add("carrierName") - outfile.write( - " carrierName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.carrierName), input_name="carrierName" - ) - ), - ) - ) - if self.serviceName is not None and "serviceName" not in already_processed: - already_processed.add("serviceName") - outfile.write( - " serviceName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.serviceName), input_name="serviceName" - ) - ), - ) - ) - if self.SCAC is not None and "SCAC" not in already_processed: - already_processed.add("SCAC") - outfile.write( - " SCAC=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.SCAC), input_name="SCAC" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CarrierType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("carrierName", node) - if value is not None and "carrierName" not in already_processed: - already_processed.add("carrierName") - self.carrierName = value - value = find_attr_value_("serviceName", node) - if value is not None and "serviceName" not in already_processed: - already_processed.add("serviceName") - self.serviceName = value - value = find_attr_value_("SCAC", node) - if value is not None and "SCAC" not in already_processed: - already_processed.add("SCAC") - self.SCAC = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class CarrierType - - -class ReferenceType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, code=None, name=None, valueOf_=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.code = _cast(None, code) - self.code_nsprefix_ = None - self.name = _cast(None, name) - self.name_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ReferenceType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ReferenceType.subclass: - return ReferenceType.subclass(*args_, **kwargs_) - else: - return ReferenceType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_code(self): - return self.code - - def set_code(self, code): - self.code = code - - def get_name(self): - return self.name - - def set_name(self, name): - self.name = name - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ReferenceType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ReferenceType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ReferenceType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ReferenceType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ReferenceType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ReferenceType", - ): - if self.code is not None and "code" not in already_processed: - already_processed.add("code") - outfile.write( - " code=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.code), input_name="code" - ) - ), - ) - ) - if self.name is not None and "name" not in already_processed: - already_processed.add("name") - outfile.write( - " name=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.name), input_name="name" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ReferenceType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("code", node) - if value is not None and "code" not in already_processed: - already_processed.add("code") - self.code = value - value = find_attr_value_("name", node) - if value is not None and "name" not in already_processed: - already_processed.add("name") - self.name = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ReferenceType - - -class PackageType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, trackingNumber=None, valueOf_=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.trackingNumber = _cast(None, trackingNumber) - self.trackingNumber_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PackageType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PackageType.subclass: - return PackageType.subclass(*args_, **kwargs_) - else: - return PackageType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_trackingNumber(self): - return self.trackingNumber - - def set_trackingNumber(self, trackingNumber): - self.trackingNumber = trackingNumber - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackageType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PackageType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PackageType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PackageType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PackageType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="PackageType", - ): - if ( - self.trackingNumber is not None - and "trackingNumber" not in already_processed - ): - already_processed.add("trackingNumber") - outfile.write( - " trackingNumber=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.trackingNumber), - input_name="trackingNumber", - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackageType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("trackingNumber", node) - if value is not None and "trackingNumber" not in already_processed: - already_processed.add("trackingNumber") - self.trackingNumber = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class PackageType - - -class PickupType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, confirmationNumber=None, valueOf_=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.confirmationNumber = _cast(None, confirmationNumber) - self.confirmationNumber_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PickupType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PickupType.subclass: - return PickupType.subclass(*args_, **kwargs_) - else: - return PickupType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_confirmationNumber(self): - return self.confirmationNumber - - def set_confirmationNumber(self, confirmationNumber): - self.confirmationNumber = confirmationNumber - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PickupType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PickupType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PickupType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PickupType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PickupType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="PickupType" - ): - if ( - self.confirmationNumber is not None - and "confirmationNumber" not in already_processed - ): - already_processed.add("confirmationNumber") - outfile.write( - " confirmationNumber=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.confirmationNumber), - input_name="confirmationNumber", - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PickupType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("confirmationNumber", node) - if value is not None and "confirmationNumber" not in already_processed: - already_processed.add("confirmationNumber") - self.confirmationNumber = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class PickupType - - -class LabelDataType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, Label=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - if Label is None: - self.Label = [] - else: - self.Label = Label - self.Label_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, LabelDataType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if LabelDataType.subclass: - return LabelDataType.subclass(*args_, **kwargs_) - else: - return LabelDataType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Label(self): - return self.Label - - def set_Label(self, Label): - self.Label = Label - - def add_Label(self, value): - self.Label.append(value) - - def insert_Label_at(self, index, value): - self.Label.insert(index, value) - - def replace_Label_at(self, index, value): - self.Label[index] = value - - def _hasContent(self): - if self.Label: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="LabelDataType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("LabelDataType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "LabelDataType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="LabelDataType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="LabelDataType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="LabelDataType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="LabelDataType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - for Label_ in self.Label: - namespaceprefix_ = ( - self.Label_nsprefix_ + ":" - if (UseCapturedNS_ and self.Label_nsprefix_) - else "" - ) - Label_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Label", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Label": - obj_ = LabelType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Label.append(obj_) - obj_.original_tagname_ = "Label" - - -# end class LabelDataType - - -class LabelType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, Type=None, Data=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.Type = Type - self.Type_nsprefix_ = None - self.Data = Data - self.Data_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, LabelType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if LabelType.subclass: - return LabelType.subclass(*args_, **kwargs_) - else: - return LabelType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Type(self): - return self.Type - - def set_Type(self, Type): - self.Type = Type - - def get_Data(self): - return self.Data - - def set_Data(self, Data): - self.Data = Data - - def _hasContent(self): - if self.Type is not None or self.Data is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="LabelType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("LabelType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "LabelType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="LabelType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="LabelType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="LabelType" - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="LabelType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.Type is not None: - namespaceprefix_ = ( - self.Type_nsprefix_ + ":" - if (UseCapturedNS_ and self.Type_nsprefix_) - else "" - ) - showIndent(outfile, level, pretty_print) - outfile.write( - "<%sType>%s%s" - % ( - namespaceprefix_, - self.gds_encode( - self.gds_format_string(quote_xml(self.Type), input_name="Type") - ), - namespaceprefix_, - eol_, - ) - ) - if self.Data is not None: - namespaceprefix_ = ( - self.Data_nsprefix_ + ":" - if (UseCapturedNS_ and self.Data_nsprefix_) - else "" - ) - showIndent(outfile, level, pretty_print) - outfile.write( - "<%sData>%s%s" - % ( - namespaceprefix_, - self.gds_encode( - self.gds_format_string(quote_xml(self.Data), input_name="Data") - ), - namespaceprefix_, - eol_, - ) - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Type": - value_ = child_.text - value_ = self.gds_parse_string(value_, node, "Type") - value_ = self.gds_validate_string(value_, node, "Type") - self.Type = value_ - self.Type_nsprefix_ = child_.prefix - elif nodeName_ == "Data": - value_ = child_.text - value_ = self.gds_parse_string(value_, node, "Data") - value_ = self.gds_validate_string(value_, node, "Data") - self.Data = value_ - self.Data_nsprefix_ = child_.prefix - - -# end class LabelType - - -class QuoteType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - carrierId=None, - carrierName=None, - serviceId=None, - serviceName=None, - modeTransport=None, - transitDays=None, - baseCharge=None, - fuelSurcharge=None, - totalCharge=None, - currency=None, - Surcharge=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.carrierId = _cast(int, carrierId) - self.carrierId_nsprefix_ = None - self.carrierName = _cast(None, carrierName) - self.carrierName_nsprefix_ = None - self.serviceId = _cast(int, serviceId) - self.serviceId_nsprefix_ = None - self.serviceName = _cast(None, serviceName) - self.serviceName_nsprefix_ = None - self.modeTransport = _cast(None, modeTransport) - self.modeTransport_nsprefix_ = None - self.transitDays = _cast(int, transitDays) - self.transitDays_nsprefix_ = None - self.baseCharge = _cast(float, baseCharge) - self.baseCharge_nsprefix_ = None - self.fuelSurcharge = _cast(float, fuelSurcharge) - self.fuelSurcharge_nsprefix_ = None - self.totalCharge = _cast(float, totalCharge) - self.totalCharge_nsprefix_ = None - self.currency = _cast(None, currency) - self.currency_nsprefix_ = None - if Surcharge is None: - self.Surcharge = [] - else: - self.Surcharge = Surcharge - self.Surcharge_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, QuoteType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if QuoteType.subclass: - return QuoteType.subclass(*args_, **kwargs_) - else: - return QuoteType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Surcharge(self): - return self.Surcharge - - def set_Surcharge(self, Surcharge): - self.Surcharge = Surcharge - - def add_Surcharge(self, value): - self.Surcharge.append(value) - - def insert_Surcharge_at(self, index, value): - self.Surcharge.insert(index, value) - - def replace_Surcharge_at(self, index, value): - self.Surcharge[index] = value - - def get_carrierId(self): - return self.carrierId - - def set_carrierId(self, carrierId): - self.carrierId = carrierId - - def get_carrierName(self): - return self.carrierName - - def set_carrierName(self, carrierName): - self.carrierName = carrierName - - def get_serviceId(self): - return self.serviceId - - def set_serviceId(self, serviceId): - self.serviceId = serviceId - - def get_serviceName(self): - return self.serviceName - - def set_serviceName(self, serviceName): - self.serviceName = serviceName - - def get_modeTransport(self): - return self.modeTransport - - def set_modeTransport(self, modeTransport): - self.modeTransport = modeTransport - - def get_transitDays(self): - return self.transitDays - - def set_transitDays(self, transitDays): - self.transitDays = transitDays - - def get_baseCharge(self): - return self.baseCharge - - def set_baseCharge(self, baseCharge): - self.baseCharge = baseCharge - - def get_fuelSurcharge(self): - return self.fuelSurcharge - - def set_fuelSurcharge(self, fuelSurcharge): - self.fuelSurcharge = fuelSurcharge - - def get_totalCharge(self): - return self.totalCharge - - def set_totalCharge(self, totalCharge): - self.totalCharge = totalCharge - - def get_currency(self): - return self.currency - - def set_currency(self, currency): - self.currency = currency - - def _hasContent(self): - if self.Surcharge: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("QuoteType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "QuoteType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="QuoteType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="QuoteType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="QuoteType" - ): - if self.carrierId is not None and "carrierId" not in already_processed: - already_processed.add("carrierId") - outfile.write( - ' carrierId="%s"' - % self.gds_format_integer(self.carrierId, input_name="carrierId") - ) - if self.carrierName is not None and "carrierName" not in already_processed: - already_processed.add("carrierName") - outfile.write( - " carrierName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.carrierName), input_name="carrierName" - ) - ), - ) - ) - if self.serviceId is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - outfile.write( - ' serviceId="%s"' - % self.gds_format_integer(self.serviceId, input_name="serviceId") - ) - if self.serviceName is not None and "serviceName" not in already_processed: - already_processed.add("serviceName") - outfile.write( - " serviceName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.serviceName), input_name="serviceName" - ) - ), - ) - ) - if self.modeTransport is not None and "modeTransport" not in already_processed: - already_processed.add("modeTransport") - outfile.write( - " modeTransport=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.modeTransport), input_name="modeTransport" - ) - ), - ) - ) - if self.transitDays is not None and "transitDays" not in already_processed: - already_processed.add("transitDays") - outfile.write( - ' transitDays="%s"' - % self.gds_format_integer(self.transitDays, input_name="transitDays") - ) - if self.baseCharge is not None and "baseCharge" not in already_processed: - already_processed.add("baseCharge") - outfile.write( - ' baseCharge="%s"' - % self.gds_format_float(self.baseCharge, input_name="baseCharge") - ) - if self.fuelSurcharge is not None and "fuelSurcharge" not in already_processed: - already_processed.add("fuelSurcharge") - outfile.write( - ' fuelSurcharge="%s"' - % self.gds_format_float(self.fuelSurcharge, input_name="fuelSurcharge") - ) - if self.totalCharge is not None and "totalCharge" not in already_processed: - already_processed.add("totalCharge") - outfile.write( - ' totalCharge="%s"' - % self.gds_format_float(self.totalCharge, input_name="totalCharge") - ) - if self.currency is not None and "currency" not in already_processed: - already_processed.add("currency") - outfile.write( - " currency=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.currency), input_name="currency" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="QuoteType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - for Surcharge_ in self.Surcharge: - namespaceprefix_ = ( - self.Surcharge_nsprefix_ + ":" - if (UseCapturedNS_ and self.Surcharge_nsprefix_) - else "" - ) - Surcharge_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Surcharge", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("carrierId", node) - if value is not None and "carrierId" not in already_processed: - already_processed.add("carrierId") - self.carrierId = self.gds_parse_integer(value, node, "carrierId") - value = find_attr_value_("carrierName", node) - if value is not None and "carrierName" not in already_processed: - already_processed.add("carrierName") - self.carrierName = value - value = find_attr_value_("serviceId", node) - if value is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - self.serviceId = self.gds_parse_integer(value, node, "serviceId") - value = find_attr_value_("serviceName", node) - if value is not None and "serviceName" not in already_processed: - already_processed.add("serviceName") - self.serviceName = value - value = find_attr_value_("modeTransport", node) - if value is not None and "modeTransport" not in already_processed: - already_processed.add("modeTransport") - self.modeTransport = value - value = find_attr_value_("transitDays", node) - if value is not None and "transitDays" not in already_processed: - already_processed.add("transitDays") - self.transitDays = self.gds_parse_integer(value, node, "transitDays") - value = find_attr_value_("baseCharge", node) - if value is not None and "baseCharge" not in already_processed: - already_processed.add("baseCharge") - value = self.gds_parse_float(value, node, "baseCharge") - self.baseCharge = value - value = find_attr_value_("fuelSurcharge", node) - if value is not None and "fuelSurcharge" not in already_processed: - already_processed.add("fuelSurcharge") - value = self.gds_parse_float(value, node, "fuelSurcharge") - self.fuelSurcharge = value - value = find_attr_value_("totalCharge", node) - if value is not None and "totalCharge" not in already_processed: - already_processed.add("totalCharge") - value = self.gds_parse_float(value, node, "totalCharge") - self.totalCharge = value - value = find_attr_value_("currency", node) - if value is not None and "currency" not in already_processed: - already_processed.add("currency") - self.currency = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Surcharge": - obj_ = SurchargeType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Surcharge.append(obj_) - obj_.original_tagname_ = "Surcharge" - - -# end class QuoteType - - -class SurchargeType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - id=None, - name=None, - amount=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.name = _cast(None, name) - self.name_nsprefix_ = None - self.amount = _cast(float, amount) - self.amount_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, SurchargeType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if SurchargeType.subclass: - return SurchargeType.subclass(*args_, **kwargs_) - else: - return SurchargeType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_name(self): - return self.name - - def set_name(self, name): - self.name = name - - def get_amount(self): - return self.amount - - def set_amount(self, amount): - self.amount = amount - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="SurchargeType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("SurchargeType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "SurchargeType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="SurchargeType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="SurchargeType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="SurchargeType", - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - if self.name is not None and "name" not in already_processed: - already_processed.add("name") - outfile.write( - " name=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.name), input_name="name" - ) - ), - ) - ) - if self.amount is not None and "amount" not in already_processed: - already_processed.add("amount") - outfile.write( - ' amount="%s"' % self.gds_format_float(self.amount, input_name="amount") - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="SurchargeType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - value = find_attr_value_("name", node) - if value is not None and "name" not in already_processed: - already_processed.add("name") - self.name = value - value = find_attr_value_("amount", node) - if value is not None and "amount" not in already_processed: - already_processed.add("amount") - value = self.gds_parse_float(value, node, "amount") - self.amount = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class SurchargeType - - -class BillingAddressType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - CompanyName=None, - Address1=None, - Address2=None, - City=None, - ProvinceCode=None, - CountryCode=None, - zip=None, - PhoneNo=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.CompanyName = _cast(None, CompanyName) - self.CompanyName_nsprefix_ = None - self.Address1 = _cast(None, Address1) - self.Address1_nsprefix_ = None - self.Address2 = _cast(None, Address2) - self.Address2_nsprefix_ = None - self.City = _cast(None, City) - self.City_nsprefix_ = None - self.ProvinceCode = _cast(None, ProvinceCode) - self.ProvinceCode_nsprefix_ = None - self.CountryCode = _cast(None, CountryCode) - self.CountryCode_nsprefix_ = None - self.zip = _cast(None, zip) - self.zip_nsprefix_ = None - self.PhoneNo = _cast(None, PhoneNo) - self.PhoneNo_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, BillingAddressType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if BillingAddressType.subclass: - return BillingAddressType.subclass(*args_, **kwargs_) - else: - return BillingAddressType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_CompanyName(self): - return self.CompanyName - - def set_CompanyName(self, CompanyName): - self.CompanyName = CompanyName - - def get_Address1(self): - return self.Address1 - - def set_Address1(self, Address1): - self.Address1 = Address1 - - def get_Address2(self): - return self.Address2 - - def set_Address2(self, Address2): - self.Address2 = Address2 - - def get_City(self): - return self.City - - def set_City(self, City): - self.City = City - - def get_ProvinceCode(self): - return self.ProvinceCode - - def set_ProvinceCode(self, ProvinceCode): - self.ProvinceCode = ProvinceCode - - def get_CountryCode(self): - return self.CountryCode - - def set_CountryCode(self, CountryCode): - self.CountryCode = CountryCode - - def get_zip(self): - return self.zip - - def set_zip(self, zip): - self.zip = zip - - def get_PhoneNo(self): - return self.PhoneNo - - def set_PhoneNo(self, PhoneNo): - self.PhoneNo = PhoneNo - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="BillingAddressType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("BillingAddressType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "BillingAddressType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="BillingAddressType", - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="BillingAddressType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="BillingAddressType", - ): - if self.CompanyName is not None and "CompanyName" not in already_processed: - already_processed.add("CompanyName") - outfile.write( - " CompanyName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.CompanyName), input_name="CompanyName" - ) - ), - ) - ) - if self.Address1 is not None and "Address1" not in already_processed: - already_processed.add("Address1") - outfile.write( - " Address1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.Address1), input_name="Address1" - ) - ), - ) - ) - if self.Address2 is not None and "Address2" not in already_processed: - already_processed.add("Address2") - outfile.write( - " Address2=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.Address2), input_name="Address2" - ) - ), - ) - ) - if self.City is not None and "City" not in already_processed: - already_processed.add("City") - outfile.write( - " City=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.City), input_name="City" - ) - ), - ) - ) - if self.ProvinceCode is not None and "ProvinceCode" not in already_processed: - already_processed.add("ProvinceCode") - outfile.write( - " ProvinceCode=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.ProvinceCode), input_name="ProvinceCode" - ) - ), - ) - ) - if self.CountryCode is not None and "CountryCode" not in already_processed: - already_processed.add("CountryCode") - outfile.write( - " CountryCode=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.CountryCode), input_name="CountryCode" - ) - ), - ) - ) - if self.zip is not None and "zip" not in already_processed: - already_processed.add("zip") - outfile.write( - " zip=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.zip), input_name="zip") - ), - ) - ) - if self.PhoneNo is not None and "PhoneNo" not in already_processed: - already_processed.add("PhoneNo") - outfile.write( - " PhoneNo=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.PhoneNo), input_name="PhoneNo" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="BillingAddressType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("CompanyName", node) - if value is not None and "CompanyName" not in already_processed: - already_processed.add("CompanyName") - self.CompanyName = value - value = find_attr_value_("Address1", node) - if value is not None and "Address1" not in already_processed: - already_processed.add("Address1") - self.Address1 = value - value = find_attr_value_("Address2", node) - if value is not None and "Address2" not in already_processed: - already_processed.add("Address2") - self.Address2 = value - value = find_attr_value_("City", node) - if value is not None and "City" not in already_processed: - already_processed.add("City") - self.City = value - value = find_attr_value_("ProvinceCode", node) - if value is not None and "ProvinceCode" not in already_processed: - already_processed.add("ProvinceCode") - self.ProvinceCode = value - value = find_attr_value_("CountryCode", node) - if value is not None and "CountryCode" not in already_processed: - already_processed.add("CountryCode") - self.CountryCode = value - value = find_attr_value_("zip", node) - if value is not None and "zip" not in already_processed: - already_processed.add("zip") - self.zip = value - value = find_attr_value_("PhoneNo", node) - if value is not None and "PhoneNo" not in already_processed: - already_processed.add("PhoneNo") - self.PhoneNo = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class BillingAddressType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from shipping_reply import *\n\n") - sys.stdout.write("import shipping_reply as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/XMLSchema": []} - -__all__ = [ - "BillingAddressType", - "CarrierType", - "Freightcom", - "LabelDataType", - "LabelType", - "OrderType", - "PackageType", - "PickupType", - "QuoteType", - "ReferenceType", - "ShippingReplyType", - "SurchargeType", -] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_request.py b/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_request.py index 1993f125c1..bde1ebf630 100644 --- a/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_request.py +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_request.py @@ -1,5953 +1,246 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +from attr import s +from typing import Optional, List +from jstruct import JStruct, JList + + +@s(auto_attribs=True) +class NumberType: + number: Optional[str] = None + extension: Optional[int] = None + + +@s(auto_attribs=True) +class BrokerType: + use_carrier: Optional[bool] = None + name: Optional[str] = None + account_number: Optional[str] = None + phone_number: Optional[NumberType] = JStruct[NumberType] + fax_number: Optional[NumberType] = JStruct[NumberType] + email_address: Optional[str] = None + usmca_number: Optional[str] = None + fda_number: Optional[str] = None + + +@s(auto_attribs=True) +class TotalCostType: + currency: Optional[str] = None + value: Optional[int] = None + + +@s(auto_attribs=True) +class WeightType: + unit: Optional[str] = None + value: Optional[float] = None + + +@s(auto_attribs=True) +class ProductType: + product_name: Optional[str] = None + weight: Optional[WeightType] = JStruct[WeightType] + hs_code: Optional[str] = None + country_of_origin: Optional[str] = None + num_units: Optional[int] = None + unit_price: Optional[TotalCostType] = JStruct[TotalCostType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class AddressType: + address_line_1: Optional[str] = None + address_line_2: Optional[str] = None + unit_number: Optional[str] = None + city: Optional[str] = None + region: Optional[str] = None + country: Optional[str] = None + postal_code: Optional[str] = None + + +@s(auto_attribs=True) +class TaxRecipientType: + type: Optional[str] = None + shipper_tax_identifier: Optional[str] = None + receiver_tax_identifier: Optional[str] = None + third_party_tax_identifier: Optional[str] = None + other_tax_identifier: Optional[str] = None + name: Optional[str] = None + address: Optional[AddressType] = JStruct[AddressType] + phone_number: Optional[NumberType] = JStruct[NumberType] + reason_for_export: Optional[str] = None + additional_remarks: Optional[str] = None + comments: Optional[str] = None -# -# Generated Fri Oct 21 12:33:20 2022 by generateDS.py version 2.41.1. -# Python 3.10.8 (v3.10.8:aaaf517424, Oct 11 2022, 10:14:40) [Clang 13.0.0 (clang-1300.0.29.30)] -# -# Command line options: -# ('--no-namespace-defs', '') -# ('-o', './karrio.schemas.freightcom/shipping_request.py') -# -# Command line arguments: -# ./vendor/schemas/shipping_request.xsd -# -# Command line: -# /Users/danielk/Documents/karrio/karrio/.venv/karrio/bin/generateDS --no-namespace-defs -o "./karrio.schemas.freightcom/shipping_request.py" ./vendor/schemas/shipping_request.xsd -# -# Current working directory (os.getcwd()): -# freightcom -# - -import sys - -try: - ModulenotfoundExp_ = ModuleNotFoundError -except NameError: - ModulenotfoundExp_ = ImportError -from six.moves import zip_longest -import os -import re as re_ -import base64 -import datetime as datetime_ -import decimal as decimal_ -from lxml import etree as etree_ - - -Validate_simpletypes_ = True -SaveElementTreeNode = True -TagNamePrefix = "" -if sys.version_info.major == 2: - BaseStrType_ = basestring -else: - BaseStrType_ = str - - -def parsexml_(infile, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - try: - if isinstance(infile, os.PathLike): - infile = os.path.join(infile) - except AttributeError: - pass - doc = etree_.parse(infile, parser=parser, **kwargs) - return doc - - -def parsexmlstring_(instring, parser=None, **kwargs): - if parser is None: - # Use the lxml ElementTree compatible parser so that, e.g., - # we ignore comments. - try: - parser = etree_.ETCompatXMLParser() - except AttributeError: - # fallback to xml.etree - parser = etree_.XMLParser() - element = etree_.fromstring(instring, parser=parser, **kwargs) - return element - - -# -# Namespace prefix definition table (and other attributes, too) -# -# The module generatedsnamespaces, if it is importable, must contain -# a dictionary named GeneratedsNamespaceDefs. This Python dictionary -# should map element type names (strings) to XML schema namespace prefix -# definitions. The export method for any class for which there is -# a namespace prefix definition, will export that definition in the -# XML representation of that element. See the export method of -# any generated element type class for an example of the use of this -# table. -# A sample table is: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceDefs = { -# "ElementtypeA": "http://www.xxx.com/namespaceA", -# "ElementtypeB": "http://www.xxx.com/namespaceB", -# } -# -# Additionally, the generatedsnamespaces module can contain a python -# dictionary named GenerateDSNamespaceTypePrefixes that associates element -# types with the namespace prefixes that are to be added to the -# "xsi:type" attribute value. See the _exportAttributes method of -# any generated element type and the generation of "xsi:type" for an -# example of the use of this table. -# An example table: -# -# # File: generatedsnamespaces.py -# -# GenerateDSNamespaceTypePrefixes = { -# "ElementtypeC": "aaa:", -# "ElementtypeD": "bbb:", -# } -# - -try: - from generatedsnamespaces import GenerateDSNamespaceDefs as GenerateDSNamespaceDefs_ -except ModulenotfoundExp_: - GenerateDSNamespaceDefs_ = {} -try: - from generatedsnamespaces import ( - GenerateDSNamespaceTypePrefixes as GenerateDSNamespaceTypePrefixes_, - ) -except ModulenotfoundExp_: - GenerateDSNamespaceTypePrefixes_ = {} - -# -# You can replace the following class definition by defining an -# importable module named "generatedscollector" containing a class -# named "GdsCollector". See the default class definition below for -# clues about the possible content of that class. -# -try: - from generatedscollector import GdsCollector as GdsCollector_ -except ModulenotfoundExp_: - - class GdsCollector_(object): - def __init__(self, messages=None): - if messages is None: - self.messages = [] - else: - self.messages = messages - - def add_message(self, msg): - self.messages.append(msg) - - def get_messages(self): - return self.messages - - def clear_messages(self): - self.messages = [] - - def print_messages(self): - for msg in self.messages: - print("Warning: {}".format(msg)) - - def write_messages(self, outstream): - for msg in self.messages: - outstream.write("Warning: {}\n".format(msg)) - - -# -# The super-class for enum types -# - -try: - from enum import Enum -except ModulenotfoundExp_: - Enum = object - -# -# The root super-class for element type classes -# -# Calls to the methods in these classes are generated by generateDS.py. -# You can replace these methods by re-implementing the following class -# in a module named generatedssuper.py. - -try: - from generatedssuper import GeneratedsSuper -except ModulenotfoundExp_ as exp: - try: - from generatedssupersuper import GeneratedsSuperSuper - except ModulenotfoundExp_ as exp: - - class GeneratedsSuperSuper(object): - pass - - class GeneratedsSuper(GeneratedsSuperSuper): - __hash__ = object.__hash__ - tzoff_pattern = re_.compile(r"(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$") - - class _FixedOffsetTZ(datetime_.tzinfo): - def __init__(self, offset, name): - self.__offset = datetime_.timedelta(minutes=offset) - self.__name = name - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return None - - def __str__(self): - settings = { - "str_pretty_print": True, - "str_indent_level": 0, - "str_namespaceprefix": "", - "str_name": self.__class__.__name__, - "str_namespacedefs": "", - } - for n in settings: - if hasattr(self, n): - settings[n] = getattr(self, n) - if sys.version_info.major == 2: - from StringIO import StringIO - else: - from io import StringIO - output = StringIO() - self.export( - output, - settings["str_indent_level"], - pretty_print=settings["str_pretty_print"], - namespaceprefix_=settings["str_namespaceprefix"], - name_=settings["str_name"], - namespacedef_=settings["str_namespacedefs"], - ) - strval = output.getvalue() - output.close() - return strval - - def gds_format_string(self, input_data, input_name=""): - return input_data - - def gds_parse_string(self, input_data, node=None, input_name=""): - return input_data - - def gds_validate_string(self, input_data, node=None, input_name=""): - if not input_data: - return "" - else: - return input_data - - def gds_format_base64(self, input_data, input_name=""): - return base64.b64encode(input_data).decode("ascii") - - def gds_validate_base64(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_integer(self, input_data, input_name=""): - return "%d" % int(input_data) - - def gds_parse_integer(self, input_data, node=None, input_name=""): - try: - ival = int(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires integer value: %s" % exp) - return ival - - def gds_validate_integer(self, input_data, node=None, input_name=""): - try: - value = int(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires integer value") - return value - - def gds_format_integer_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_integer_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - int(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of integer values") - return values - - def gds_format_float(self, input_data, input_name=""): - return ("%.15f" % float(input_data)).rstrip("0") - - def gds_parse_float(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires float or double value: %s" % exp) - return fval_ - - def gds_validate_float(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires float value") - return value - - def gds_format_float_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_float_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of float values") - return values - - def gds_format_decimal(self, input_data, input_name=""): - return_value = "%s" % input_data - if "." in return_value: - return_value = return_value.rstrip("0") - if return_value.endswith("."): - return_value = return_value.rstrip(".") - return return_value - - def gds_parse_decimal(self, input_data, node=None, input_name=""): - try: - decimal_value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return decimal_value - - def gds_validate_decimal(self, input_data, node=None, input_name=""): - try: - value = decimal_.Decimal(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires decimal value") - return value - - def gds_format_decimal_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return " ".join([self.gds_format_decimal(item) for item in input_data]) - - def gds_validate_decimal_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - decimal_.Decimal(value) - except (TypeError, ValueError): - raise_parse_error(node, "Requires sequence of decimal values") - return values - - def gds_format_double(self, input_data, input_name=""): - return "%s" % input_data - - def gds_parse_double(self, input_data, node=None, input_name=""): - try: - fval_ = float(input_data) - except (TypeError, ValueError) as exp: - raise_parse_error(node, "Requires double or float value: %s" % exp) - return fval_ - - def gds_validate_double(self, input_data, node=None, input_name=""): - try: - value = float(input_data) - except (TypeError, ValueError): - raise_parse_error(node, "Requires double or float value") - return value - - def gds_format_double_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_double_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - try: - float(value) - except (TypeError, ValueError): - raise_parse_error( - node, "Requires sequence of double or float values" - ) - return values - - def gds_format_boolean(self, input_data, input_name=""): - return ("%s" % input_data).lower() - - def gds_parse_boolean(self, input_data, node=None, input_name=""): - input_data = input_data.strip() - if input_data in ("true", "1"): - bval = True - elif input_data in ("false", "0"): - bval = False - else: - raise_parse_error(node, "Requires boolean value") - return bval - - def gds_validate_boolean(self, input_data, node=None, input_name=""): - if input_data not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, "Requires boolean value " "(one of True, 1, False, 0)" - ) - return input_data - - def gds_format_boolean_list(self, input_data, input_name=""): - if len(input_data) > 0 and not isinstance(input_data[0], BaseStrType_): - input_data = [str(s) for s in input_data] - return "%s" % " ".join(input_data) - - def gds_validate_boolean_list(self, input_data, node=None, input_name=""): - values = input_data.split() - for value in values: - value = self.gds_parse_boolean(value, node, input_name) - if value not in ( - True, - 1, - False, - 0, - ): - raise_parse_error( - node, - "Requires sequence of boolean values " - "(one of True, 1, False, 0)", - ) - return values - - def gds_validate_datetime(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_datetime(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%04d-%02d-%02dT%02d:%02d:%02d.%s" % ( - input_data.year, - input_data.month, - input_data.day, - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - @classmethod - def gds_parse_datetime(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - time_parts = input_data.split(".") - if len(time_parts) > 1: - micro_seconds = int(float("0." + time_parts[1]) * 1000000) - input_data = "%s.%s" % ( - time_parts[0], - "{}".format(micro_seconds).rjust(6, "0"), - ) - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%dT%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt - - def gds_validate_date(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_date(self, input_data, input_name=""): - _svalue = "%04d-%02d-%02d" % ( - input_data.year, - input_data.month, - input_data.day, - ) - try: - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - except AttributeError: - pass - return _svalue - - @classmethod - def gds_parse_date(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - dt = datetime_.datetime.strptime(input_data, "%Y-%m-%d") - dt = dt.replace(tzinfo=tz) - return dt.date() - - def gds_validate_time(self, input_data, node=None, input_name=""): - return input_data - - def gds_format_time(self, input_data, input_name=""): - if input_data.microsecond == 0: - _svalue = "%02d:%02d:%02d" % ( - input_data.hour, - input_data.minute, - input_data.second, - ) - else: - _svalue = "%02d:%02d:%02d.%s" % ( - input_data.hour, - input_data.minute, - input_data.second, - ("%f" % (float(input_data.microsecond) / 1000000))[2:], - ) - if input_data.tzinfo is not None: - tzoff = input_data.tzinfo.utcoffset(input_data) - if tzoff is not None: - total_seconds = tzoff.seconds + (86400 * tzoff.days) - if total_seconds == 0: - _svalue += "Z" - else: - if total_seconds < 0: - _svalue += "-" - total_seconds *= -1 - else: - _svalue += "+" - hours = total_seconds // 3600 - minutes = (total_seconds - (hours * 3600)) // 60 - _svalue += "{0:02d}:{1:02d}".format(hours, minutes) - return _svalue - - def gds_validate_simple_patterns(self, patterns, target): - # pat is a list of lists of strings/patterns. - # The target value must match at least one of the patterns - # in order for the test to succeed. - found1 = True - target = str(target) - for patterns1 in patterns: - found2 = False - for patterns2 in patterns1: - mo = re_.search(patterns2, target) - if mo is not None and len(mo.group(0)) == len(target): - found2 = True - break - if not found2: - found1 = False - break - return found1 - - @classmethod - def gds_parse_time(cls, input_data): - tz = None - if input_data[-1] == "Z": - tz = GeneratedsSuper._FixedOffsetTZ(0, "UTC") - input_data = input_data[:-1] - else: - results = GeneratedsSuper.tzoff_pattern.search(input_data) - if results is not None: - tzoff_parts = results.group(2).split(":") - tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1]) - if results.group(1) == "-": - tzoff *= -1 - tz = GeneratedsSuper._FixedOffsetTZ(tzoff, results.group(0)) - input_data = input_data[:-6] - if len(input_data.split(".")) > 1: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S.%f") - else: - dt = datetime_.datetime.strptime(input_data, "%H:%M:%S") - dt = dt.replace(tzinfo=tz) - return dt.time() - - def gds_check_cardinality_( - self, value, input_name, min_occurs=0, max_occurs=1, required=None - ): - if value is None: - length = 0 - elif isinstance(value, list): - length = len(value) - else: - length = 1 - if required is not None: - if required and length < 1: - self.gds_collector_.add_message( - "Required value {}{} is missing".format( - input_name, self.gds_get_node_lineno_() - ) - ) - if length < min_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is below " - "the minimum allowed, " - "expected at least {}, found {}".format( - input_name, self.gds_get_node_lineno_(), min_occurs, length - ) - ) - elif length > max_occurs: - self.gds_collector_.add_message( - "Number of values for {}{} is above " - "the maximum allowed, " - "expected at most {}, found {}".format( - input_name, self.gds_get_node_lineno_(), max_occurs, length - ) - ) - - def gds_validate_builtin_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value, input_name=input_name) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_validate_defined_ST_( - self, - validator, - value, - input_name, - min_occurs=None, - max_occurs=None, - required=None, - ): - if value is not None: - try: - validator(value) - except GDSParseError as parse_error: - self.gds_collector_.add_message(str(parse_error)) - - def gds_str_lower(self, instring): - return instring.lower() - - def get_path_(self, node): - path_list = [] - self.get_path_list_(node, path_list) - path_list.reverse() - path = "/".join(path_list) - return path - - Tag_strip_pattern_ = re_.compile(r"\{.*\}") - - def get_path_list_(self, node, path_list): - if node is None: - return - tag = GeneratedsSuper.Tag_strip_pattern_.sub("", node.tag) - if tag: - path_list.append(tag) - self.get_path_list_(node.getparent(), path_list) - - def get_class_obj_(self, node, default_class=None): - class_obj1 = default_class - if "xsi" in node.nsmap: - classname = node.get("{%s}type" % node.nsmap["xsi"]) - if classname is not None: - names = classname.split(":") - if len(names) == 2: - classname = names[1] - class_obj2 = globals().get(classname) - if class_obj2 is not None: - class_obj1 = class_obj2 - return class_obj1 - - def gds_build_any(self, node, type_name=None): - # provide default value in case option --disable-xml is used. - content = "" - content = etree_.tostring(node, encoding="unicode") - return content - - @classmethod - def gds_reverse_node_mapping(cls, mapping): - return dict(((v, k) for k, v in mapping.items())) - - @staticmethod - def gds_encode(instring): - if sys.version_info.major == 2: - if ExternalEncoding: - encoding = ExternalEncoding - else: - encoding = "utf-8" - return instring.encode(encoding) - else: - return instring - - @staticmethod - def convert_unicode(instring): - if isinstance(instring, str): - result = quote_xml(instring) - elif sys.version_info.major == 2 and isinstance(instring, unicode): - result = quote_xml(instring).encode("utf8") - else: - result = GeneratedsSuper.gds_encode(str(instring)) - return result - - def __eq__(self, other): - def excl_select_objs_(obj): - return obj[0] != "parent_object_" and obj[0] != "gds_collector_" - - if type(self) != type(other): - return False - return all( - x == y - for x, y in zip_longest( - filter(excl_select_objs_, self.__dict__.items()), - filter(excl_select_objs_, other.__dict__.items()), - ) - ) - - def __ne__(self, other): - return not self.__eq__(other) - - # Django ETL transform hooks. - def gds_djo_etl_transform(self): - pass - - def gds_djo_etl_transform_db_obj(self, dbobj): - pass - - # SQLAlchemy ETL transform hooks. - def gds_sqa_etl_transform(self): - return 0, None - - def gds_sqa_etl_transform_db_obj(self, dbobj): - pass - - def gds_get_node_lineno_(self): - if ( - hasattr(self, "gds_elementtree_node_") - and self.gds_elementtree_node_ is not None - ): - return " near line {}".format(self.gds_elementtree_node_.sourceline) - else: - return "" - - def getSubclassFromModule_(module, class_): - """Get the subclass of a class from a specific module.""" - name = class_.__name__ + "Sub" - if hasattr(module, name): - return getattr(module, name) - else: - return None - - -# -# If you have installed IPython you can uncomment and use the following. -# IPython is available from http://ipython.scipy.org/. -# - -## from IPython.Shell import IPShellEmbed -## args = '' -## ipshell = IPShellEmbed(args, -## banner = 'Dropping into IPython', -## exit_msg = 'Leaving Interpreter, back to program.') - -# Then use the following line where and when you want to drop into the -# IPython shell: -# ipshell(' -- Entering ipshell.\nHit Ctrl-D to exit') - -# -# Globals -# - -ExternalEncoding = "" -# Set this to false in order to deactivate during export, the use of -# name space prefixes captured from the input document. -UseCapturedNS_ = True -CapturedNsmap_ = {} -Tag_pattern_ = re_.compile(r"({.*})?(.*)") -String_cleanup_pat_ = re_.compile(r"[\n\r\s]+") -Namespace_extract_pat_ = re_.compile(r"{(.*)}(.*)") -CDATA_pattern_ = re_.compile(r"", re_.DOTALL) - -# Change this to redirect the generated superclass module to use a -# specific subclass module. -CurrentSubclassModule_ = None - -# -# Support/utility functions. -# - - -def showIndent(outfile, level, pretty_print=True): - if pretty_print: - for idx in range(level): - outfile.write(" ") - - -def quote_xml(inStr): - "Escape markup chars, but do not modify CDATA sections." - if not inStr: - return "" - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s2 = "" - pos = 0 - matchobjects = CDATA_pattern_.finditer(s1) - for mo in matchobjects: - s3 = s1[pos : mo.start()] - s2 += quote_xml_aux(s3) - s2 += s1[mo.start() : mo.end()] - pos = mo.end() - s3 = s1[pos:] - s2 += quote_xml_aux(s3) - return s2 - - -def quote_xml_aux(inStr): - s1 = inStr.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - return s1 - - -def quote_attrib(inStr): - s1 = isinstance(inStr, BaseStrType_) and inStr or "%s" % inStr - s1 = s1.replace("&", "&") - s1 = s1.replace("<", "<") - s1 = s1.replace(">", ">") - s1 = s1.replace("\n", " ") - if '"' in s1: - if "'" in s1: - s1 = '"%s"' % s1.replace('"', """) - else: - s1 = "'%s'" % s1 - else: - s1 = '"%s"' % s1 - return s1 - - -def quote_python(inStr): - s1 = inStr - if s1.find("'") == -1: - if s1.find("\n") == -1: - return "'%s'" % s1 - else: - return "'''%s'''" % s1 - else: - if s1.find('"') != -1: - s1 = s1.replace('"', '\\"') - if s1.find("\n") == -1: - return '"%s"' % s1 - else: - return '"""%s"""' % s1 - - -def get_all_text_(node): - if node.text is not None: - text = node.text - else: - text = "" - for child in node: - if child.tail is not None: - text += child.tail - return text - - -def find_attr_value_(attr_name, node): - attrs = node.attrib - attr_parts = attr_name.split(":") - value = None - if len(attr_parts) == 1: - value = attrs.get(attr_name) - elif len(attr_parts) == 2: - prefix, name = attr_parts - if prefix == "xml": - namespace = "http://www.w3.org/XML/1998/namespace" - else: - namespace = node.nsmap.get(prefix) - if namespace is not None: - value = attrs.get( - "{%s}%s" - % ( - namespace, - name, - ) - ) - return value - - -def encode_str_2_3(instr): - return instr - - -class GDSParseError(Exception): - pass - - -def raise_parse_error(node, msg): - if node is not None: - msg = "%s (element %s/line %d)" % ( - msg, - node.tag, - node.sourceline, - ) - raise GDSParseError(msg) - - -class MixedContainer: - # Constants for category: - CategoryNone = 0 - CategoryText = 1 - CategorySimple = 2 - CategoryComplex = 3 - # Constants for content_type: - TypeNone = 0 - TypeText = 1 - TypeString = 2 - TypeInteger = 3 - TypeFloat = 4 - TypeDecimal = 5 - TypeDouble = 6 - TypeBoolean = 7 - TypeBase64 = 8 - - def __init__(self, category, content_type, name, value): - self.category = category - self.content_type = content_type - self.name = name - self.value = value - - def getCategory(self): - return self.category - - def getContenttype(self, content_type): - return self.content_type - - def getValue(self): - return self.value - - def getName(self): - return self.name - - def export(self, outfile, level, name, namespace, pretty_print=True): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - outfile.write(self.value) - elif self.category == MixedContainer.CategorySimple: - self.exportSimple(outfile, level, name) - else: # category == MixedContainer.CategoryComplex - self.value.export( - outfile, level, namespace, name_=name, pretty_print=pretty_print - ) - - def exportSimple(self, outfile, level, name): - if self.content_type == MixedContainer.TypeString: - outfile.write("<%s>%s" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - outfile.write("<%s>%d" % (self.name, self.value, self.name)) - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - outfile.write("<%s>%f" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeDouble: - outfile.write("<%s>%g" % (self.name, self.value, self.name)) - elif self.content_type == MixedContainer.TypeBase64: - outfile.write( - "<%s>%s" % (self.name, base64.b64encode(self.value), self.name) - ) - - def to_etree(self, element, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.category == MixedContainer.CategoryText: - # Prevent exporting empty content as empty lines. - if self.value.strip(): - if len(element) > 0: - if element[-1].tail is None: - element[-1].tail = self.value - else: - element[-1].tail += self.value - else: - if element.text is None: - element.text = self.value - else: - element.text += self.value - elif self.category == MixedContainer.CategorySimple: - subelement = etree_.SubElement(element, "%s" % self.name) - subelement.text = self.to_etree_simple() - else: # category == MixedContainer.CategoryComplex - self.value.to_etree(element) - - def to_etree_simple(self, mapping_=None, reverse_mapping_=None, nsmap_=None): - if self.content_type == MixedContainer.TypeString: - text = self.value - elif ( - self.content_type == MixedContainer.TypeInteger - or self.content_type == MixedContainer.TypeBoolean - ): - text = "%d" % self.value - elif ( - self.content_type == MixedContainer.TypeFloat - or self.content_type == MixedContainer.TypeDecimal - ): - text = "%f" % self.value - elif self.content_type == MixedContainer.TypeDouble: - text = "%g" % self.value - elif self.content_type == MixedContainer.TypeBase64: - text = "%s" % base64.b64encode(self.value) - return text - - def exportLiteral(self, outfile, level, name): - if self.category == MixedContainer.CategoryText: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - elif self.category == MixedContainer.CategorySimple: - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s", "%s"),\n' - % (self.category, self.content_type, self.name, self.value) - ) - else: # category == MixedContainer.CategoryComplex - showIndent(outfile, level) - outfile.write( - 'model_.MixedContainer(%d, %d, "%s",\n' - % ( - self.category, - self.content_type, - self.name, - ) - ) - self.value.exportLiteral(outfile, level + 1) - showIndent(outfile, level) - outfile.write(")\n") - - -class MemberSpec_(object): - def __init__( - self, - name="", - data_type="", - container=0, - optional=0, - child_attrs=None, - choice=None, - ): - self.name = name - self.data_type = data_type - self.container = container - self.child_attrs = child_attrs - self.choice = choice - self.optional = optional - - def set_name(self, name): - self.name = name - - def get_name(self): - return self.name - - def set_data_type(self, data_type): - self.data_type = data_type - - def get_data_type_chain(self): - return self.data_type - - def get_data_type(self): - if isinstance(self.data_type, list): - if len(self.data_type) > 0: - return self.data_type[-1] - else: - return "xs:string" - else: - return self.data_type - - def set_container(self, container): - self.container = container - - def get_container(self): - return self.container - - def set_child_attrs(self, child_attrs): - self.child_attrs = child_attrs - - def get_child_attrs(self): - return self.child_attrs - - def set_choice(self, choice): - self.choice = choice - - def get_choice(self): - return self.choice - - def set_optional(self, optional): - self.optional = optional - - def get_optional(self): - return self.optional - - -def _cast(typ, value): - if typ is None or value is None: - return value - return typ(value) - - -# -# Data representation classes. -# - - -class Freightcom(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - username=None, - password=None, - version=None, - ShippingRequest=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.username = _cast(None, username) - self.username_nsprefix_ = None - self.password = _cast(None, password) - self.password_nsprefix_ = None - self.version = _cast(None, version) - self.version_nsprefix_ = None - self.ShippingRequest = ShippingRequest - self.ShippingRequest_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, Freightcom) - if subclass is not None: - return subclass(*args_, **kwargs_) - if Freightcom.subclass: - return Freightcom.subclass(*args_, **kwargs_) - else: - return Freightcom(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_ShippingRequest(self): - return self.ShippingRequest - - def set_ShippingRequest(self, ShippingRequest): - self.ShippingRequest = ShippingRequest - - def get_username(self): - return self.username - - def set_username(self, username): - self.username = username - - def get_password(self): - return self.password - - def set_password(self, password): - self.password = password - - def get_version(self): - return self.version - - def set_version(self, version): - self.version = version - - def _hasContent(self): - if self.ShippingRequest is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("Freightcom") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "Freightcom": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="Freightcom" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="Freightcom", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="Freightcom" - ): - if self.username is not None and "username" not in already_processed: - already_processed.add("username") - outfile.write( - " username=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.username), input_name="username" - ) - ), - ) - ) - if self.password is not None and "password" not in already_processed: - already_processed.add("password") - outfile.write( - " password=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.password), input_name="password" - ) - ), - ) - ) - if self.version is not None and "version" not in already_processed: - already_processed.add("version") - outfile.write( - " version=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.version), input_name="version" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="Freightcom", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.ShippingRequest is not None: - namespaceprefix_ = ( - self.ShippingRequest_nsprefix_ + ":" - if (UseCapturedNS_ and self.ShippingRequest_nsprefix_) - else "" - ) - self.ShippingRequest.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="ShippingRequest", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("username", node) - if value is not None and "username" not in already_processed: - already_processed.add("username") - self.username = value - value = find_attr_value_("password", node) - if value is not None and "password" not in already_processed: - already_processed.add("password") - self.password = value - value = find_attr_value_("version", node) - if value is not None and "version" not in already_processed: - already_processed.add("version") - self.version = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "ShippingRequest": - obj_ = ShippingRequestType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.ShippingRequest = obj_ - obj_.original_tagname_ = "ShippingRequest" - - -# end class Freightcom - - -class ShippingRequestType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - saturdayPickupRequired=None, - homelandSecurity=None, - pierCharge=None, - exhibitionConventionSite=None, - militaryBaseDelivery=None, - customsIn_bondFreight=None, - limitedAccess=None, - excessLength=None, - tailgatePickup=None, - residentialPickup=None, - crossBorderFee=None, - notifyRecipient=None, - singleShipment=None, - tailgateDelivery=None, - residentialDelivery=None, - insuranceType=None, - scheduledShipDate=None, - insideDelivery=None, - isSaturdayService=None, - dangerousGoodsType=None, - serviceId=None, - stackable=None, - From=None, - To=None, - COD=None, - Packages=None, - Payment=None, - Reference=None, - CustomsInvoice=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.saturdayPickupRequired = _cast(None, saturdayPickupRequired) - self.saturdayPickupRequired_nsprefix_ = None - self.homelandSecurity = _cast(None, homelandSecurity) - self.homelandSecurity_nsprefix_ = None - self.pierCharge = _cast(None, pierCharge) - self.pierCharge_nsprefix_ = None - self.exhibitionConventionSite = _cast(None, exhibitionConventionSite) - self.exhibitionConventionSite_nsprefix_ = None - self.militaryBaseDelivery = _cast(None, militaryBaseDelivery) - self.militaryBaseDelivery_nsprefix_ = None - self.customsIn_bondFreight = _cast(None, customsIn_bondFreight) - self.customsIn_bondFreight_nsprefix_ = None - self.limitedAccess = _cast(None, limitedAccess) - self.limitedAccess_nsprefix_ = None - self.excessLength = _cast(None, excessLength) - self.excessLength_nsprefix_ = None - self.tailgatePickup = _cast(None, tailgatePickup) - self.tailgatePickup_nsprefix_ = None - self.residentialPickup = _cast(None, residentialPickup) - self.residentialPickup_nsprefix_ = None - self.crossBorderFee = _cast(None, crossBorderFee) - self.crossBorderFee_nsprefix_ = None - self.notifyRecipient = _cast(None, notifyRecipient) - self.notifyRecipient_nsprefix_ = None - self.singleShipment = _cast(None, singleShipment) - self.singleShipment_nsprefix_ = None - self.tailgateDelivery = _cast(None, tailgateDelivery) - self.tailgateDelivery_nsprefix_ = None - self.residentialDelivery = _cast(None, residentialDelivery) - self.residentialDelivery_nsprefix_ = None - self.insuranceType = _cast(None, insuranceType) - self.insuranceType_nsprefix_ = None - self.scheduledShipDate = _cast(None, scheduledShipDate) - self.scheduledShipDate_nsprefix_ = None - self.insideDelivery = _cast(None, insideDelivery) - self.insideDelivery_nsprefix_ = None - self.isSaturdayService = _cast(None, isSaturdayService) - self.isSaturdayService_nsprefix_ = None - self.dangerousGoodsType = _cast(None, dangerousGoodsType) - self.dangerousGoodsType_nsprefix_ = None - self.serviceId = _cast(int, serviceId) - self.serviceId_nsprefix_ = None - self.stackable = _cast(None, stackable) - self.stackable_nsprefix_ = None - self.From = From - self.From_nsprefix_ = None - self.To = To - self.To_nsprefix_ = None - self.COD = COD - self.COD_nsprefix_ = None - self.Packages = Packages - self.Packages_nsprefix_ = None - self.Payment = Payment - self.Payment_nsprefix_ = None - if Reference is None: - self.Reference = [] - else: - self.Reference = Reference - self.Reference_nsprefix_ = None - self.CustomsInvoice = CustomsInvoice - self.CustomsInvoice_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, ShippingRequestType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ShippingRequestType.subclass: - return ShippingRequestType.subclass(*args_, **kwargs_) - else: - return ShippingRequestType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_From(self): - return self.From - - def set_From(self, From): - self.From = From - - def get_To(self): - return self.To - - def set_To(self, To): - self.To = To - - def get_COD(self): - return self.COD - - def set_COD(self, COD): - self.COD = COD - - def get_Packages(self): - return self.Packages - - def set_Packages(self, Packages): - self.Packages = Packages - - def get_Payment(self): - return self.Payment - - def set_Payment(self, Payment): - self.Payment = Payment - - def get_Reference(self): - return self.Reference - - def set_Reference(self, Reference): - self.Reference = Reference - - def add_Reference(self, value): - self.Reference.append(value) - - def insert_Reference_at(self, index, value): - self.Reference.insert(index, value) - - def replace_Reference_at(self, index, value): - self.Reference[index] = value - - def get_CustomsInvoice(self): - return self.CustomsInvoice - - def set_CustomsInvoice(self, CustomsInvoice): - self.CustomsInvoice = CustomsInvoice - - def get_saturdayPickupRequired(self): - return self.saturdayPickupRequired - - def set_saturdayPickupRequired(self, saturdayPickupRequired): - self.saturdayPickupRequired = saturdayPickupRequired - - def get_homelandSecurity(self): - return self.homelandSecurity - - def set_homelandSecurity(self, homelandSecurity): - self.homelandSecurity = homelandSecurity - - def get_pierCharge(self): - return self.pierCharge - - def set_pierCharge(self, pierCharge): - self.pierCharge = pierCharge - - def get_exhibitionConventionSite(self): - return self.exhibitionConventionSite - - def set_exhibitionConventionSite(self, exhibitionConventionSite): - self.exhibitionConventionSite = exhibitionConventionSite - - def get_militaryBaseDelivery(self): - return self.militaryBaseDelivery - - def set_militaryBaseDelivery(self, militaryBaseDelivery): - self.militaryBaseDelivery = militaryBaseDelivery - - def get_customsIn_bondFreight(self): - return self.customsIn_bondFreight - - def set_customsIn_bondFreight(self, customsIn_bondFreight): - self.customsIn_bondFreight = customsIn_bondFreight - - def get_limitedAccess(self): - return self.limitedAccess - - def set_limitedAccess(self, limitedAccess): - self.limitedAccess = limitedAccess - - def get_excessLength(self): - return self.excessLength - - def set_excessLength(self, excessLength): - self.excessLength = excessLength - - def get_tailgatePickup(self): - return self.tailgatePickup - - def set_tailgatePickup(self, tailgatePickup): - self.tailgatePickup = tailgatePickup - - def get_residentialPickup(self): - return self.residentialPickup - - def set_residentialPickup(self, residentialPickup): - self.residentialPickup = residentialPickup - - def get_crossBorderFee(self): - return self.crossBorderFee - - def set_crossBorderFee(self, crossBorderFee): - self.crossBorderFee = crossBorderFee - - def get_notifyRecipient(self): - return self.notifyRecipient - - def set_notifyRecipient(self, notifyRecipient): - self.notifyRecipient = notifyRecipient - - def get_singleShipment(self): - return self.singleShipment - - def set_singleShipment(self, singleShipment): - self.singleShipment = singleShipment - - def get_tailgateDelivery(self): - return self.tailgateDelivery - - def set_tailgateDelivery(self, tailgateDelivery): - self.tailgateDelivery = tailgateDelivery - - def get_residentialDelivery(self): - return self.residentialDelivery - - def set_residentialDelivery(self, residentialDelivery): - self.residentialDelivery = residentialDelivery - - def get_insuranceType(self): - return self.insuranceType - - def set_insuranceType(self, insuranceType): - self.insuranceType = insuranceType - - def get_scheduledShipDate(self): - return self.scheduledShipDate - - def set_scheduledShipDate(self, scheduledShipDate): - self.scheduledShipDate = scheduledShipDate - - def get_insideDelivery(self): - return self.insideDelivery - - def set_insideDelivery(self, insideDelivery): - self.insideDelivery = insideDelivery - - def get_isSaturdayService(self): - return self.isSaturdayService - - def set_isSaturdayService(self, isSaturdayService): - self.isSaturdayService = isSaturdayService - - def get_dangerousGoodsType(self): - return self.dangerousGoodsType - - def set_dangerousGoodsType(self, dangerousGoodsType): - self.dangerousGoodsType = dangerousGoodsType - - def get_serviceId(self): - return self.serviceId - - def set_serviceId(self, serviceId): - self.serviceId = serviceId - - def get_stackable(self): - return self.stackable - - def set_stackable(self, stackable): - self.stackable = stackable - - def _hasContent(self): - if ( - self.From is not None - or self.To is not None - or self.COD is not None - or self.Packages is not None - or self.Payment is not None - or self.Reference - or self.CustomsInvoice is not None - ): - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShippingRequestType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ShippingRequestType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ShippingRequestType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="ShippingRequestType", - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ShippingRequestType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ShippingRequestType", - ): - if ( - self.saturdayPickupRequired is not None - and "saturdayPickupRequired" not in already_processed - ): - already_processed.add("saturdayPickupRequired") - outfile.write( - " saturdayPickupRequired=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.saturdayPickupRequired), - input_name="saturdayPickupRequired", - ) - ), - ) - ) - if ( - self.homelandSecurity is not None - and "homelandSecurity" not in already_processed - ): - already_processed.add("homelandSecurity") - outfile.write( - " homelandSecurity=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.homelandSecurity), - input_name="homelandSecurity", - ) - ), - ) - ) - if self.pierCharge is not None and "pierCharge" not in already_processed: - already_processed.add("pierCharge") - outfile.write( - " pierCharge=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.pierCharge), input_name="pierCharge" - ) - ), - ) - ) - if ( - self.exhibitionConventionSite is not None - and "exhibitionConventionSite" not in already_processed - ): - already_processed.add("exhibitionConventionSite") - outfile.write( - " exhibitionConventionSite=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.exhibitionConventionSite), - input_name="exhibitionConventionSite", - ) - ), - ) - ) - if ( - self.militaryBaseDelivery is not None - and "militaryBaseDelivery" not in already_processed - ): - already_processed.add("militaryBaseDelivery") - outfile.write( - " militaryBaseDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.militaryBaseDelivery), - input_name="militaryBaseDelivery", - ) - ), - ) - ) - if ( - self.customsIn_bondFreight is not None - and "customsIn_bondFreight" not in already_processed - ): - already_processed.add("customsIn_bondFreight") - outfile.write( - " customsIn-bondFreight=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.customsIn_bondFreight), - input_name="customsIn-bondFreight", - ) - ), - ) - ) - if self.limitedAccess is not None and "limitedAccess" not in already_processed: - already_processed.add("limitedAccess") - outfile.write( - " limitedAccess=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.limitedAccess), input_name="limitedAccess" - ) - ), - ) - ) - if self.excessLength is not None and "excessLength" not in already_processed: - already_processed.add("excessLength") - outfile.write( - " excessLength=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.excessLength), input_name="excessLength" - ) - ), - ) - ) - if ( - self.tailgatePickup is not None - and "tailgatePickup" not in already_processed - ): - already_processed.add("tailgatePickup") - outfile.write( - " tailgatePickup=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgatePickup), - input_name="tailgatePickup", - ) - ), - ) - ) - if ( - self.residentialPickup is not None - and "residentialPickup" not in already_processed - ): - already_processed.add("residentialPickup") - outfile.write( - " residentialPickup=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residentialPickup), - input_name="residentialPickup", - ) - ), - ) - ) - if ( - self.crossBorderFee is not None - and "crossBorderFee" not in already_processed - ): - already_processed.add("crossBorderFee") - outfile.write( - " crossBorderFee=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.crossBorderFee), - input_name="crossBorderFee", - ) - ), - ) - ) - if ( - self.notifyRecipient is not None - and "notifyRecipient" not in already_processed - ): - already_processed.add("notifyRecipient") - outfile.write( - " notifyRecipient=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.notifyRecipient), - input_name="notifyRecipient", - ) - ), - ) - ) - if ( - self.singleShipment is not None - and "singleShipment" not in already_processed - ): - already_processed.add("singleShipment") - outfile.write( - " singleShipment=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.singleShipment), - input_name="singleShipment", - ) - ), - ) - ) - if ( - self.tailgateDelivery is not None - and "tailgateDelivery" not in already_processed - ): - already_processed.add("tailgateDelivery") - outfile.write( - " tailgateDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgateDelivery), - input_name="tailgateDelivery", - ) - ), - ) - ) - if ( - self.residentialDelivery is not None - and "residentialDelivery" not in already_processed - ): - already_processed.add("residentialDelivery") - outfile.write( - " residentialDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residentialDelivery), - input_name="residentialDelivery", - ) - ), - ) - ) - if self.insuranceType is not None and "insuranceType" not in already_processed: - already_processed.add("insuranceType") - outfile.write( - " insuranceType=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.insuranceType), input_name="insuranceType" - ) - ), - ) - ) - if ( - self.scheduledShipDate is not None - and "scheduledShipDate" not in already_processed - ): - already_processed.add("scheduledShipDate") - outfile.write( - " scheduledShipDate=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.scheduledShipDate), - input_name="scheduledShipDate", - ) - ), - ) - ) - if ( - self.insideDelivery is not None - and "insideDelivery" not in already_processed - ): - already_processed.add("insideDelivery") - outfile.write( - " insideDelivery=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.insideDelivery), - input_name="insideDelivery", - ) - ), - ) - ) - if ( - self.isSaturdayService is not None - and "isSaturdayService" not in already_processed - ): - already_processed.add("isSaturdayService") - outfile.write( - " isSaturdayService=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.isSaturdayService), - input_name="isSaturdayService", - ) - ), - ) - ) - if ( - self.dangerousGoodsType is not None - and "dangerousGoodsType" not in already_processed - ): - already_processed.add("dangerousGoodsType") - outfile.write( - " dangerousGoodsType=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.dangerousGoodsType), - input_name="dangerousGoodsType", - ) - ), - ) - ) - if self.serviceId is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - outfile.write( - ' serviceId="%s"' - % self.gds_format_integer(self.serviceId, input_name="serviceId") - ) - if self.stackable is not None and "stackable" not in already_processed: - already_processed.add("stackable") - outfile.write( - " stackable=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.stackable), input_name="stackable" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ShippingRequestType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.From is not None: - namespaceprefix_ = ( - self.From_nsprefix_ + ":" - if (UseCapturedNS_ and self.From_nsprefix_) - else "" - ) - self.From.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="From", - pretty_print=pretty_print, - ) - if self.To is not None: - namespaceprefix_ = ( - self.To_nsprefix_ + ":" - if (UseCapturedNS_ and self.To_nsprefix_) - else "" - ) - self.To.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="To", - pretty_print=pretty_print, - ) - if self.COD is not None: - namespaceprefix_ = ( - self.COD_nsprefix_ + ":" - if (UseCapturedNS_ and self.COD_nsprefix_) - else "" - ) - self.COD.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="COD", - pretty_print=pretty_print, - ) - if self.Packages is not None: - namespaceprefix_ = ( - self.Packages_nsprefix_ + ":" - if (UseCapturedNS_ and self.Packages_nsprefix_) - else "" - ) - self.Packages.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Packages", - pretty_print=pretty_print, - ) - if self.Payment is not None: - namespaceprefix_ = ( - self.Payment_nsprefix_ + ":" - if (UseCapturedNS_ and self.Payment_nsprefix_) - else "" - ) - self.Payment.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Payment", - pretty_print=pretty_print, - ) - for Reference_ in self.Reference: - namespaceprefix_ = ( - self.Reference_nsprefix_ + ":" - if (UseCapturedNS_ and self.Reference_nsprefix_) - else "" - ) - Reference_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Reference", - pretty_print=pretty_print, - ) - if self.CustomsInvoice is not None: - namespaceprefix_ = ( - self.CustomsInvoice_nsprefix_ + ":" - if (UseCapturedNS_ and self.CustomsInvoice_nsprefix_) - else "" - ) - self.CustomsInvoice.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="CustomsInvoice", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("saturdayPickupRequired", node) - if value is not None and "saturdayPickupRequired" not in already_processed: - already_processed.add("saturdayPickupRequired") - self.saturdayPickupRequired = value - value = find_attr_value_("homelandSecurity", node) - if value is not None and "homelandSecurity" not in already_processed: - already_processed.add("homelandSecurity") - self.homelandSecurity = value - value = find_attr_value_("pierCharge", node) - if value is not None and "pierCharge" not in already_processed: - already_processed.add("pierCharge") - self.pierCharge = value - value = find_attr_value_("exhibitionConventionSite", node) - if value is not None and "exhibitionConventionSite" not in already_processed: - already_processed.add("exhibitionConventionSite") - self.exhibitionConventionSite = value - value = find_attr_value_("militaryBaseDelivery", node) - if value is not None and "militaryBaseDelivery" not in already_processed: - already_processed.add("militaryBaseDelivery") - self.militaryBaseDelivery = value - value = find_attr_value_("customsIn-bondFreight", node) - if value is not None and "customsIn-bondFreight" not in already_processed: - already_processed.add("customsIn-bondFreight") - self.customsIn_bondFreight = value - value = find_attr_value_("limitedAccess", node) - if value is not None and "limitedAccess" not in already_processed: - already_processed.add("limitedAccess") - self.limitedAccess = value - value = find_attr_value_("excessLength", node) - if value is not None and "excessLength" not in already_processed: - already_processed.add("excessLength") - self.excessLength = value - value = find_attr_value_("tailgatePickup", node) - if value is not None and "tailgatePickup" not in already_processed: - already_processed.add("tailgatePickup") - self.tailgatePickup = value - value = find_attr_value_("residentialPickup", node) - if value is not None and "residentialPickup" not in already_processed: - already_processed.add("residentialPickup") - self.residentialPickup = value - value = find_attr_value_("crossBorderFee", node) - if value is not None and "crossBorderFee" not in already_processed: - already_processed.add("crossBorderFee") - self.crossBorderFee = value - value = find_attr_value_("notifyRecipient", node) - if value is not None and "notifyRecipient" not in already_processed: - already_processed.add("notifyRecipient") - self.notifyRecipient = value - value = find_attr_value_("singleShipment", node) - if value is not None and "singleShipment" not in already_processed: - already_processed.add("singleShipment") - self.singleShipment = value - value = find_attr_value_("tailgateDelivery", node) - if value is not None and "tailgateDelivery" not in already_processed: - already_processed.add("tailgateDelivery") - self.tailgateDelivery = value - value = find_attr_value_("residentialDelivery", node) - if value is not None and "residentialDelivery" not in already_processed: - already_processed.add("residentialDelivery") - self.residentialDelivery = value - value = find_attr_value_("insuranceType", node) - if value is not None and "insuranceType" not in already_processed: - already_processed.add("insuranceType") - self.insuranceType = value - value = find_attr_value_("scheduledShipDate", node) - if value is not None and "scheduledShipDate" not in already_processed: - already_processed.add("scheduledShipDate") - self.scheduledShipDate = value - value = find_attr_value_("insideDelivery", node) - if value is not None and "insideDelivery" not in already_processed: - already_processed.add("insideDelivery") - self.insideDelivery = value - value = find_attr_value_("isSaturdayService", node) - if value is not None and "isSaturdayService" not in already_processed: - already_processed.add("isSaturdayService") - self.isSaturdayService = value - value = find_attr_value_("dangerousGoodsType", node) - if value is not None and "dangerousGoodsType" not in already_processed: - already_processed.add("dangerousGoodsType") - self.dangerousGoodsType = value - value = find_attr_value_("serviceId", node) - if value is not None and "serviceId" not in already_processed: - already_processed.add("serviceId") - self.serviceId = self.gds_parse_integer(value, node, "serviceId") - value = find_attr_value_("stackable", node) - if value is not None and "stackable" not in already_processed: - already_processed.add("stackable") - self.stackable = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "From": - obj_ = FromType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.From = obj_ - obj_.original_tagname_ = "From" - elif nodeName_ == "To": - obj_ = ToType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.To = obj_ - obj_.original_tagname_ = "To" - elif nodeName_ == "COD": - obj_ = CODType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.COD = obj_ - obj_.original_tagname_ = "COD" - elif nodeName_ == "Packages": - obj_ = PackagesType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Packages = obj_ - obj_.original_tagname_ = "Packages" - elif nodeName_ == "Payment": - obj_ = PaymentType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Payment = obj_ - obj_.original_tagname_ = "Payment" - elif nodeName_ == "Reference": - obj_ = ReferenceType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Reference.append(obj_) - obj_.original_tagname_ = "Reference" - elif nodeName_ == "CustomsInvoice": - obj_ = CustomsInvoiceType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.CustomsInvoice = obj_ - obj_.original_tagname_ = "CustomsInvoice" - - -# end class ShippingRequestType - - -class FromType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - id=None, - company=None, - instructions=None, - email=None, - attention=None, - phone=None, - tailgateRequired=None, - residential=None, - address1=None, - address2=None, - city=None, - state=None, - country=None, - zip=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.company = _cast(None, company) - self.company_nsprefix_ = None - self.instructions = _cast(None, instructions) - self.instructions_nsprefix_ = None - self.email = _cast(None, email) - self.email_nsprefix_ = None - self.attention = _cast(None, attention) - self.attention_nsprefix_ = None - self.phone = _cast(None, phone) - self.phone_nsprefix_ = None - self.tailgateRequired = _cast(None, tailgateRequired) - self.tailgateRequired_nsprefix_ = None - self.residential = _cast(None, residential) - self.residential_nsprefix_ = None - self.address1 = _cast(None, address1) - self.address1_nsprefix_ = None - self.address2 = _cast(None, address2) - self.address2_nsprefix_ = None - self.city = _cast(None, city) - self.city_nsprefix_ = None - self.state = _cast(None, state) - self.state_nsprefix_ = None - self.country = _cast(None, country) - self.country_nsprefix_ = None - self.zip = _cast(None, zip) - self.zip_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, FromType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if FromType.subclass: - return FromType.subclass(*args_, **kwargs_) - else: - return FromType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_company(self): - return self.company - - def set_company(self, company): - self.company = company - - def get_instructions(self): - return self.instructions - - def set_instructions(self, instructions): - self.instructions = instructions - - def get_email(self): - return self.email - - def set_email(self, email): - self.email = email - - def get_attention(self): - return self.attention - - def set_attention(self, attention): - self.attention = attention - - def get_phone(self): - return self.phone - - def set_phone(self, phone): - self.phone = phone - - def get_tailgateRequired(self): - return self.tailgateRequired - - def set_tailgateRequired(self, tailgateRequired): - self.tailgateRequired = tailgateRequired - - def get_residential(self): - return self.residential - - def set_residential(self, residential): - self.residential = residential - - def get_address1(self): - return self.address1 - - def set_address1(self, address1): - self.address1 = address1 - - def get_address2(self): - return self.address2 - - def set_address2(self, address2): - self.address2 = address2 - - def get_city(self): - return self.city - - def set_city(self, city): - self.city = city - - def get_state(self): - return self.state - - def set_state(self, state): - self.state = state - - def get_country(self): - return self.country - - def set_country(self, country): - self.country = country - - def get_zip(self): - return self.zip - - def set_zip(self, zip): - self.zip = zip - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="FromType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("FromType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "FromType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="FromType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="FromType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="FromType" - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - if self.company is not None and "company" not in already_processed: - already_processed.add("company") - outfile.write( - " company=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.company), input_name="company" - ) - ), - ) - ) - if self.instructions is not None and "instructions" not in already_processed: - already_processed.add("instructions") - outfile.write( - " instructions=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.instructions), input_name="instructions" - ) - ), - ) - ) - if self.email is not None and "email" not in already_processed: - already_processed.add("email") - outfile.write( - " email=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.email), input_name="email" - ) - ), - ) - ) - if self.attention is not None and "attention" not in already_processed: - already_processed.add("attention") - outfile.write( - " attention=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.attention), input_name="attention" - ) - ), - ) - ) - if self.phone is not None and "phone" not in already_processed: - already_processed.add("phone") - outfile.write( - " phone=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.phone), input_name="phone" - ) - ), - ) - ) - if ( - self.tailgateRequired is not None - and "tailgateRequired" not in already_processed - ): - already_processed.add("tailgateRequired") - outfile.write( - " tailgateRequired=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgateRequired), - input_name="tailgateRequired", - ) - ), - ) - ) - if self.residential is not None and "residential" not in already_processed: - already_processed.add("residential") - outfile.write( - " residential=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residential), input_name="residential" - ) - ), - ) - ) - if self.address1 is not None and "address1" not in already_processed: - already_processed.add("address1") - outfile.write( - " address1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address1), input_name="address1" - ) - ), - ) - ) - if self.address2 is not None and "address2" not in already_processed: - already_processed.add("address2") - outfile.write( - " address2=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address2), input_name="address2" - ) - ), - ) - ) - if self.city is not None and "city" not in already_processed: - already_processed.add("city") - outfile.write( - " city=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.city), input_name="city" - ) - ), - ) - ) - if self.state is not None and "state" not in already_processed: - already_processed.add("state") - outfile.write( - " state=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.state), input_name="state" - ) - ), - ) - ) - if self.country is not None and "country" not in already_processed: - already_processed.add("country") - outfile.write( - " country=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.country), input_name="country" - ) - ), - ) - ) - if self.zip is not None and "zip" not in already_processed: - already_processed.add("zip") - outfile.write( - " zip=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.zip), input_name="zip") - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="FromType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - value = find_attr_value_("company", node) - if value is not None and "company" not in already_processed: - already_processed.add("company") - self.company = value - value = find_attr_value_("instructions", node) - if value is not None and "instructions" not in already_processed: - already_processed.add("instructions") - self.instructions = value - value = find_attr_value_("email", node) - if value is not None and "email" not in already_processed: - already_processed.add("email") - self.email = value - value = find_attr_value_("attention", node) - if value is not None and "attention" not in already_processed: - already_processed.add("attention") - self.attention = value - value = find_attr_value_("phone", node) - if value is not None and "phone" not in already_processed: - already_processed.add("phone") - self.phone = value - value = find_attr_value_("tailgateRequired", node) - if value is not None and "tailgateRequired" not in already_processed: - already_processed.add("tailgateRequired") - self.tailgateRequired = value - value = find_attr_value_("residential", node) - if value is not None and "residential" not in already_processed: - already_processed.add("residential") - self.residential = value - value = find_attr_value_("address1", node) - if value is not None and "address1" not in already_processed: - already_processed.add("address1") - self.address1 = value - value = find_attr_value_("address2", node) - if value is not None and "address2" not in already_processed: - already_processed.add("address2") - self.address2 = value - value = find_attr_value_("city", node) - if value is not None and "city" not in already_processed: - already_processed.add("city") - self.city = value - value = find_attr_value_("state", node) - if value is not None and "state" not in already_processed: - already_processed.add("state") - self.state = value - value = find_attr_value_("country", node) - if value is not None and "country" not in already_processed: - already_processed.add("country") - self.country = value - value = find_attr_value_("zip", node) - if value is not None and "zip" not in already_processed: - already_processed.add("zip") - self.zip = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class FromType - - -class ToType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - id=None, - company=None, - notifyRecipient=None, - instructions=None, - email=None, - attention=None, - phone=None, - tailgateRequired=None, - residential=None, - address1=None, - address2=None, - city=None, - state=None, - zip=None, - country=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.id = _cast(None, id) - self.id_nsprefix_ = None - self.company = _cast(None, company) - self.company_nsprefix_ = None - self.notifyRecipient = _cast(None, notifyRecipient) - self.notifyRecipient_nsprefix_ = None - self.instructions = _cast(None, instructions) - self.instructions_nsprefix_ = None - self.email = _cast(None, email) - self.email_nsprefix_ = None - self.attention = _cast(None, attention) - self.attention_nsprefix_ = None - self.phone = _cast(None, phone) - self.phone_nsprefix_ = None - self.tailgateRequired = _cast(None, tailgateRequired) - self.tailgateRequired_nsprefix_ = None - self.residential = _cast(None, residential) - self.residential_nsprefix_ = None - self.address1 = _cast(None, address1) - self.address1_nsprefix_ = None - self.address2 = _cast(None, address2) - self.address2_nsprefix_ = None - self.city = _cast(None, city) - self.city_nsprefix_ = None - self.state = _cast(None, state) - self.state_nsprefix_ = None - self.zip = _cast(None, zip) - self.zip_nsprefix_ = None - self.country = _cast(None, country) - self.country_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ToType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ToType.subclass: - return ToType.subclass(*args_, **kwargs_) - else: - return ToType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_id(self): - return self.id - - def set_id(self, id): - self.id = id - - def get_company(self): - return self.company - - def set_company(self, company): - self.company = company - - def get_notifyRecipient(self): - return self.notifyRecipient - - def set_notifyRecipient(self, notifyRecipient): - self.notifyRecipient = notifyRecipient - - def get_instructions(self): - return self.instructions - - def set_instructions(self, instructions): - self.instructions = instructions - - def get_email(self): - return self.email - - def set_email(self, email): - self.email = email - - def get_attention(self): - return self.attention - - def set_attention(self, attention): - self.attention = attention - - def get_phone(self): - return self.phone - - def set_phone(self, phone): - self.phone = phone - - def get_tailgateRequired(self): - return self.tailgateRequired - - def set_tailgateRequired(self, tailgateRequired): - self.tailgateRequired = tailgateRequired - - def get_residential(self): - return self.residential - - def set_residential(self, residential): - self.residential = residential - - def get_address1(self): - return self.address1 - - def set_address1(self, address1): - self.address1 = address1 - - def get_address2(self): - return self.address2 - - def set_address2(self, address2): - self.address2 = address2 - - def get_city(self): - return self.city - - def set_city(self, city): - self.city = city - - def get_state(self): - return self.state - - def set_state(self, state): - self.state = state - - def get_zip(self): - return self.zip - - def set_zip(self, zip): - self.zip = zip - - def get_country(self): - return self.country - - def set_country(self, country): - self.country = country - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ToType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ToType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ToType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ToType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ToType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="ToType" - ): - if self.id is not None and "id" not in already_processed: - already_processed.add("id") - outfile.write( - " id=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.id), input_name="id") - ), - ) - ) - if self.company is not None and "company" not in already_processed: - already_processed.add("company") - outfile.write( - " company=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.company), input_name="company" - ) - ), - ) - ) - if ( - self.notifyRecipient is not None - and "notifyRecipient" not in already_processed - ): - already_processed.add("notifyRecipient") - outfile.write( - " notifyRecipient=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.notifyRecipient), - input_name="notifyRecipient", - ) - ), - ) - ) - if self.instructions is not None and "instructions" not in already_processed: - already_processed.add("instructions") - outfile.write( - " instructions=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.instructions), input_name="instructions" - ) - ), - ) - ) - if self.email is not None and "email" not in already_processed: - already_processed.add("email") - outfile.write( - " email=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.email), input_name="email" - ) - ), - ) - ) - if self.attention is not None and "attention" not in already_processed: - already_processed.add("attention") - outfile.write( - " attention=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.attention), input_name="attention" - ) - ), - ) - ) - if self.phone is not None and "phone" not in already_processed: - already_processed.add("phone") - outfile.write( - " phone=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.phone), input_name="phone" - ) - ), - ) - ) - if ( - self.tailgateRequired is not None - and "tailgateRequired" not in already_processed - ): - already_processed.add("tailgateRequired") - outfile.write( - " tailgateRequired=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.tailgateRequired), - input_name="tailgateRequired", - ) - ), - ) - ) - if self.residential is not None and "residential" not in already_processed: - already_processed.add("residential") - outfile.write( - " residential=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.residential), input_name="residential" - ) - ), - ) - ) - if self.address1 is not None and "address1" not in already_processed: - already_processed.add("address1") - outfile.write( - " address1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address1), input_name="address1" - ) - ), - ) - ) - if self.address2 is not None and "address2" not in already_processed: - already_processed.add("address2") - outfile.write( - " address2=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address2), input_name="address2" - ) - ), - ) - ) - if self.city is not None and "city" not in already_processed: - already_processed.add("city") - outfile.write( - " city=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.city), input_name="city" - ) - ), - ) - ) - if self.state is not None and "state" not in already_processed: - already_processed.add("state") - outfile.write( - " state=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.state), input_name="state" - ) - ), - ) - ) - if self.zip is not None and "zip" not in already_processed: - already_processed.add("zip") - outfile.write( - " zip=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.zip), input_name="zip") - ), - ) - ) - if self.country is not None and "country" not in already_processed: - already_processed.add("country") - outfile.write( - " country=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.country), input_name="country" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ToType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("id", node) - if value is not None and "id" not in already_processed: - already_processed.add("id") - self.id = value - value = find_attr_value_("company", node) - if value is not None and "company" not in already_processed: - already_processed.add("company") - self.company = value - value = find_attr_value_("notifyRecipient", node) - if value is not None and "notifyRecipient" not in already_processed: - already_processed.add("notifyRecipient") - self.notifyRecipient = value - value = find_attr_value_("instructions", node) - if value is not None and "instructions" not in already_processed: - already_processed.add("instructions") - self.instructions = value - value = find_attr_value_("email", node) - if value is not None and "email" not in already_processed: - already_processed.add("email") - self.email = value - value = find_attr_value_("attention", node) - if value is not None and "attention" not in already_processed: - already_processed.add("attention") - self.attention = value - value = find_attr_value_("phone", node) - if value is not None and "phone" not in already_processed: - already_processed.add("phone") - self.phone = value - value = find_attr_value_("tailgateRequired", node) - if value is not None and "tailgateRequired" not in already_processed: - already_processed.add("tailgateRequired") - self.tailgateRequired = value - value = find_attr_value_("residential", node) - if value is not None and "residential" not in already_processed: - already_processed.add("residential") - self.residential = value - value = find_attr_value_("address1", node) - if value is not None and "address1" not in already_processed: - already_processed.add("address1") - self.address1 = value - value = find_attr_value_("address2", node) - if value is not None and "address2" not in already_processed: - already_processed.add("address2") - self.address2 = value - value = find_attr_value_("city", node) - if value is not None and "city" not in already_processed: - already_processed.add("city") - self.city = value - value = find_attr_value_("state", node) - if value is not None and "state" not in already_processed: - already_processed.add("state") - self.state = value - value = find_attr_value_("zip", node) - if value is not None and "zip" not in already_processed: - already_processed.add("zip") - self.zip = value - value = find_attr_value_("country", node) - if value is not None and "country" not in already_processed: - already_processed.add("country") - self.country = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ToType - - -class CODType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, paymentType=None, CODReturnAddress=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.paymentType = _cast(None, paymentType) - self.paymentType_nsprefix_ = None - self.CODReturnAddress = CODReturnAddress - self.CODReturnAddress_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, CODType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CODType.subclass: - return CODType.subclass(*args_, **kwargs_) - else: - return CODType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_CODReturnAddress(self): - return self.CODReturnAddress - - def set_CODReturnAddress(self, CODReturnAddress): - self.CODReturnAddress = CODReturnAddress - - def get_paymentType(self): - return self.paymentType - - def set_paymentType(self, paymentType): - self.paymentType = paymentType - - def _hasContent(self): - if self.CODReturnAddress is not None: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CODType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CODType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="CODType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CODType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="CODType" - ): - if self.paymentType is not None and "paymentType" not in already_processed: - already_processed.add("paymentType") - outfile.write( - " paymentType=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.paymentType), input_name="paymentType" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.CODReturnAddress is not None: - namespaceprefix_ = ( - self.CODReturnAddress_nsprefix_ + ":" - if (UseCapturedNS_ and self.CODReturnAddress_nsprefix_) - else "" - ) - self.CODReturnAddress.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="CODReturnAddress", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("paymentType", node) - if value is not None and "paymentType" not in already_processed: - already_processed.add("paymentType") - self.paymentType = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "CODReturnAddress": - obj_ = CODReturnAddressType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.CODReturnAddress = obj_ - obj_.original_tagname_ = "CODReturnAddress" - - -# end class CODType - - -class CODReturnAddressType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - codCompany=None, - codName=None, - codAddress1=None, - codCity=None, - codStateCode=None, - codZip=None, - codCountry=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.codCompany = _cast(None, codCompany) - self.codCompany_nsprefix_ = None - self.codName = _cast(None, codName) - self.codName_nsprefix_ = None - self.codAddress1 = _cast(None, codAddress1) - self.codAddress1_nsprefix_ = None - self.codCity = _cast(None, codCity) - self.codCity_nsprefix_ = None - self.codStateCode = _cast(None, codStateCode) - self.codStateCode_nsprefix_ = None - self.codZip = _cast(None, codZip) - self.codZip_nsprefix_ = None - self.codCountry = _cast(None, codCountry) - self.codCountry_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, CODReturnAddressType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CODReturnAddressType.subclass: - return CODReturnAddressType.subclass(*args_, **kwargs_) - else: - return CODReturnAddressType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_codCompany(self): - return self.codCompany - - def set_codCompany(self, codCompany): - self.codCompany = codCompany - - def get_codName(self): - return self.codName - - def set_codName(self, codName): - self.codName = codName - - def get_codAddress1(self): - return self.codAddress1 - - def set_codAddress1(self, codAddress1): - self.codAddress1 = codAddress1 - - def get_codCity(self): - return self.codCity - - def set_codCity(self, codCity): - self.codCity = codCity - - def get_codStateCode(self): - return self.codStateCode - - def set_codStateCode(self, codStateCode): - self.codStateCode = codStateCode - - def get_codZip(self): - return self.codZip - - def set_codZip(self, codZip): - self.codZip = codZip - - def get_codCountry(self): - return self.codCountry - - def set_codCountry(self, codCountry): - self.codCountry = codCountry - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODReturnAddressType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CODReturnAddressType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CODReturnAddressType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="CODReturnAddressType", - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CODReturnAddressType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="CODReturnAddressType", - ): - if self.codCompany is not None and "codCompany" not in already_processed: - already_processed.add("codCompany") - outfile.write( - " codCompany=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codCompany), input_name="codCompany" - ) - ), - ) - ) - if self.codName is not None and "codName" not in already_processed: - already_processed.add("codName") - outfile.write( - " codName=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codName), input_name="codName" - ) - ), - ) - ) - if self.codAddress1 is not None and "codAddress1" not in already_processed: - already_processed.add("codAddress1") - outfile.write( - " codAddress1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codAddress1), input_name="codAddress1" - ) - ), - ) - ) - if self.codCity is not None and "codCity" not in already_processed: - already_processed.add("codCity") - outfile.write( - " codCity=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codCity), input_name="codCity" - ) - ), - ) - ) - if self.codStateCode is not None and "codStateCode" not in already_processed: - already_processed.add("codStateCode") - outfile.write( - " codStateCode=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codStateCode), input_name="codStateCode" - ) - ), - ) - ) - if self.codZip is not None and "codZip" not in already_processed: - already_processed.add("codZip") - outfile.write( - " codZip=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codZip), input_name="codZip" - ) - ), - ) - ) - if self.codCountry is not None and "codCountry" not in already_processed: - already_processed.add("codCountry") - outfile.write( - " codCountry=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.codCountry), input_name="codCountry" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CODReturnAddressType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("codCompany", node) - if value is not None and "codCompany" not in already_processed: - already_processed.add("codCompany") - self.codCompany = value - value = find_attr_value_("codName", node) - if value is not None and "codName" not in already_processed: - already_processed.add("codName") - self.codName = value - value = find_attr_value_("codAddress1", node) - if value is not None and "codAddress1" not in already_processed: - already_processed.add("codAddress1") - self.codAddress1 = value - value = find_attr_value_("codCity", node) - if value is not None and "codCity" not in already_processed: - already_processed.add("codCity") - self.codCity = value - value = find_attr_value_("codStateCode", node) - if value is not None and "codStateCode" not in already_processed: - already_processed.add("codStateCode") - self.codStateCode = value - value = find_attr_value_("codZip", node) - if value is not None and "codZip" not in already_processed: - already_processed.add("codZip") - self.codZip = value - value = find_attr_value_("codCountry", node) - if value is not None and "codCountry" not in already_processed: - already_processed.add("codCountry") - self.codCountry = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class CODReturnAddressType - - -class PackagesType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, type_=None, Package=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.type_ = _cast(None, type_) - self.type__nsprefix_ = None - if Package is None: - self.Package = [] - else: - self.Package = Package - self.Package_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PackagesType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PackagesType.subclass: - return PackagesType.subclass(*args_, **kwargs_) - else: - return PackagesType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_Package(self): - return self.Package - - def set_Package(self, Package): - self.Package = Package - - def add_Package(self, value): - self.Package.append(value) - - def insert_Package_at(self, index, value): - self.Package.insert(index, value) - - def replace_Package_at(self, index, value): - self.Package[index] = value - - def get_type(self): - return self.type_ - - def set_type(self, type_): - self.type_ = type_ - - def _hasContent(self): - if self.Package: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackagesType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PackagesType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PackagesType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PackagesType" - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PackagesType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="PackagesType", - ): - if self.type_ is not None and "type_" not in already_processed: - already_processed.add("type_") - outfile.write( - " type=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.type_), input_name="type" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackagesType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - for Package_ in self.Package: - namespaceprefix_ = ( - self.Package_nsprefix_ + ":" - if (UseCapturedNS_ and self.Package_nsprefix_) - else "" - ) - Package_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Package", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("type", node) - if value is not None and "type" not in already_processed: - already_processed.add("type") - self.type_ = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "Package": - obj_ = PackageType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Package.append(obj_) - obj_.original_tagname_ = "Package" - - -# end class PackagesType - - -class PackageType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - length=None, - width=None, - height=None, - weight=None, - type_=None, - freightClass=None, - nmfcCode=None, - insuranceAmount=None, - codAmount=None, - description=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.length = _cast(int, length) - self.length_nsprefix_ = None - self.width = _cast(int, width) - self.width_nsprefix_ = None - self.height = _cast(int, height) - self.height_nsprefix_ = None - self.weight = _cast(int, weight) - self.weight_nsprefix_ = None - self.type_ = _cast(None, type_) - self.type__nsprefix_ = None - self.freightClass = _cast(int, freightClass) - self.freightClass_nsprefix_ = None - self.nmfcCode = _cast(None, nmfcCode) - self.nmfcCode_nsprefix_ = None - self.insuranceAmount = _cast(float, insuranceAmount) - self.insuranceAmount_nsprefix_ = None - self.codAmount = _cast(float, codAmount) - self.codAmount_nsprefix_ = None - self.description = _cast(None, description) - self.description_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PackageType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PackageType.subclass: - return PackageType.subclass(*args_, **kwargs_) - else: - return PackageType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_length(self): - return self.length - - def set_length(self, length): - self.length = length - - def get_width(self): - return self.width - - def set_width(self, width): - self.width = width - - def get_height(self): - return self.height - - def set_height(self, height): - self.height = height - - def get_weight(self): - return self.weight - - def set_weight(self, weight): - self.weight = weight - - def get_type(self): - return self.type_ - - def set_type(self, type_): - self.type_ = type_ - - def get_freightClass(self): - return self.freightClass - - def set_freightClass(self, freightClass): - self.freightClass = freightClass - - def get_nmfcCode(self): - return self.nmfcCode - - def set_nmfcCode(self, nmfcCode): - self.nmfcCode = nmfcCode - - def get_insuranceAmount(self): - return self.insuranceAmount - - def set_insuranceAmount(self, insuranceAmount): - self.insuranceAmount = insuranceAmount - - def get_codAmount(self): - return self.codAmount - - def set_codAmount(self, codAmount): - self.codAmount = codAmount - - def get_description(self): - return self.description - - def set_description(self, description): - self.description = description - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackageType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PackageType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PackageType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PackageType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PackageType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="PackageType", - ): - if self.length is not None and "length" not in already_processed: - already_processed.add("length") - outfile.write( - ' length="%s"' - % self.gds_format_integer(self.length, input_name="length") - ) - if self.width is not None and "width" not in already_processed: - already_processed.add("width") - outfile.write( - ' width="%s"' % self.gds_format_integer(self.width, input_name="width") - ) - if self.height is not None and "height" not in already_processed: - already_processed.add("height") - outfile.write( - ' height="%s"' - % self.gds_format_integer(self.height, input_name="height") - ) - if self.weight is not None and "weight" not in already_processed: - already_processed.add("weight") - outfile.write( - ' weight="%s"' - % self.gds_format_integer(self.weight, input_name="weight") - ) - if self.type_ is not None and "type_" not in already_processed: - already_processed.add("type_") - outfile.write( - " type=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.type_), input_name="type" - ) - ), - ) - ) - if self.freightClass is not None and "freightClass" not in already_processed: - already_processed.add("freightClass") - outfile.write( - ' freightClass="%s"' - % self.gds_format_integer(self.freightClass, input_name="freightClass") - ) - if self.nmfcCode is not None and "nmfcCode" not in already_processed: - already_processed.add("nmfcCode") - outfile.write( - " nmfcCode=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.nmfcCode), input_name="nmfcCode" - ) - ), - ) - ) - if ( - self.insuranceAmount is not None - and "insuranceAmount" not in already_processed - ): - already_processed.add("insuranceAmount") - outfile.write( - ' insuranceAmount="%s"' - % self.gds_format_float( - self.insuranceAmount, input_name="insuranceAmount" - ) - ) - if self.codAmount is not None and "codAmount" not in already_processed: - already_processed.add("codAmount") - outfile.write( - ' codAmount="%s"' - % self.gds_format_float(self.codAmount, input_name="codAmount") - ) - if self.description is not None and "description" not in already_processed: - already_processed.add("description") - outfile.write( - " description=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.description), input_name="description" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PackageType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("length", node) - if value is not None and "length" not in already_processed: - already_processed.add("length") - self.length = self.gds_parse_integer(value, node, "length") - value = find_attr_value_("width", node) - if value is not None and "width" not in already_processed: - already_processed.add("width") - self.width = self.gds_parse_integer(value, node, "width") - value = find_attr_value_("height", node) - if value is not None and "height" not in already_processed: - already_processed.add("height") - self.height = self.gds_parse_integer(value, node, "height") - value = find_attr_value_("weight", node) - if value is not None and "weight" not in already_processed: - already_processed.add("weight") - self.weight = self.gds_parse_integer(value, node, "weight") - value = find_attr_value_("type", node) - if value is not None and "type" not in already_processed: - already_processed.add("type") - self.type_ = value - value = find_attr_value_("freightClass", node) - if value is not None and "freightClass" not in already_processed: - already_processed.add("freightClass") - self.freightClass = self.gds_parse_integer(value, node, "freightClass") - value = find_attr_value_("nmfcCode", node) - if value is not None and "nmfcCode" not in already_processed: - already_processed.add("nmfcCode") - self.nmfcCode = value - value = find_attr_value_("insuranceAmount", node) - if value is not None and "insuranceAmount" not in already_processed: - already_processed.add("insuranceAmount") - value = self.gds_parse_float(value, node, "insuranceAmount") - self.insuranceAmount = value - value = find_attr_value_("codAmount", node) - if value is not None and "codAmount" not in already_processed: - already_processed.add("codAmount") - value = self.gds_parse_float(value, node, "codAmount") - self.codAmount = value - value = find_attr_value_("description", node) - if value is not None and "description" not in already_processed: - already_processed.add("description") - self.description = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class PackageType - - -class PaymentType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__(self, type_=None, valueOf_=None, gds_collector_=None, **kwargs_): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.type_ = _cast(None, type_) - self.type__nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, PaymentType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if PaymentType.subclass: - return PaymentType.subclass(*args_, **kwargs_) - else: - return PaymentType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_type(self): - return self.type_ - - def set_type(self, type_): - self.type_ = type_ - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PaymentType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("PaymentType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "PaymentType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="PaymentType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="PaymentType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="PaymentType", - ): - if self.type_ is not None and "type_" not in already_processed: - already_processed.add("type_") - outfile.write( - " type=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.type_), input_name="type" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="PaymentType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("type", node) - if value is not None and "type" not in already_processed: - already_processed.add("type") - self.type_ = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class PaymentType - - -class ReferenceType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, name=None, code=None, valueOf_=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.name = _cast(None, name) - self.name_nsprefix_ = None - self.code = _cast(None, code) - self.code_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ReferenceType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ReferenceType.subclass: - return ReferenceType.subclass(*args_, **kwargs_) - else: - return ReferenceType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_name(self): - return self.name - - def set_name(self, name): - self.name = name - - def get_code(self): - return self.code - - def set_code(self, code): - self.code = code - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ReferenceType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ReferenceType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ReferenceType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ReferenceType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ReferenceType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ReferenceType", - ): - if self.name is not None and "name" not in already_processed: - already_processed.add("name") - outfile.write( - " name=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.name), input_name="name" - ) - ), - ) - ) - if self.code is not None and "code" not in already_processed: - already_processed.add("code") - outfile.write( - " code=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.code), input_name="code" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ReferenceType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("name", node) - if value is not None and "name" not in already_processed: - already_processed.add("name") - self.name = value - value = find_attr_value_("code", node) - if value is not None and "code" not in already_processed: - already_processed.add("code") - self.code = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ReferenceType - - -class CustomsInvoiceType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, BillTo=None, Contact=None, Item=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.BillTo = BillTo - self.BillTo_nsprefix_ = None - self.Contact = Contact - self.Contact_nsprefix_ = None - if Item is None: - self.Item = [] - else: - self.Item = Item - self.Item_nsprefix_ = None - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_( - CurrentSubclassModule_, CustomsInvoiceType - ) - if subclass is not None: - return subclass(*args_, **kwargs_) - if CustomsInvoiceType.subclass: - return CustomsInvoiceType.subclass(*args_, **kwargs_) - else: - return CustomsInvoiceType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_BillTo(self): - return self.BillTo - - def set_BillTo(self, BillTo): - self.BillTo = BillTo - - def get_Contact(self): - return self.Contact - - def set_Contact(self, Contact): - self.Contact = Contact - - def get_Item(self): - return self.Item - - def set_Item(self, Item): - self.Item = Item - - def add_Item(self, value): - self.Item.append(value) - - def insert_Item_at(self, index, value): - self.Item.insert(index, value) - - def replace_Item_at(self, index, value): - self.Item[index] = value - - def _hasContent(self): - if self.BillTo is not None or self.Contact is not None or self.Item: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CustomsInvoiceType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("CustomsInvoiceType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "CustomsInvoiceType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, - level, - already_processed, - namespaceprefix_, - name_="CustomsInvoiceType", - ) - if self._hasContent(): - outfile.write(">%s" % (eol_,)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="CustomsInvoiceType", - pretty_print=pretty_print, - ) - showIndent(outfile, level, pretty_print) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="CustomsInvoiceType", - ): - pass - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="CustomsInvoiceType", - fromsubclass_=False, - pretty_print=True, - ): - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.BillTo is not None: - namespaceprefix_ = ( - self.BillTo_nsprefix_ + ":" - if (UseCapturedNS_ and self.BillTo_nsprefix_) - else "" - ) - self.BillTo.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="BillTo", - pretty_print=pretty_print, - ) - if self.Contact is not None: - namespaceprefix_ = ( - self.Contact_nsprefix_ + ":" - if (UseCapturedNS_ and self.Contact_nsprefix_) - else "" - ) - self.Contact.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Contact", - pretty_print=pretty_print, - ) - for Item_ in self.Item: - namespaceprefix_ = ( - self.Item_nsprefix_ + ":" - if (UseCapturedNS_ and self.Item_nsprefix_) - else "" - ) - Item_.export( - outfile, - level, - namespaceprefix_, - namespacedef_="", - name_="Item", - pretty_print=pretty_print, - ) - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - pass - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - if nodeName_ == "BillTo": - obj_ = BillToType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.BillTo = obj_ - obj_.original_tagname_ = "BillTo" - elif nodeName_ == "Contact": - obj_ = ContactType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Contact = obj_ - obj_.original_tagname_ = "Contact" - elif nodeName_ == "Item": - obj_ = ItemType.factory(parent_object_=self) - obj_.build(child_, gds_collector_=gds_collector_) - self.Item.append(obj_) - obj_.original_tagname_ = "Item" - - -# end class CustomsInvoiceType - - -class BillToType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - company=None, - name=None, - address1=None, - city=None, - state=None, - zip=None, - country=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.company = _cast(None, company) - self.company_nsprefix_ = None - self.name = _cast(None, name) - self.name_nsprefix_ = None - self.address1 = _cast(None, address1) - self.address1_nsprefix_ = None - self.city = _cast(None, city) - self.city_nsprefix_ = None - self.state = _cast(None, state) - self.state_nsprefix_ = None - self.zip = _cast(None, zip) - self.zip_nsprefix_ = None - self.country = _cast(None, country) - self.country_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, BillToType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if BillToType.subclass: - return BillToType.subclass(*args_, **kwargs_) - else: - return BillToType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_company(self): - return self.company - - def set_company(self, company): - self.company = company - - def get_name(self): - return self.name - - def set_name(self, name): - self.name = name - - def get_address1(self): - return self.address1 - - def set_address1(self, address1): - self.address1 = address1 - - def get_city(self): - return self.city - - def set_city(self, city): - self.city = city - - def get_state(self): - return self.state - - def set_state(self, state): - self.state = state - - def get_zip(self): - return self.zip - - def set_zip(self, zip): - self.zip = zip - - def get_country(self): - return self.country - - def set_country(self, country): - self.country = country - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="BillToType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("BillToType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "BillToType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="BillToType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="BillToType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="BillToType" - ): - if self.company is not None and "company" not in already_processed: - already_processed.add("company") - outfile.write( - " company=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.company), input_name="company" - ) - ), - ) - ) - if self.name is not None and "name" not in already_processed: - already_processed.add("name") - outfile.write( - " name=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.name), input_name="name" - ) - ), - ) - ) - if self.address1 is not None and "address1" not in already_processed: - already_processed.add("address1") - outfile.write( - " address1=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.address1), input_name="address1" - ) - ), - ) - ) - if self.city is not None and "city" not in already_processed: - already_processed.add("city") - outfile.write( - " city=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.city), input_name="city" - ) - ), - ) - ) - if self.state is not None and "state" not in already_processed: - already_processed.add("state") - outfile.write( - " state=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.state), input_name="state" - ) - ), - ) - ) - if self.zip is not None and "zip" not in already_processed: - already_processed.add("zip") - outfile.write( - " zip=%s" - % ( - self.gds_encode( - self.gds_format_string(quote_attrib(self.zip), input_name="zip") - ), - ) - ) - if self.country is not None and "country" not in already_processed: - already_processed.add("country") - outfile.write( - " country=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.country), input_name="country" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="BillToType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("company", node) - if value is not None and "company" not in already_processed: - already_processed.add("company") - self.company = value - value = find_attr_value_("name", node) - if value is not None and "name" not in already_processed: - already_processed.add("name") - self.name = value - value = find_attr_value_("address1", node) - if value is not None and "address1" not in already_processed: - already_processed.add("address1") - self.address1 = value - value = find_attr_value_("city", node) - if value is not None and "city" not in already_processed: - already_processed.add("city") - self.city = value - value = find_attr_value_("state", node) - if value is not None and "state" not in already_processed: - already_processed.add("state") - self.state = value - value = find_attr_value_("zip", node) - if value is not None and "zip" not in already_processed: - already_processed.add("zip") - self.zip = value - value = find_attr_value_("country", node) - if value is not None and "country" not in already_processed: - already_processed.add("country") - self.country = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class BillToType - - -class ContactType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, name=None, phone=None, valueOf_=None, gds_collector_=None, **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.name = _cast(None, name) - self.name_nsprefix_ = None - self.phone = _cast(None, phone) - self.phone_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ContactType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ContactType.subclass: - return ContactType.subclass(*args_, **kwargs_) - else: - return ContactType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_name(self): - return self.name - - def set_name(self, name): - self.name = name - - def get_phone(self): - return self.phone - - def set_phone(self, phone): - self.phone = phone - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ContactType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ContactType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ContactType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ContactType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ContactType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, - outfile, - level, - already_processed, - namespaceprefix_="", - name_="ContactType", - ): - if self.name is not None and "name" not in already_processed: - already_processed.add("name") - outfile.write( - " name=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.name), input_name="name" - ) - ), - ) - ) - if self.phone is not None and "phone" not in already_processed: - already_processed.add("phone") - outfile.write( - " phone=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.phone), input_name="phone" - ) - ), - ) - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ContactType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("name", node) - if value is not None and "name" not in already_processed: - already_processed.add("name") - self.name = value - value = find_attr_value_("phone", node) - if value is not None and "phone" not in already_processed: - already_processed.add("phone") - self.phone = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ContactType - - -class ItemType(GeneratedsSuper): - __hash__ = GeneratedsSuper.__hash__ - subclass = None - superclass = None - - def __init__( - self, - code=None, - description=None, - originCountry=None, - quantity=None, - unitPrice=None, - valueOf_=None, - gds_collector_=None, - **kwargs_ - ): - self.gds_collector_ = gds_collector_ - self.gds_elementtree_node_ = None - self.original_tagname_ = None - self.parent_object_ = kwargs_.get("parent_object_") - self.ns_prefix_ = None - self.code = _cast(None, code) - self.code_nsprefix_ = None - self.description = _cast(None, description) - self.description_nsprefix_ = None - self.originCountry = _cast(None, originCountry) - self.originCountry_nsprefix_ = None - self.quantity = _cast(int, quantity) - self.quantity_nsprefix_ = None - self.unitPrice = _cast(float, unitPrice) - self.unitPrice_nsprefix_ = None - self.valueOf_ = valueOf_ - - def factory(*args_, **kwargs_): - if CurrentSubclassModule_ is not None: - subclass = getSubclassFromModule_(CurrentSubclassModule_, ItemType) - if subclass is not None: - return subclass(*args_, **kwargs_) - if ItemType.subclass: - return ItemType.subclass(*args_, **kwargs_) - else: - return ItemType(*args_, **kwargs_) - - factory = staticmethod(factory) - - def get_ns_prefix_(self): - return self.ns_prefix_ - - def set_ns_prefix_(self, ns_prefix): - self.ns_prefix_ = ns_prefix - - def get_code(self): - return self.code - - def set_code(self, code): - self.code = code - - def get_description(self): - return self.description - - def set_description(self, description): - self.description = description - - def get_originCountry(self): - return self.originCountry - - def set_originCountry(self, originCountry): - self.originCountry = originCountry - - def get_quantity(self): - return self.quantity - - def set_quantity(self, quantity): - self.quantity = quantity - - def get_unitPrice(self): - return self.unitPrice - - def set_unitPrice(self, unitPrice): - self.unitPrice = unitPrice - - def get_valueOf_(self): - return self.valueOf_ - - def set_valueOf_(self, valueOf_): - self.valueOf_ = valueOf_ - - def _hasContent(self): - if 1 if type(self.valueOf_) in [int, float] else self.valueOf_: - return True - else: - return False - - def export( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ItemType", - pretty_print=True, - ): - imported_ns_def_ = GenerateDSNamespaceDefs_.get("ItemType") - if imported_ns_def_ is not None: - namespacedef_ = imported_ns_def_ - if pretty_print: - eol_ = "\n" - else: - eol_ = "" - if self.original_tagname_ is not None and name_ == "ItemType": - name_ = self.original_tagname_ - if UseCapturedNS_ and self.ns_prefix_: - namespaceprefix_ = self.ns_prefix_ + ":" - showIndent(outfile, level, pretty_print) - outfile.write( - "<%s%s%s" - % ( - namespaceprefix_, - name_, - namespacedef_ and " " + namespacedef_ or "", - ) - ) - already_processed = set() - self._exportAttributes( - outfile, level, already_processed, namespaceprefix_, name_="ItemType" - ) - if self._hasContent(): - outfile.write(">") - outfile.write(self.convert_unicode(self.valueOf_)) - self._exportChildren( - outfile, - level + 1, - namespaceprefix_, - namespacedef_, - name_="ItemType", - pretty_print=pretty_print, - ) - outfile.write("%s" % (namespaceprefix_, name_, eol_)) - else: - outfile.write("/>%s" % (eol_,)) - - def _exportAttributes( - self, outfile, level, already_processed, namespaceprefix_="", name_="ItemType" - ): - if self.code is not None and "code" not in already_processed: - already_processed.add("code") - outfile.write( - " code=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.code), input_name="code" - ) - ), - ) - ) - if self.description is not None and "description" not in already_processed: - already_processed.add("description") - outfile.write( - " description=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.description), input_name="description" - ) - ), - ) - ) - if self.originCountry is not None and "originCountry" not in already_processed: - already_processed.add("originCountry") - outfile.write( - " originCountry=%s" - % ( - self.gds_encode( - self.gds_format_string( - quote_attrib(self.originCountry), input_name="originCountry" - ) - ), - ) - ) - if self.quantity is not None and "quantity" not in already_processed: - already_processed.add("quantity") - outfile.write( - ' quantity="%s"' - % self.gds_format_integer(self.quantity, input_name="quantity") - ) - if self.unitPrice is not None and "unitPrice" not in already_processed: - already_processed.add("unitPrice") - outfile.write( - ' unitPrice="%s"' - % self.gds_format_float(self.unitPrice, input_name="unitPrice") - ) - - def _exportChildren( - self, - outfile, - level, - namespaceprefix_="", - namespacedef_="", - name_="ItemType", - fromsubclass_=False, - pretty_print=True, - ): - pass - - def build(self, node, gds_collector_=None): - self.gds_collector_ = gds_collector_ - if SaveElementTreeNode: - self.gds_elementtree_node_ = node - already_processed = set() - self.ns_prefix_ = node.prefix - self._buildAttributes(node, node.attrib, already_processed) - self.valueOf_ = get_all_text_(node) - for child in node: - nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] - self._buildChildren(child, node, nodeName_, gds_collector_=gds_collector_) - return self - - def _buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_("code", node) - if value is not None and "code" not in already_processed: - already_processed.add("code") - self.code = value - value = find_attr_value_("description", node) - if value is not None and "description" not in already_processed: - already_processed.add("description") - self.description = value - value = find_attr_value_("originCountry", node) - if value is not None and "originCountry" not in already_processed: - already_processed.add("originCountry") - self.originCountry = value - value = find_attr_value_("quantity", node) - if value is not None and "quantity" not in already_processed: - already_processed.add("quantity") - self.quantity = self.gds_parse_integer(value, node, "quantity") - value = find_attr_value_("unitPrice", node) - if value is not None and "unitPrice" not in already_processed: - already_processed.add("unitPrice") - value = self.gds_parse_float(value, node, "unitPrice") - self.unitPrice = value - - def _buildChildren( - self, child_, node, nodeName_, fromsubclass_=False, gds_collector_=None - ): - pass - - -# end class ItemType - - -GDSClassesMapping = {} - - -USAGE_TEXT = """ -Usage: python .py [ -s ] -""" - - -def usage(): - print(USAGE_TEXT) - sys.exit(1) - - -def get_root_tag(node): - tag = Tag_pattern_.match(node.tag).groups()[-1] - prefix_tag = TagNamePrefix + tag - rootClass = GDSClassesMapping.get(prefix_tag) - if rootClass is None: - rootClass = globals().get(prefix_tag) - return tag, rootClass - - -def get_required_ns_prefix_defs(rootNode): - """Get all name space prefix definitions required in this XML doc. - Return a dictionary of definitions and a char string of definitions. - """ - nsmap = { - prefix: uri - for node in rootNode.iter() - for (prefix, uri) in node.nsmap.items() - if prefix is not None - } - namespacedefs = " ".join( - ['xmlns:{}="{}"'.format(prefix, uri) for prefix, uri in nsmap.items()] - ) - return nsmap, namespacedefs - - -def parse(inFileName, silence=False, print_warnings=True): - global CapturedNsmap_ - gds_collector = GdsCollector_() - parser = None - doc = parsexml_(inFileName, parser) - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - CapturedNsmap_, namespacedefs = get_required_ns_prefix_defs(rootNode) - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export( - sys.stdout, 0, name_=rootTag, namespacedef_=namespacedefs, pretty_print=True - ) - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseEtree( - inFileName, - silence=False, - print_warnings=True, - mapping=None, - reverse_mapping=None, - nsmap=None, -): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if mapping is None: - mapping = {} - if reverse_mapping is None: - reverse_mapping = {} - rootElement = rootObj.to_etree( - None, - name_=rootTag, - mapping_=mapping, - reverse_mapping_=reverse_mapping, - nsmap_=nsmap, - ) - reverse_node_mapping = rootObj.gds_reverse_node_mapping(mapping) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - content = etree_.tostring( - rootElement, pretty_print=True, xml_declaration=True, encoding="utf-8" - ) - sys.stdout.write(str(content)) - sys.stdout.write("\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj, rootElement, mapping, reverse_node_mapping - - -def parseString(inString, silence=False, print_warnings=True): - """Parse a string, create the object tree, and export it. - - Arguments: - - inString -- A string. This XML fragment should not start - with an XML declaration containing an encoding. - - silence -- A boolean. If False, export the object. - Returns -- The root object in the tree. - """ - parser = None - rootNode = parsexmlstring_(inString, parser) - gds_collector = GdsCollector_() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - if not SaveElementTreeNode: - rootNode = None - if not silence: - sys.stdout.write('\n') - rootObj.export(sys.stdout, 0, name_=rootTag, namespacedef_="") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def parseLiteral(inFileName, silence=False, print_warnings=True): - parser = None - doc = parsexml_(inFileName, parser) - gds_collector = GdsCollector_() - rootNode = doc.getroot() - rootTag, rootClass = get_root_tag(rootNode) - if rootClass is None: - rootTag = "Freightcom" - rootClass = Freightcom - rootObj = rootClass.factory() - rootObj.build(rootNode, gds_collector_=gds_collector) - # Enable Python to collect the space used by the DOM. - if not SaveElementTreeNode: - doc = None - rootNode = None - if not silence: - sys.stdout.write("#from shipping_request import *\n\n") - sys.stdout.write("import shipping_request as model_\n\n") - sys.stdout.write("rootObj = model_.rootClass(\n") - rootObj.exportLiteral(sys.stdout, 0, name_=rootTag) - sys.stdout.write(")\n") - if print_warnings and len(gds_collector.get_messages()) > 0: - separator = ("-" * 50) + "\n" - sys.stderr.write(separator) - sys.stderr.write( - "----- Warnings -- count: {} -----\n".format( - len(gds_collector.get_messages()), - ) - ) - gds_collector.write_messages(sys.stderr) - sys.stderr.write(separator) - return rootObj - - -def main(): - args = sys.argv[1:] - if len(args) == 1: - parse(args[0]) - else: - usage() - - -if __name__ == "__main__": - # import pdb; pdb.set_trace() - main() - -RenameMappings_ = {} - -# -# Mapping of namespaces to types defined in them -# and the file in which each is defined. -# simpleTypes are marked "ST" and complexTypes "CT". -NamespaceToDefMappings_ = {"http://www.freightcom.net/XMLSchema": []} - -__all__ = [ - "BillToType", - "CODReturnAddressType", - "CODType", - "ContactType", - "CustomsInvoiceType", - "Freightcom", - "FromType", - "ItemType", - "PackageType", - "PackagesType", - "PaymentType", - "ReferenceType", - "ShippingRequestType", - "ToType", -] + +@s(auto_attribs=True) +class CustomsInvoiceDetailsType: + tax_recipient: Optional[TaxRecipientType] = JStruct[TaxRecipientType] + products: List[ProductType] = JList[ProductType] + + +@s(auto_attribs=True) +class CustomsInvoiceType: + source: Optional[str] = None + broker: Optional[BrokerType] = JStruct[BrokerType] + details: Optional[CustomsInvoiceDetailsType] = JStruct[CustomsInvoiceDetailsType] + + +@s(auto_attribs=True) +class ReadyType: + hour: Optional[int] = None + minute: Optional[int] = None + + +@s(auto_attribs=True) +class DestinationType: + name: Optional[str] = None + address: Optional[AddressType] = JStruct[AddressType] + residential: Optional[bool] = None + tailgate_required: Optional[bool] = None + instructions: Optional[str] = None + contact_name: Optional[str] = None + phone_number: Optional[NumberType] = JStruct[NumberType] + email_addresses: List[str] = [] + receives_email_updates: Optional[bool] = None + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + signature_requirement: Optional[str] = None + + +@s(auto_attribs=True) +class DateType: + year: Optional[int] = None + month: Optional[int] = None + day: Optional[int] = None + + +@s(auto_attribs=True) +class InsuranceType: + type: Optional[str] = None + total_cost: Optional[TotalCostType] = JStruct[TotalCostType] + + +@s(auto_attribs=True) +class CourierpakMeasurementsType: + weight: Optional[WeightType] = JStruct[WeightType] + + +@s(auto_attribs=True) +class CourierpakType: + measurements: Optional[CourierpakMeasurementsType] = JStruct[CourierpakMeasurementsType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class DangerousGoodsDetailsType: + packaging_group: Optional[str] = None + goods_class: Optional[str] = None + description: Optional[str] = None + united_nations_number: Optional[str] = None + emergency_contact_name: Optional[str] = None + emergency_contact_phone_number: Optional[NumberType] = JStruct[NumberType] + + +@s(auto_attribs=True) +class CuboidType: + unit: Optional[str] = None + l: Optional[int] = None + w: Optional[int] = None + h: Optional[int] = None + + +@s(auto_attribs=True) +class PackageMeasurementsType: + weight: Optional[WeightType] = JStruct[WeightType] + cuboid: Optional[CuboidType] = JStruct[CuboidType] + + +@s(auto_attribs=True) +class PackageType: + measurements: Optional[PackageMeasurementsType] = JStruct[PackageMeasurementsType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class InBondDetailsType: + type: Optional[str] = None + name: Optional[str] = None + address: Optional[str] = None + contact_method: Optional[str] = None + contact_email_address: Optional[str] = None + contact_phone_number: Optional[NumberType] = JStruct[NumberType] + + +@s(auto_attribs=True) +class PalletServiceDetailsType: + limited_access_delivery_type: Optional[str] = None + limited_access_delivery_other_name: Optional[str] = None + in_bond: Optional[bool] = None + in_bond_details: Optional[InBondDetailsType] = JStruct[InBondDetailsType] + appointment_delivery: Optional[bool] = None + protect_from_freeze: Optional[bool] = None + threshold_pickup: Optional[bool] = None + threshold_delivery: Optional[bool] = None + + +@s(auto_attribs=True) +class PalletType: + measurements: Optional[PackageMeasurementsType] = JStruct[PackageMeasurementsType] + description: Optional[str] = None + freight_class: Optional[str] = None + nmfc: Optional[str] = None + contents_type: Optional[str] = None + num_pieces: Optional[int] = None + + +@s(auto_attribs=True) +class PackagingPropertiesType: + pallet_type: Optional[str] = None + has_stackable_pallets: Optional[bool] = None + dangerous_goods: Optional[str] = None + dangerous_goods_details: Optional[DangerousGoodsDetailsType] = JStruct[DangerousGoodsDetailsType] + pallets: List[PalletType] = JList[PalletType] + packages: List[PackageType] = JList[PackageType] + courierpaks: List[CourierpakType] = JList[CourierpakType] + includes_return_label: Optional[bool] = None + special_handling_required: Optional[bool] = None + has_dangerous_goods: Optional[bool] = None + pallet_service_details: Optional[PalletServiceDetailsType] = JStruct[PalletServiceDetailsType] + + +@s(auto_attribs=True) +class ShippingRequestDetailsType: + origin: Optional[DestinationType] = JStruct[DestinationType] + destination: Optional[DestinationType] = JStruct[DestinationType] + expected_ship_date: Optional[DateType] = JStruct[DateType] + packaging_type: Optional[str] = None + packaging_properties: Optional[PackagingPropertiesType] = JStruct[PackagingPropertiesType] + insurance: Optional[InsuranceType] = JStruct[InsuranceType] + reference_codes: List[str] = [] + + +@s(auto_attribs=True) +class DispatchDetailsType: + date: Optional[DateType] = JStruct[DateType] + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + + +@s(auto_attribs=True) +class PickupDetailsType: + pre_scheduled_pickup: Optional[bool] = None + date: Optional[DateType] = JStruct[DateType] + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + pickup_location: Optional[str] = None + contact_name: Optional[str] = None + contact_phone_number: Optional[NumberType] = JStruct[NumberType] + + +@s(auto_attribs=True) +class ShippingRequestType: + unique_id: Optional[str] = None + payment_method_id: Optional[str] = None + service_id: Optional[str] = None + details: Optional[ShippingRequestDetailsType] = JStruct[ShippingRequestDetailsType] + customs_invoice: Optional[CustomsInvoiceType] = JStruct[CustomsInvoiceType] + pickup_details: Optional[PickupDetailsType] = JStruct[PickupDetailsType] + dispatch_details: Optional[DispatchDetailsType] = JStruct[DispatchDetailsType] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_response.py b/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_response.py new file mode 100644 index 0000000000..3f0b5613ac --- /dev/null +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/shipping_response.py @@ -0,0 +1,224 @@ +from attr import s +from typing import Optional, List +from jstruct import JStruct, JList + + +@s(auto_attribs=True) +class AddressType: + address_line_1: Optional[str] = None + address_line_2: Optional[str] = None + unit_number: Optional[str] = None + city: Optional[str] = None + region: Optional[str] = None + country: Optional[str] = None + postal_code: Optional[str] = None + + +@s(auto_attribs=True) +class PhoneNumberType: + number: Optional[str] = None + extension: Optional[int] = None + + +@s(auto_attribs=True) +class ReadyType: + hour: Optional[int] = None + minute: Optional[int] = None + + +@s(auto_attribs=True) +class DestinationType: + name: Optional[str] = None + address: Optional[AddressType] = JStruct[AddressType] + residential: Optional[bool] = None + tailgate_required: Optional[bool] = None + instructions: Optional[str] = None + contact_name: Optional[str] = None + phone_number: Optional[PhoneNumberType] = JStruct[PhoneNumberType] + email_addresses: List[str] = [] + receives_email_updates: Optional[bool] = None + ready_at: Optional[ReadyType] = JStruct[ReadyType] + ready_until: Optional[ReadyType] = JStruct[ReadyType] + signature_requirement: Optional[str] = None + + +@s(auto_attribs=True) +class ExpectedShipDateType: + year: Optional[int] = None + month: Optional[int] = None + day: Optional[int] = None + + +@s(auto_attribs=True) +class BaseType: + currency: Optional[str] = None + value: Optional[int] = None + + +@s(auto_attribs=True) +class InsuranceType: + type: Optional[str] = None + total_cost: Optional[BaseType] = JStruct[BaseType] + + +@s(auto_attribs=True) +class WeightType: + unit: Optional[str] = None + value: Optional[float] = None + + +@s(auto_attribs=True) +class CourierpakMeasurementsType: + weight: Optional[WeightType] = JStruct[WeightType] + + +@s(auto_attribs=True) +class CourierpakType: + measurements: Optional[CourierpakMeasurementsType] = JStruct[CourierpakMeasurementsType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class DangerousGoodsDetailsType: + packaging_group: Optional[str] = None + goods_class: Optional[str] = None + description: Optional[str] = None + united_nations_number: Optional[str] = None + emergency_contact_name: Optional[str] = None + emergency_contact_phone_number: Optional[PhoneNumberType] = JStruct[PhoneNumberType] + + +@s(auto_attribs=True) +class CuboidType: + unit: Optional[str] = None + l: Optional[int] = None + w: Optional[int] = None + h: Optional[int] = None + + +@s(auto_attribs=True) +class PackageMeasurementsType: + weight: Optional[WeightType] = JStruct[WeightType] + cuboid: Optional[CuboidType] = JStruct[CuboidType] + + +@s(auto_attribs=True) +class PackageType: + measurements: Optional[PackageMeasurementsType] = JStruct[PackageMeasurementsType] + description: Optional[str] = None + + +@s(auto_attribs=True) +class InBondDetailsType: + type: Optional[str] = None + name: Optional[str] = None + address: Optional[str] = None + contact_method: Optional[str] = None + contact_email_address: Optional[str] = None + contact_phone_number: Optional[PhoneNumberType] = JStruct[PhoneNumberType] + + +@s(auto_attribs=True) +class PalletServiceDetailsType: + limited_access_delivery_type: Optional[str] = None + limited_access_delivery_other_name: Optional[str] = None + in_bond: Optional[bool] = None + in_bond_details: Optional[InBondDetailsType] = JStruct[InBondDetailsType] + appointment_delivery: Optional[bool] = None + protect_from_freeze: Optional[bool] = None + threshold_pickup: Optional[bool] = None + threshold_delivery: Optional[bool] = None + + +@s(auto_attribs=True) +class PalletType: + measurements: Optional[PackageMeasurementsType] = JStruct[PackageMeasurementsType] + description: Optional[str] = None + freight_class: Optional[str] = None + nmfc: Optional[str] = None + contents_type: Optional[str] = None + num_pieces: Optional[int] = None + + +@s(auto_attribs=True) +class PackagingPropertiesType: + pallet_type: Optional[str] = None + has_stackable_pallets: Optional[bool] = None + dangerous_goods: Optional[str] = None + dangerous_goods_details: Optional[DangerousGoodsDetailsType] = JStruct[DangerousGoodsDetailsType] + pallets: List[PalletType] = JList[PalletType] + packages: List[PackageType] = JList[PackageType] + courierpaks: List[CourierpakType] = JList[CourierpakType] + includes_return_label: Optional[bool] = None + special_handling_required: Optional[bool] = None + has_dangerous_goods: Optional[bool] = None + pallet_service_details: Optional[PalletServiceDetailsType] = JStruct[PalletServiceDetailsType] + + +@s(auto_attribs=True) +class DetailsType: + origin: Optional[DestinationType] = JStruct[DestinationType] + destination: Optional[DestinationType] = JStruct[DestinationType] + expected_ship_date: Optional[ExpectedShipDateType] = JStruct[ExpectedShipDateType] + packaging_type: Optional[str] = None + packaging_properties: Optional[PackagingPropertiesType] = JStruct[PackagingPropertiesType] + insurance: Optional[InsuranceType] = JStruct[InsuranceType] + reference_codes: List[str] = [] + + +@s(auto_attribs=True) +class LabelType: + size: Optional[str] = None + format: Optional[str] = None + url: Optional[str] = None + padded: Optional[bool] = None + + +@s(auto_attribs=True) +class SurchargeType: + type: Optional[str] = None + amount: Optional[BaseType] = JStruct[BaseType] + + +@s(auto_attribs=True) +class RateType: + carrier_name: Optional[str] = None + service_name: Optional[str] = None + service_id: Optional[str] = None + valid_until: Optional[ExpectedShipDateType] = JStruct[ExpectedShipDateType] + total: Optional[BaseType] = JStruct[BaseType] + base: Optional[BaseType] = JStruct[BaseType] + surcharges: List[SurchargeType] = JList[SurchargeType] + taxes: List[SurchargeType] = JList[SurchargeType] + transit_time_days: Optional[int] = None + transit_time_not_available: Optional[bool] = None + + +@s(auto_attribs=True) +class TransportDataType: + pass + + +@s(auto_attribs=True) +class ShipmentType: + id: Optional[str] = None + unique_id: Optional[str] = None + state: Optional[str] = None + transaction_number: Optional[str] = None + primary_tracking_number: Optional[str] = None + tracking_numbers: List[str] = [] + tracking_url: Optional[str] = None + return_tracking_number: Optional[str] = None + bol_number: Optional[str] = None + pickup_confirmation_number: Optional[str] = None + details: Optional[DetailsType] = JStruct[DetailsType] + transport_data: Optional[TransportDataType] = JStruct[TransportDataType] + labels: List[LabelType] = JList[LabelType] + customs_invoice_url: Optional[str] = None + rate: Optional[RateType] = JStruct[RateType] + order_source: Optional[str] = None + + +@s(auto_attribs=True) +class ShippingResponseType: + shipment: Optional[ShipmentType] = JStruct[ShipmentType] diff --git a/modules/connectors/freightcom/karrio/schemas/freightcom/tracking_response.py b/modules/connectors/freightcom/karrio/schemas/freightcom/tracking_response.py new file mode 100644 index 0000000000..f1fceca3e7 --- /dev/null +++ b/modules/connectors/freightcom/karrio/schemas/freightcom/tracking_response.py @@ -0,0 +1,23 @@ +from attr import s +from typing import Optional, List +from jstruct import JStruct, JList + + +@s(auto_attribs=True) +class WhereType: + city: Optional[str] = None + region: Optional[str] = None + country: Optional[str] = None + + +@s(auto_attribs=True) +class EventType: + type: Optional[str] = None + when: Optional[str] = None + where: Optional[WhereType] = JStruct[WhereType] + message: Optional[str] = None + + +@s(auto_attribs=True) +class TrackingResponseType: + events: List[EventType] = JList[EventType] diff --git a/modules/connectors/freightcom/schemas/error_response.json b/modules/connectors/freightcom/schemas/error_response.json index 1f295a22e9..0959a23996 100644 --- a/modules/connectors/freightcom/schemas/error_response.json +++ b/modules/connectors/freightcom/schemas/error_response.json @@ -1,6 +1,4 @@ { - "message": "bad or missing data", - "data": { - "details.destination.signature_requirement": "invalid" - } +"message": "string", + "data": {"services":"invalid-syntax"} } diff --git a/modules/connectors/freightcom/schemas/pickup_request.json b/modules/connectors/freightcom/schemas/pickup_request.json new file mode 100644 index 0000000000..7c5b184cc5 --- /dev/null +++ b/modules/connectors/freightcom/schemas/pickup_request.json @@ -0,0 +1,39 @@ +{ + "pickup_details": { + "pre_scheduled_pickup": true, + "date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + }, + "pickup_location": "string", + "contact_name": "string", + "contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "dispatch_details": { + "date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + } + } +} diff --git a/modules/connectors/freightcom/schemas/shipping_request.json b/modules/connectors/freightcom/schemas/shipping_request.json new file mode 100644 index 0000000000..15a543f41e --- /dev/null +++ b/modules/connectors/freightcom/schemas/shipping_request.json @@ -0,0 +1,267 @@ +{ + "unique_id": "string", + "payment_method_id": "string", + "service_id": "string", + "details": { + "origin": { + "name": "Philip J Fry", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "residential": true, + "tailgate_required": true, + "instructions": "string", + "contact_name": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "email_addresses": [ + "user@example.com" + ], + "receives_email_updates": true + }, + "destination": { + "name": "Philip J Fry", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "residential": true, + "tailgate_required": true, + "instructions": "string", + "contact_name": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "email_addresses": [ + "user@example.com" + ], + "receives_email_updates": true, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + }, + "signature_requirement": "not-required" + }, + "expected_ship_date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "packaging_type": "pallet", + "packaging_properties": { + "pallet_type": "ltl", + "has_stackable_pallets": true, + "dangerous_goods": "limited-quantity", + "dangerous_goods_details": { + "packaging_group": "string", + "goods_class": "string", + "description": "string", + "united_nations_number": "string", + "emergency_contact_name": "string", + "emergency_contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "pallets": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + }, + "cuboid": { + "unit": "ft", + "l": 5, + "w": 5, + "h": 5 + } + }, + "description": "string", + "freight_class": "string", + "nmfc": "string", + "contents_type": "string", + "num_pieces": 0 + } + ], + "packages": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + }, + "cuboid": { + "unit": "ft", + "l": 5, + "w": 5, + "h": 5 + } + }, + "description": "string" + } + ], + "courierpaks": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + } + }, + "description": "string" + } + ], + "includes_return_label": false, + "special_handling_required": false, + "has_dangerous_goods": false, + "pallet_service_details": { + "limited_access_delivery_type": "construction-site", + "limited_access_delivery_other_name": "string", + "in_bond": true, + "in_bond_details": { + "type": "immediate-exportation", + "name": "string", + "address": "string", + "contact_method": "email-address", + "contact_email_address": "string", + "contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "appointment_delivery": true, + "protect_from_freeze": true, + "threshold_pickup": true, + "threshold_delivery": true + } + }, + "insurance": { + "type": "internal", + "total_cost": { + "currency": "CAD", + "value": "4250" + } + }, + "reference_codes": [ + "string" + ] + }, + "customs_invoice": { + "source": "details", + "broker": { + "use_carrier": true, + "name": "string", + "account_number": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "fax_number": { + "number": "5554447777", + "extension": "123" + }, + "email_address": "string", + "usmca_number": "string", + "fda_number": "string" + }, + "details": { + "tax_recipient": { + "type": "shipper", + "shipper_tax_identifier": "string", + "receiver_tax_identifier": "string", + "third_party_tax_identifier": "string", + "other_tax_identifier": "string", + "name": "string", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "reason_for_export": "gift", + "additional_remarks": "string", + "comments": "string" + }, + "products": [ + { + "product_name": "string", + "weight": { + "unit": "lb", + "value": 2.95 + }, + "hs_code": "string", + "country_of_origin": "CA", + "num_units": 1, + "unit_price": { + "currency": "CAD", + "value": "4250" + }, + "description": "string" + } + ] + } + }, + "pickup_details": { + "pre_scheduled_pickup": true, + "date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + }, + "pickup_location": "string", + "contact_name": "string", + "contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "dispatch_details": { + "date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + } + } +} diff --git a/modules/connectors/freightcom/schemas/shipping_response.json b/modules/connectors/freightcom/schemas/shipping_response.json new file mode 100644 index 0000000000..7a32f87abb --- /dev/null +++ b/modules/connectors/freightcom/schemas/shipping_response.json @@ -0,0 +1,228 @@ +{ + "shipment": { + "id": "string", + "unique_id": "string", + "state": "draft", + "transaction_number": "string", + "primary_tracking_number": "string", + "tracking_numbers": [ + "string" + ], + "tracking_url": "string", + "return_tracking_number": "string", + "bol_number": "string", + "pickup_confirmation_number": "string", + "details": { + "origin": { + "name": "Philip J Fry", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "residential": true, + "tailgate_required": true, + "instructions": "string", + "contact_name": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "email_addresses": [ + "user@example.com" + ], + "receives_email_updates": true + }, + "destination": { + "name": "Philip J Fry", + "address": { + "address_line_1": "200 University Avenue West", + "address_line_2": "string", + "unit_number": "42a", + "city": "Waterloo", + "region": "ON", + "country": "CA", + "postal_code": "string" + }, + "residential": true, + "tailgate_required": true, + "instructions": "string", + "contact_name": "string", + "phone_number": { + "number": "5554447777", + "extension": "123" + }, + "email_addresses": [ + "user@example.com" + ], + "receives_email_updates": true, + "ready_at": { + "hour": 15, + "minute": 6 + }, + "ready_until": { + "hour": 15, + "minute": 6 + }, + "signature_requirement": "not-required" + }, + "expected_ship_date": { + "year": 2006, + "month": 6, + "day": 7 + }, + "packaging_type": "pallet", + "packaging_properties": { + "pallet_type": "ltl", + "has_stackable_pallets": true, + "dangerous_goods": "limited-quantity", + "dangerous_goods_details": { + "packaging_group": "string", + "goods_class": "string", + "description": "string", + "united_nations_number": "string", + "emergency_contact_name": "string", + "emergency_contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "pallets": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + }, + "cuboid": { + "unit": "ft", + "l": 5, + "w": 5, + "h": 5 + } + }, + "description": "string", + "freight_class": "string", + "nmfc": "string", + "contents_type": "string", + "num_pieces": 0 + } + ], + "packages": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + }, + "cuboid": { + "unit": "ft", + "l": 5, + "w": 5, + "h": 5 + } + }, + "description": "string" + } + ], + "courierpaks": [ + { + "measurements": { + "weight": { + "unit": "lb", + "value": 2.95 + } + }, + "description": "string" + } + ], + "includes_return_label": false, + "special_handling_required": false, + "has_dangerous_goods": false, + "pallet_service_details": { + "limited_access_delivery_type": "construction-site", + "limited_access_delivery_other_name": "string", + "in_bond": true, + "in_bond_details": { + "type": "immediate-exportation", + "name": "string", + "address": "string", + "contact_method": "email-address", + "contact_email_address": "string", + "contact_phone_number": { + "number": "5554447777", + "extension": "123" + } + }, + "appointment_delivery": true, + "protect_from_freeze": true, + "threshold_pickup": true, + "threshold_delivery": true + } + }, + "insurance": { + "type": "internal", + "total_cost": { + "currency": "CAD", + "value": "4250" + } + }, + "reference_codes": [ + "string" + ] + }, + "transport_data": {}, + "labels": [ + { + "size": "letter", + "format": "pdf", + "url": "string", + "padded": true + } + ], + "customs_invoice_url": "string", + "rate": { + "carrier_name": "string", + "service_name": "string", + "service_id": "string", + "valid_until": { + "year": 2006, + "month": 6, + "day": 7 + }, + "total": { + "currency": "CAD", + "value": "4250" + }, + "base": { + "currency": "CAD", + "value": "4250" + }, + "surcharges": [ + { + "type": "fuel", + "amount": { + "currency": "CAD", + "value": "4250" + } + } + ], + "taxes": [ + { + "type": "fuel", + "amount": { + "currency": "CAD", + "value": "4250" + } + } + ], + "transit_time_days": 5, + "transit_time_not_available": true + }, + "order_source": "string" + } +} diff --git a/modules/connectors/freightcom/schemas/tracking_response.json b/modules/connectors/freightcom/schemas/tracking_response.json new file mode 100644 index 0000000000..b0310d62f0 --- /dev/null +++ b/modules/connectors/freightcom/schemas/tracking_response.json @@ -0,0 +1,14 @@ +{ + "events": [ + { + "type": "label-created", + "when": "string", + "where": { + "city": "string", + "region": "string", + "country": "string" + }, + "message": "string" + } + ] +} From 714a749e78f8b00d6e12c03ab0e794a90b7cd2d6 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 10 Feb 2025 16:46:46 -0500 Subject: [PATCH 06/14] Remove username and password from Freightcom settings. This migration removes the `username` and `password` fields from Freightcom settings across models, fixtures, and settings definitions. The changes streamline authentication to rely solely on `api_key`. Relevant tests and configurations have been updated accordingly. --- .../karrio/mappers/freightcom/settings.py | 2 -- .../freightcom/tests/freightcom/fixture.py | 2 -- .../providers/extension/models/freightcom.py | 2 -- ...ve_freightcomsettings_password_and_more.py | 21 +++++++++++++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py index ebdd584997..9aae43f710 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py @@ -8,8 +8,6 @@ class Settings(BaseSettings): """Freightcom connection settings.""" - username: str - password: str api_key: str id: str = None diff --git a/modules/connectors/freightcom/tests/freightcom/fixture.py b/modules/connectors/freightcom/tests/freightcom/fixture.py index 69c1b18140..6cc6de05a6 100644 --- a/modules/connectors/freightcom/tests/freightcom/fixture.py +++ b/modules/connectors/freightcom/tests/freightcom/fixture.py @@ -2,8 +2,6 @@ gateway = karrio.gateway["freightcom"].create( dict( - username="username", - password="password", api_key="api_key", ) ) diff --git a/modules/core/karrio/server/providers/extension/models/freightcom.py b/modules/core/karrio/server/providers/extension/models/freightcom.py index 6b056b0e09..2a499af189 100644 --- a/modules/core/karrio/server/providers/extension/models/freightcom.py +++ b/modules/core/karrio/server/providers/extension/models/freightcom.py @@ -10,8 +10,6 @@ class Meta: verbose_name = "Freightcom Settings" verbose_name_plural = "Freightcom Settings" - username = models.CharField(max_length=200) - password = models.CharField(max_length=200) api_key = models.CharField(max_length=200, null=True) @property diff --git a/modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py b/modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py new file mode 100644 index 0000000000..a1b0b79eaa --- /dev/null +++ b/modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.16 on 2025-02-10 21:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("providers", "0081_freightcomsettings_api_key"), + ] + + operations = [ + migrations.RemoveField( + model_name="freightcomsettings", + name="password", + ), + migrations.RemoveField( + model_name="freightcomsettings", + name="username", + ), + ] From d11bf1d13c1bb394aa92c8acac71aae82927fa8d Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 10 Feb 2025 17:31:58 -0500 Subject: [PATCH 07/14] Update Freightcom connection configs and payment ID handling --- .../karrio/mappers/freightcom/__init__.py | 3 ++- .../karrio/providers/freightcom/shipment/create.py | 10 +++++----- .../karrio/providers/freightcom/units.py | 5 +++++ .../karrio/providers/freightcom/utils.py | 14 ++++++++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py b/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py index f7ec65645c..e2193a7312 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/__init__.py @@ -16,5 +16,6 @@ Settings=Settings, # Data Units options=units.ShippingOption, - services=units.ShippingService + services=units.ShippingService, + connection_configs = units.ConnectionConfig, ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py index 12a6e80952..357e8e4ef4 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py @@ -140,11 +140,11 @@ def create_shipment_request( # ) # ] - # payment_method_id = filtered_methods[0].get('id') if filtered_methods else payment_methods[0].get('id') - # - # if not payment_method_id: - # raise Exception("No payment method found") - payment_method_id = '3PQtJaY49gIWzEVJ5DZrP8VP0vH1ZgWU' + + payment_method_id = options.freightcom_payment_id or settings.connection_config.payment_id.state + + if not payment_method_id: + raise Exception("No payment method found need to be set in config") request = freightcom.ShippingRequestType( diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/units.py b/modules/connectors/freightcom/karrio/providers/freightcom/units.py index 7ad92b770c..0ae1e6ee26 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/units.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/units.py @@ -21,6 +21,11 @@ "dhl_e_commerce": "dhl_express", } +class ConnectionConfig(lib.Enum): + """Carrier specific connection configs""" + shipping_options = lib.OptionEnum("shipping_options", list) + shipping_services = lib.OptionEnum("shipping_services", list) + payment_id = lib.OptionEnum("payment_id") class PackagingType(lib.StrEnum): # TODO: review types diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index 7159fc43ea..17b6fabd3b 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -1,8 +1,9 @@ import base64 from typing import Optional import math + +from karrio import lib from karrio.core import Settings as BaseSettings -from karrio.lib import request class Settings(BaseSettings): @@ -28,8 +29,17 @@ def server_url(self): def carrier_name(self): return "freightcom" + @property + def connection_config(self) -> lib.units.Options: + from karrio.providers.freightcom.units import ConnectionConfig + + return lib.to_connection_config( + self.config or {}, + option_type=ConnectionConfig, + ) + def download_label(file_url: str) -> str: - return request( + return lib.request( decoder=lambda b: base64.encodebytes(b).decode("utf-8"), url=file_url, ) From 52efee75929d62df89cb0712d79fbca13e19bdd6 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Wed, 12 Feb 2025 19:29:23 -0500 Subject: [PATCH 08/14] Refactor payment method handling in Freightcom integration Streamlined the retrieval and configuration of payment methods by introducing dynamic fetching based on account settings and payment method type. Removed hardcoded payment IDs and legacy unused logic, replacing them with a cache-based mechanism to improve flexibility and maintainability. --- .../karrio/mappers/freightcom/proxy.py | 2 +- .../karrio/mappers/freightcom/settings.py | 9 ++-- .../providers/freightcom/shipment/create.py | 21 +--------- .../karrio/providers/freightcom/units.py | 2 +- .../karrio/providers/freightcom/utils.py | 42 ++++++++++++++++++- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py index 9cdb10abdd..a0704df285 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py @@ -75,7 +75,7 @@ def get_tracking(self, request: lib.Serializable) -> lib.Deserializable[str]: return lib.Deserializable(response, lib.to_dict) # TODO: not sure how this can be a dynamic unit Enum, and cached for now i hard code the id in the ship request - def get_payments_methods(self, request: lib.Serializable) -> lib.Deserializable[str]: + def get_payments_methods(self) -> lib.Deserializable[str]: response = self._send_request( path="/finance/payment-methods", method="GET" diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py index 9aae43f710..8a131d608f 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py @@ -1,15 +1,18 @@ """Karrio freightcom connection settings.""" import attr -from karrio.providers.freightcom.utils import Settings as BaseSettings +import karrio.providers.freightcom.utils as provider_utils +from karrio.providers.freightcom.units import PaymentMethodType @attr.s(auto_attribs=True) -class Settings(BaseSettings): +class Settings(provider_utils.Settings): """Freightcom connection settings.""" - + #carrier specific API connection properties here api_key: str + payment_method_type: PaymentMethodType = "net_terms" + # generic properties id: str = None test_mode: bool = False carrier_id: str = "freightcom" diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py index 357e8e4ef4..2531e58f18 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py @@ -122,26 +122,7 @@ def create_shipment_request( ), ) - # TODO: need to know how to make this to get the payment_method ID, it's unique on each account, and not sure where this code belongs - - # payment_methods_response = proxy.get_payments_methods(lib.Serializable(None)) - # payment_methods = payment_methods_response.deserialize() - # - # # Get requested payment type or default to net_terms - # requested_type = (payload.payment.type - # if payload and payload.payment and payload.payment.type - # else provider_units.PaymentMethodType.map().value) - # - # # Filter payment methods by type - # filtered_methods = [ - # method for method in payment_methods - # if method.get('type') == provider_units.PaymentMethodType.map( - # options.freightcom_payment_method or "net_terms" - # ) - # ] - - - payment_method_id = options.freightcom_payment_id or settings.connection_config.payment_id.state + payment_method_id = settings.payment_method if not payment_method_id: raise Exception("No payment method found need to be set in config") diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/units.py b/modules/connectors/freightcom/karrio/providers/freightcom/units.py index 0ae1e6ee26..89a871f3ab 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/units.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/units.py @@ -21,11 +21,11 @@ "dhl_e_commerce": "dhl_express", } + class ConnectionConfig(lib.Enum): """Carrier specific connection configs""" shipping_options = lib.OptionEnum("shipping_options", list) shipping_services = lib.OptionEnum("shipping_services", list) - payment_id = lib.OptionEnum("payment_id") class PackagingType(lib.StrEnum): # TODO: review types diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index 17b6fabd3b..ac69039d6e 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -4,14 +4,15 @@ from karrio import lib from karrio.core import Settings as BaseSettings +from karrio.providers.freightcom.units import PaymentMethodType class Settings(BaseSettings): """Freightcom connection settings.""" - username: str - password: str api_key: str + payment_method_type: PaymentMethodType = PaymentMethodType.net_terms + account_country_code: str = None metadata: dict = {} @@ -38,6 +39,22 @@ def connection_config(self) -> lib.units.Options: option_type=ConnectionConfig, ) + @property + def payment_method(self): + cache_key = f"payment|{self.carrier_name}|{self.payment_method_type}|{self.api_key}" + + payment = self.connection_cache.get(cache_key) or {} + payment_id = payment.get("id") + + if payment_id: + return payment_id + + self.connection_cache.set(cache_key, lambda: get_payment_id(self)) + new_auth = self.connection_cache.get(cache_key) + + return new_auth.get("id") + + def download_label(file_url: str) -> str: return lib.request( decoder=lambda b: base64.encodebytes(b).decode("utf-8"), @@ -49,3 +66,24 @@ def ceil(value: Optional[float]) -> Optional[int]: if value is None: return None return math.ceil(value) + +def get_payment_id(settings: Settings) -> dict: + + try: + from karrio.mappers.freightcom.proxy import Proxy + + proxy = Proxy(settings) + response = proxy.get_payments_methods() + methods = response.deserialize() + + + except Exception as e: + raise + + + for method in methods: + if PaymentMethodType.map(method.get('type')).name == settings.payment_method_type: + return method + + else: + raise Exception(f"Payment method {settings.payment_method_type} not found") From 9537628d18b8e4e6f6e4ae343afca023a755c7f3 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 24 Feb 2025 12:37:24 -0500 Subject: [PATCH 09/14] Refactor Freightcom provider function names and responses. Renamed and standardized function names (e.g., `create_shipment_request` to `shipment_request`) for consistency and readability. Adjusted response handling and removed unused/commented-out code to improve maintainability. Minor cleanup in formatting and imports to streamline the codebase. --- .../karrio/mappers/freightcom/mapper.py | 2 +- .../karrio/providers/freightcom/__init__.py | 2 +- .../karrio/providers/freightcom/rate.py | 16 ++++++++-------- .../providers/freightcom/shipment/__init__.py | 4 ++-- .../providers/freightcom/shipment/cancel.py | 5 ++--- .../providers/freightcom/shipment/create.py | 13 ++----------- 6 files changed, 16 insertions(+), 26 deletions(-) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py b/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py index 684a75b0b9..b583e1ec0f 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/mapper.py @@ -15,7 +15,7 @@ def create_rate_request(self, payload: models.RateRequest) -> Serializable: return provider.rate_request(payload, self.settings) def create_shipment_request(self, payload: models.ShipmentRequest) -> Serializable: - return provider.create_shipment_request(payload, self.settings) + return provider.shipment_request(payload, self.settings) def create_cancel_shipment_request( self, payload: models.ShipmentCancelRequest diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py b/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py index 1e1d8bd406..1f6e3f4dbe 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/__init__.py @@ -2,7 +2,7 @@ from karrio.providers.freightcom.rate import parse_rate_response, rate_request from karrio.providers.freightcom.shipment import ( parse_shipment_response, - create_shipment_request, + shipment_request, parse_shipment_cancel_response, shipment_cancel_request, ) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py index 617b35e25b..f677edffe3 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py @@ -10,15 +10,17 @@ def parse_rate_response( - response: lib.Deserializable[dict], + _response: lib.Deserializable[dict], settings: provider_utils.Settings, ) -> typing.Tuple[typing.List[models.RateDetails], typing.List[models.Message]]: - """Parse Freightcom rate response into Karrio format""" - parsed_response = response.deserialize() - messages = error.parse_error_response(parsed_response, settings) - rates = [_extract_details(rate, settings) for rate in parsed_response.get("rates", [])] + response = _response.deserialize() + + messages = error.parse_error_response(response, settings) + rates = [_extract_details(rate, settings) for rate in response.get("rates", [])] + return rates, messages + def _extract_details( data: dict, settings: provider_utils.Settings, @@ -58,11 +60,11 @@ def _extract_details( ), ) + def rate_request( payload: models.RateRequest, settings: provider_utils.Settings, ) -> lib.Serializable: - """Create a Freightcom rate request from Karrio unified request""" shipper = lib.to_address(payload.shipper) recipient = lib.to_address(payload.recipient) packages = lib.to_packages(payload.parcels) @@ -200,5 +202,3 @@ def rate_request( ) ) return lib.Serializable(request, lib.to_dict) - - diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py index ee61d33cbc..9b68164657 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/__init__.py @@ -1,8 +1,8 @@ + from karrio.providers.freightcom.shipment.create import ( parse_shipment_response, - create_shipment_request, + shipment_request, ) - from karrio.providers.freightcom.shipment.cancel import ( parse_shipment_cancel_response, shipment_cancel_request, diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py index 41352e30f9..f30a6a83a2 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/cancel.py @@ -1,3 +1,4 @@ + import typing import karrio.lib as lib import karrio.core.models as models @@ -19,9 +20,7 @@ def parse_shipment_cancel_response( carrier_name=settings.carrier_name, operation="Cancel Shipment", success=success, - ) - if success - else None + ) if success else None ) return confirmation, messages diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py index 2531e58f18..ce86bc74e9 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py @@ -4,6 +4,7 @@ import datetime import uuid import karrio.lib as lib +import karrio.core.units as units import karrio.core.models as models import karrio.providers.freightcom.error as error import karrio.providers.freightcom.utils as provider_utils @@ -18,14 +19,6 @@ def parse_shipment_response( response = _response.deserialize() messages = error.parse_error_response(response, settings) - # shipment = lib.to_multi_piece_shipment( - # [ - # (index, _extract_details(data, data.get("shipmentId"), settings)) - # for index, data in enumerate(response.get("labels", [])) - # ] - # ) - # - shipment = _extract_details(response.get("shipment", {}), settings, ctx=_response.ctx) if "shipment" in response else None return shipment, messages @@ -75,12 +68,10 @@ def _extract_details( ) -def create_shipment_request( +def shipment_request( payload: models.ShipmentRequest, settings: provider_utils.Settings, ) -> lib.Serializable: - - shipper = lib.to_address(payload.shipper) recipient = lib.to_address(payload.recipient) packages = lib.to_packages(payload.parcels) From b7a6a0bf709c7d47a270ef910ed7a887b341ef1b Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 24 Feb 2025 17:26:29 -0500 Subject: [PATCH 10/14] Fix Freightcom tests --- .../karrio/providers/freightcom/rate.py | 16 +- .../providers/freightcom/shipment/create.py | 36 +- .../karrio/providers/freightcom/units.py | 4 +- .../karrio/providers/freightcom/utils.py | 3 +- .../freightcom/tests/freightcom/fixture.py | 12 +- .../freightcom/tests/freightcom/test_rate.py | 505 +++++++++++++----- .../tests/freightcom/test_shipment.py | 478 ++++++++++++----- 7 files changed, 772 insertions(+), 282 deletions(-) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py index f677edffe3..755f37e485 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/rate.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/rate.py @@ -56,8 +56,8 @@ def _extract_details( ], meta=dict( rate_provider=courier.name_or_key, - service_name=service.name_or_key , - ), + service_name=service.name_or_key + ) ) @@ -93,10 +93,10 @@ def rate_request( country=shipper.country_code, postal_code=shipper.postal_code, ), - residential=shipper.residential, + residential=shipper.residential is True, contact_name=shipper.person_name if shipper.company_name else "", phone_number=freightcom.PhoneNumberType( - number=shipper.phone_number + number=shipper.phone_number, ) if shipper.phone_number else None, email_addresses=lib.join(shipper.email), ), @@ -110,7 +110,7 @@ def rate_request( country=recipient.country_code, postal_code=recipient.postal_code, ), - residential=recipient.residential, + residential=recipient.residential is True, contact_name=recipient.person_name, phone_number=freightcom.PhoneNumberType( number=recipient.phone_number @@ -124,6 +124,7 @@ def rate_request( hour=17, minute=0 ), + receives_email_updates=options.email_notification.state, signature_requirement="required" if options.signature_confirmation.state else "not-required" ), expected_ship_date=freightcom.ExpectedShipDateType( @@ -195,10 +196,9 @@ def rate_request( ) ) if options.insurance.state else None, pallet_service_details=freightcom.PalletServiceDetailsType() if packaging_type == "pallet" else None, - ) - + ) ), - reference_codes=[payload.reference] if payload.reference else [] + reference_codes=[payload.reference] if any(payload.reference or "") else [] ) ) return lib.Serializable(request, lib.to_dict) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py index ce86bc74e9..bb766e8810 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py @@ -29,7 +29,7 @@ def _extract_details( ctx: dict, ) -> models.ShipmentDetails: shipment = lib.to_object(shipping.ShipmentType, data) - label_type = "ZPL" if ctx["label_type"] == "ZPL" else "PDF" + label_type = "ZPL" if ctx.get("label_type") == "ZPL" else "PDF" label_url = [_.url for _ in shipment.labels if _.format == label_type.lower() and _.size == "a6" and not _.padded] label = provider_utils.download_label(label_url[0]) if label_url else None tracking_numbers = ( @@ -48,7 +48,7 @@ def _extract_details( ) courier = provider_units.ShippingCourier.find(rate.service_id) - + print(label) return models.ShipmentDetails( carrier_id=settings.carrier_id, carrier_name=settings.carrier_name, @@ -57,6 +57,7 @@ def _extract_details( label_type=label_type, docs=models.Documents(label=label), meta=dict( + carrier_tracking_link=shipment.tracking_url, tracking_numbers=tracking_numbers, rate_provider=courier.name_or_key, @@ -85,6 +86,11 @@ def shipment_request( packages.package_type or "small_box" ).value + ship_datetime = lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M", + ) + is_intl = shipper.country_code != recipient.country_code customs = lib.to_customs_info( payload.customs, @@ -118,7 +124,6 @@ def shipment_request( if not payment_method_id: raise Exception("No payment method found need to be set in config") - request = freightcom.ShippingRequestType( unique_id=str(uuid.uuid4()), payment_method_id=payment_method_id, @@ -134,7 +139,7 @@ def shipment_request( country=shipper.country_code, postal_code=shipper.postal_code, ), - residential=shipper.residential, + residential=shipper.residential is True, contact_name=shipper.person_name if shipper.company_name else "", phone_number=freightcom.NumberType( number=shipper.phone_number @@ -151,38 +156,27 @@ def shipment_request( country=recipient.country_code, postal_code=recipient.postal_code, ), - residential=recipient.residential, + residential=recipient.residential is True, contact_name=recipient.person_name, phone_number=freightcom.NumberType( number=recipient.phone_number ) if recipient.phone_number else None, email_addresses=[recipient.email] if recipient.email else [], ready_at=freightcom.ReadyType( - hour=lib.to_next_business_datetime( - options.shipping_date.state or datetime.datetime.now(), - current_format="%Y-%m-%dT%H:%M" - ).hour, + hour=ship_datetime.hour, minute=0 ), ready_until=freightcom.ReadyType( hour=17, minute=0 ), + receives_email_updates=options.email_notification.state, signature_requirement="required" if options.signature_confirmation.state else "not-required" ), expected_ship_date=freightcom.DateType( - year=lib.to_next_business_datetime( - options.shipping_date.state or datetime.datetime.now(), - current_format="%Y-%m-%dT%H:%M" - ).year, - month=lib.to_next_business_datetime( - options.shipping_date.state or datetime.datetime.now(), - current_format="%Y-%m-%dT%H:%M" - ).month, - day=lib.to_next_business_datetime( - options.shipping_date.state or datetime.datetime.now(), - current_format="%Y-%m-%dT%H:%M" - ).day, + year=ship_datetime.year, + month=ship_datetime.month, + day=ship_datetime.day, ), packaging_type=packaging_type, packaging_properties=freightcom.PackagingPropertiesType( diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/units.py b/modules/connectors/freightcom/karrio/providers/freightcom/units.py index 89a871f3ab..b619bcbd33 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/units.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/units.py @@ -105,8 +105,8 @@ class ShippingOption(lib.Enum): freightcom_payment_method = lib.OptionEnum("payment_method", str) """ Unified Option type mapping """ - saturday_delivery = freightcom_saturday_pickup_required - signature_confirmation = freightcom_signature_required + # saturday_delivery = freightcom_saturday_pickup_required + # signature_confirmation = freightcom_signature_required diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index ac69039d6e..b6069824c3 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -2,6 +2,7 @@ from typing import Optional import math +from karrio.lib import request from karrio import lib from karrio.core import Settings as BaseSettings from karrio.providers.freightcom.units import PaymentMethodType @@ -56,7 +57,7 @@ def payment_method(self): def download_label(file_url: str) -> str: - return lib.request( + return request( decoder=lambda b: base64.encodebytes(b).decode("utf-8"), url=file_url, ) diff --git a/modules/connectors/freightcom/tests/freightcom/fixture.py b/modules/connectors/freightcom/tests/freightcom/fixture.py index 6cc6de05a6..ea3cc9c8cb 100644 --- a/modules/connectors/freightcom/tests/freightcom/fixture.py +++ b/modules/connectors/freightcom/tests/freightcom/fixture.py @@ -1,7 +1,17 @@ import karrio +import karrio.lib as lib +cached_payment_method_id = { + f"payment|freightcom|net_terms|api_key": dict( + id="string", + type= "net-terms", + label="Net Terms" + ) +} gateway = karrio.gateway["freightcom"].create( dict( api_key="api_key", - ) + payment_method_type="net_terms" + ), + cache=lib.Cache(**cached_payment_method_id), ) diff --git a/modules/connectors/freightcom/tests/freightcom/test_rate.py b/modules/connectors/freightcom/tests/freightcom/test_rate.py index 53bde5553c..ffd6efce97 100644 --- a/modules/connectors/freightcom/tests/freightcom/test_rate.py +++ b/modules/connectors/freightcom/tests/freightcom/test_rate.py @@ -1,168 +1,421 @@ +import datetime import unittest -from unittest.mock import patch -from karrio.core.utils import DP -from karrio.core.models import RateRequest -from karrio.core.errors import FieldError -from karrio import Rating +from unittest.mock import patch, ANY from .fixture import gateway +# from tests import logger + +import karrio +import karrio.lib as lib +import karrio.core.models as models class TestFreightcomRating(unittest.TestCase): def setUp(self): self.maxDiff = None - self.RateRequest = RateRequest(**RatePayload) + self.RateRequest = models.RateRequest(**RatePayload) def test_create_rate_request(self): request = gateway.mapper.create_rate_request(self.RateRequest) + self.assertEqual(request.serialize(), RateRequest) - self.assertEqual(request.serialize(), RateRequestXML) + def test_get_rate(self): + with patch("karrio.mappers.freightcom.proxy.lib.request") as mock: + mock.return_value = "{}" + karrio.Rating.fetch(self.RateRequest).from_(gateway) - def test_create_rate_request_from_package_preset_missing_weight(self): - with self.assertRaises(FieldError): - gateway.mapper.create_rate_request( - RateRequest(**RateWithPresetMissingDimensionPayload) + self.assertEqual( + mock.call_args[1]["url"], + f"{gateway.settings.server_url}/rate", ) - @patch("karrio.mappers.freightcom.proxy.http", return_value="") - def test_get_rates(self, http_mock): - Rating.fetch(self.RateRequest).from_(gateway) - - url = http_mock.call_args[1]["url"] - self.assertEqual(url, gateway.proxy.settings.server_url) - def test_parse_rate_response(self): - with patch("karrio.mappers.freightcom.proxy.http") as mock: - mock.return_value = RateResponseXml - parsed_response = Rating.fetch(self.RateRequest).from_(gateway).parse() - - self.assertListEqual(DP.to_dict(parsed_response), ParsedQuoteResponse) - - def test_parse_rate_response_error(self): - with patch("karrio.mappers.freightcom.proxy.http") as mock: - mock.return_value = RateErrorResponseXML - parsed_response = Rating.fetch(self.RateRequest).from_(gateway).parse() - - self.assertListEqual(DP.to_dict(parsed_response), ParsedRateError) + with patch("karrio.mappers.freightcom.proxy.lib.request") as mock: + mock.return_value = RateResponse + parsed_response = karrio.Rating.fetch(self.RateRequest).from_(gateway).parse() + self.assertListEqual(lib.to_dict(parsed_response), ParsedRateResponse) if __name__ == "__main__": unittest.main() + RatePayload = { - "shipper": {"postal_code": "H8Z2Z3", "country_code": "CA"}, - "recipient": {"postal_code": "H8Z2V4", "country_code": "CA"}, + "shipper": { + "company_name": "Test Company - From", + "address_line1": "9, Van Der Graaf Court", + "city": "Brampton", + "postal_code": "L4T3T1", + "country_code": "CA", + "state_code": "ON", + "email": "shipper@example.com", + "phone_number": "(123) 114 1499" + }, + "recipient": { + "company_name": "Test Company - Destination", + "address_line1": "1410 Fall River Rd", + "city": "Fall River", + "country_code": "CA", + "postal_code": "B2T1J1", + "residential": "true", + "state_code": "NS", + "email": "recipient@example.com", + "phone_number": "(999) 999 9999" + }, "parcels": [ { - "height": 3, - "length": 10, - "width": 3, - "weight": 4.0, + "height": 50, + "length": 50, + "weight": 20, + "width": 12, + "dimension_unit": "CM", + "weight_unit": "KG", + "description": "Package 1 Description" + }, + { + "height": 30, + "length": 50, + "weight": 20, + "width": 12, "dimension_unit": "CM", "weight_unit": "KG", + "description": "Package 2 Description" } ], - "services": ["freightcom_central_transport"], -} - -RateWithPresetMissingDimensionPayload = { - "shipper": {"postal_code": "H8Z2Z3", "country_code": "CA"}, - "recipient": {"postal_code": "H8Z2V4", "country_code": "CA"}, - "parcels": [{}], + "reference": "REF-001", + "options": { + "email_notification": True, + "shipping_date": datetime.datetime(2025, 2, 25, 1,0).strftime("%Y-%m-%dT%H:%M"), + } } -ParsedQuoteResponse = [ - [ - { - "carrier_id": "freightcom", - "carrier_name": "freightcom", - "currency": "CAD", - "extra_charges": [ - {"amount": 177.0, "currency": "CAD", "name": "Base charge"} - ], - "meta": { - "rate_provider": "Freightcom", - "service_name": "central_transport", - }, - "service": "freightcom_central_transport", - "total_charge": 177.0, - "transit_days": 1, +ParsedRateResponse = [ + [ + { + "carrier_id": "freightcom", + "carrier_name": "freightcom", + "currency": "CAD", + "extra_charges": [ + { + "amount": 33.68, + "currency": "CAD", + "name": "Base charge" }, { - "carrier_id": "freightcom", - "carrier_name": "freightcom", - "currency": "CAD", - "extra_charges": [ - {"amount": 28.65, "currency": "CAD", "name": "Base charge"} - ], - "meta": {"rate_provider": "Freightcom", "service_name": "estes"}, - "service": "freightcom_estes", - "total_charge": 28.65, - "transit_days": 1, + "amount": 10.01, + "currency": "CAD", + "name": "fuel" }, { - "carrier_id": "freightcom", - "carrier_name": "freightcom", - "currency": "CAD", - "extra_charges": [ - {"amount": 46.27, "currency": "CAD", "name": "Base charge"}, - {"amount": 6.25, "currency": "CAD", "name": "Fuel surcharge"}, - ], - "meta": {"rate_provider": "Freightcom", "service_name": "usf_holland"}, - "service": "freightcom_usf_holland", - "total_charge": 52.52, - "transit_days": 0, + "amount": 0.51, + "currency": "CAD", + "name": "carbon-surcharge" + }, + { + "amount": 2.18, + "currency": "CAD", + "name": "residential-delivery" }, - ], - [ { - "carrier_id": "freightcom", - "carrier_name": "freightcom", - "code": "CarrierErrorMessage", - "message": "Polaris:Military Base Delivery,Saturday Pickup,Construction Site,BORDER FEE,Homeland Security,Limited Access,Saturday Delivery,Sort and Segregate Charge,Pier Charge", + "amount": 6.96, + "currency": "CAD", + "name": "tax-hst-ns" } - ], -] - -ParsedRateError = [ - [], - [ - { - "code": "Error", - "carrier_id": "freightcom", - "carrier_name": "freightcom", - "message": "Required field: company is missing.", + ], + "meta": { + "rate_provider": "canpar", + "service_name": "freightcom_canpar_ground" + }, + "service": "freightcom_canpar_ground", + "total_charge": 53.34, + "transit_days": 2 + }, + { + "carrier_id": "freightcom", + "carrier_name": "freightcom", + "currency": "CAD", + "extra_charges": [ + { + "amount": 40.87, + "currency": "CAD", + "name": "Base charge" + }, + { + "amount": 12.54, + "currency": "CAD", + "name": "fuel" + }, + { + "amount": 2.78, + "currency": "CAD", + "name": "residential-delivery" + }, + { + "amount": 8.43, + "currency": "CAD", + "name": "tax-hst-ns" } - ], + ], + "meta": { + "rate_provider": "fedex", + "service_name": "freightcom_fedex_ground" + }, + "service": "freightcom_fedex_ground", + "total_charge": 64.62, + "transit_days": 2 + }, + { + "carrier_id": "freightcom", + "carrier_name": "freightcom", + "currency": "CAD", + "extra_charges": [ + { + "amount": 41.34, + "currency": "CAD", + "name": "Base charge" + }, + { + "amount": 11.24, + "currency": "CAD", + "name": "fuel" + }, + { + "amount": 7.89, + "currency": "CAD", + "name": "tax-hst-ns" + } + ], + "meta": { + "rate_provider": "purolator", + "service_name": "freightcom_purolator_ground" + }, + "service": "freightcom_purolator_ground", + "total_charge": 60.47, + "transit_days": 3 + } + ], + [] ] -RateRequestXML = f""" - - - - - - - - -""" -RateErrorResponseXML = f""" - - - - -""" +RateRequest = { + "details": { + "destination": { + "address": { + "address_line_1": "1410 Fall River Rd", + "city": "Fall River", + "country": "CA", + "postal_code": "B2T1J1", + "region": "NS", + }, + "email_addresses": ["recipient@example.com"], + 'name': 'Test Company - Destination', + "phone_number": {"number": "(999) 999 9999"}, + "ready_at": { + "hour": 10, "minute": 0 + }, + "ready_until": { + "hour": 17, "minute": 0 + }, + "receives_email_updates": True, + "residential": False, + "signature_requirement": "not-required" + }, + "origin": { + "address": { + "address_line_1": "9, Van Der Graaf Court", + "city": "Brampton", + "country": "CA", + "postal_code": "L4T3T1", + "region": "ON", + }, + "name": "Test Company - From", + "email_addresses": ["shipper@example.com"], + "phone_number": {"number": "(123) 114 1499"}, + "residential": False + }, + "expected_ship_date": {"day": 25, "month": 2, "year": 2025}, + "packaging_type": "package", + "packaging_properties": { + "packages": [ + { + "description": "Package 1 Description", + "measurements": { + "cuboid": { + "h": 50.0, + "l": 50.0, + "unit": "cm", + "w": 12.0 + }, + "weight": { + "unit": "kg", + "value": 20.0 + } + } + }, + { + "description": "Package 2 Description", + "measurements": { + "cuboid": { + "h": 30.0, + "l": 50.0, + "unit": "cm", + "w": 12.0 + }, + "weight": { + "unit": "kg", + "value": 20.0 + } + } + } + ], + }, + "reference_codes": ["REF-001"] + } +} -RateResponseXml = """ - - - - - - - - - - - +RateResponse = """ +{ + "status": { + "done": true, + "total": 99, + "complete": 99 + }, + "rates": [ + { + "service_id": "canpar.ground", + "valid_until": { + "year": 2025, + "month": 3, + "day": 3 + }, + "total": { + "value": "5334", + "currency": "CAD" + }, + "base": { + "value": "3368", + "currency": "CAD" + }, + "surcharges": [ + { + "type": "fuel", + "amount": { + "value": "1001", + "currency": "CAD" + } + }, + { + "type": "carbon-surcharge", + "amount": { + "value": "51", + "currency": "CAD" + } + }, + { + "type": "residential-delivery", + "amount": { + "value": "218", + "currency": "CAD" + } + } + ], + "taxes": [ + { + "type": "tax-hst-ns", + "amount": { + "value": "696", + "currency": "CAD" + } + } + ], + "transit_time_days": 2, + "transit_time_not_available": false, + "carrier_name": "Canpar", + "service_name": "Ground" + }, + { + "service_id": "fedex-courier.ground", + "valid_until": { + "year": 2025, + "month": 3, + "day": 3 + }, + "total": { + "value": "6462", + "currency": "CAD" + }, + "base": { + "value": "4087", + "currency": "CAD" + }, + "surcharges": [ + { + "type": "fuel", + "amount": { + "value": "1254", + "currency": "CAD" + } + }, + { + "type": "residential-delivery", + "amount": { + "value": "278", + "currency": "CAD" + } + } + ], + "taxes": [ + { + "type": "tax-hst-ns", + "amount": { + "value": "843", + "currency": "CAD" + } + } + ], + "transit_time_days": 2, + "transit_time_not_available": false, + "carrier_name": "FedEx Courier", + "service_name": "Ground" + }, + { + "service_id": "purolatorcourier.ground", + "valid_until": { + "year": 2025, + "month": 3, + "day": 3 + }, + "total": { + "value": "6047", + "currency": "CAD" + }, + "base": { + "value": "4134", + "currency": "CAD" + }, + "surcharges": [ + { + "type": "fuel", + "amount": { + "value": "1124", + "currency": "CAD" + } + } + ], + "taxes": [ + { + "type": "tax-hst-ns", + "amount": { + "value": "789", + "currency": "CAD" + } + } + ], + "transit_time_days": 3, + "transit_time_not_available": false, + "carrier_name": "Purolator", + "service_name": "Ground" + } + ] +} """ diff --git a/modules/connectors/freightcom/tests/freightcom/test_shipment.py b/modules/connectors/freightcom/tests/freightcom/test_shipment.py index cb6ca3da2f..8330d3f817 100644 --- a/modules/connectors/freightcom/tests/freightcom/test_shipment.py +++ b/modules/connectors/freightcom/tests/freightcom/test_shipment.py @@ -1,133 +1,149 @@ +import datetime import unittest from unittest.mock import patch, ANY from .fixture import gateway +# from tests import logger import karrio -from karrio.core.utils import DP -from karrio.core.models import ShipmentRequest, ShipmentCancelRequest +import karrio.lib as lib +import karrio.core.models as models -class TestFreightcomShipment(unittest.TestCase): +class TestFreightcomShipping(unittest.TestCase): def setUp(self): self.maxDiff = None - self.ShipmentRequest = ShipmentRequest(**shipment_data) - self.ShipmentCancelRequest = ShipmentCancelRequest(**shipment_cancel_data) + self.ShipmentRequest = models.ShipmentRequest(**ShipmentPayload) + self.ShipmentCancelRequest = models.ShipmentCancelRequest(**ShipmentCancelPayload) def test_create_shipment_request(self): request = gateway.mapper.create_shipment_request(self.ShipmentRequest) - - self.assertEqual(request.serialize(), ShipmentRequestXML) + self.assertEqual(request.serialize(), ShipmentRequest) def test_create_cancel_shipment_request(self): request = gateway.mapper.create_cancel_shipment_request( self.ShipmentCancelRequest ) - - self.assertEqual(request.serialize(), ShipmentCancelRequestXML) + self.assertEqual(request.serialize(), ShipmentCancelRequest) def test_create_shipment(self): - with patch("karrio.mappers.freightcom.proxy.http") as mock: - mock.return_value = "" + with patch("karrio.mappers.freightcom.proxy.lib.request") as mock: + mock.return_value = "{}" karrio.Shipment.create(self.ShipmentRequest).from_(gateway) - url = mock.call_args[1]["url"] - self.assertEqual(url, gateway.settings.server_url) + self.assertEqual( + mock.call_args[1]["url"], + f"{gateway.settings.server_url}/shipment", + ) def test_cancel_shipment(self): - with patch("karrio.mappers.freightcom.proxy.http") as mock: - mock.return_value = "" + with patch("karrio.mappers.freightcom.proxy.lib.request") as mock: + mock.return_value = "{}" karrio.Shipment.cancel(self.ShipmentCancelRequest).from_(gateway) - url = mock.call_args[1]["url"] - self.assertEqual(url, gateway.settings.server_url) + self.assertEqual( + mock.call_args[1]["url"], + f"{gateway.settings.server_url}/shipment/{self.ShipmentCancelRequest.shipment_identifier}", + ) def test_parse_shipment_response(self): - with patch("karrio.mappers.freightcom.proxy.http") as mock: - mock.return_value = ShipmentResponseXML - parsed_response = ( - karrio.Shipment.create(self.ShipmentRequest).from_(gateway).parse() - ) + with patch("karrio.mappers.freightcom.proxy.lib.request") as mock: + mock.return_value = ShipmentResponse + response = karrio.Shipment.create(self.ShipmentRequest).from_(gateway) + + with patch("karrio.providers.freightcom.utils.request") as mock: + mock.return_value = "" + parsed_response = response.parse() + print(parsed_response) - self.assertEqual(DP.to_dict(parsed_response), ParsedShipmentResponse) + self.assertListEqual(lib.to_dict(parsed_response), ParsedShipmentResponse) def test_parse_cancel_shipment_response(self): - with patch("karrio.mappers.freightcom.proxy.http") as mock: - mock.return_value = ShipmentCancelResponseXML + with patch("karrio.mappers.freightcom.proxy.lib.request") as mock: + mock.return_value = ShipmentCancelResponse parsed_response = ( - karrio.Shipment.cancel(self.ShipmentCancelRequest) - .from_(gateway) - .parse() + karrio.Shipment.cancel(self.ShipmentCancelRequest).from_(gateway).parse() ) - - self.assertEqual( - DP.to_dict(parsed_response), DP.to_dict(ParsedCancelShipmentResponse) + self.assertListEqual( + lib.to_dict(parsed_response), ParsedCancelShipmentResponse ) if __name__ == "__main__": unittest.main() -shipment_cancel_data = {"shipment_identifier": "383363"} -shipment_data = { +ShipmentPayload = { "shipper": { - "company_name": "CGI", - "address_line1": "502 MAIN ST N", - "city": "MONTREAL", - "postal_code": "H2B1A0", + "company_name": "Test Company - From", + "address_line1": "9, Van Der Graaf Court", + "city": "Brampton", + "postal_code": "L4T3T1", "country_code": "CA", - "person_name": "Bob", - "phone_number": "1 (450) 823-8432", - "state_code": "QC", + "state_code": "ON", + "email": "shipper@example.com", + "phone_number": "(123) 114 1499" }, "recipient": { - "company_name": "CGI", - "address_line1": "23 jardin private", - "city": "Ottawa", - "postal_code": "K1K4T3", + "company_name": "Test Company - Destination", + "address_line1": "1410 Fall River Rd", + "city": "Fall River", "country_code": "CA", - "person_name": "Jain", - "state_code": "ON", + "postal_code": "B2T1J1", + "residential": "true", + "state_code": "NS", + "email": "recipient@example.com", + "phone_number": "(999) 999 9999" }, "parcels": [ { - "height": 9, - "length": 6, + "height": 50, + "length": 50, + "weight": 20, "width": 12, - "weight": 20.0, "dimension_unit": "CM", "weight_unit": "KG", + "description": "Package 1 Description" + }, + { + "height": 30, + "length": 50, + "weight": 20, + "width": 12, + "dimension_unit": "CM", + "weight_unit": "KG", + "description": "Package 2 Description" } ], - "service": "freightcom_central_transport", - "options": {"cash_on_delivery": 10.5, "insurance": 70.0}, + "service": "freightcom_canpar_ground", + "options": { + "signature_confirmation": True, + "shipping_date": datetime.datetime(2025, 2, 25, 1, 0).strftime("%Y-%m-%dT%H:%M"), + }, + "reference": "#Order 11111", +} + +ShipmentCancelPayload = { + "shipment_identifier": "shipment_id", } ParsedShipmentResponse = [ { "carrier_id": "freightcom", "carrier_name": "freightcom", - "docs": {"label": ANY, "invoice": ANY}, - "meta": {"rate_provider": "Freightcom", "service_name": "central_transport"}, - "selected_rate": { - "carrier_id": "freightcom", - "carrier_name": "freightcom", - "currency": "CAD", - "extra_charges": [ - {"amount": 30.74, "currency": "CAD", "name": "Base charge"}, - {"amount": 1.08, "currency": "CAD", "name": "Other"}, - ], - "meta": { - "rate_provider": "Freightcom", - "service_name": "central_transport", - }, - "service": "freightcom_central_transport", - "total_charge": 31.82, - "transit_days": 0, + "docs": {}, + 'label_type': 'PDF', + "meta": { + 'carrier_tracking_link': 'https://www.ups.com/WebTracking?trackingNumber=1ZXXXXXXXXXXXXXXXX', + 'freightcom_service_id': 'ups.standard', + 'freightcom_unique_id': '38a8b937-4262-497b-8f5c-b9d9d4c6bae6', + 'rate_provider': 'ups', + 'service_name': 'freightcom_ups_standard', + 'tracking_numbers': ['1ZXXXXXXXXXXXXXXXX'] + }, + + "shipment_identifier": "uQeh1XwbVIbIyP9mEPtVM2puAFZYmAYA", + "tracking_number": "1ZXXXXXXXXXXXXXXXX" }, - "shipment_identifier": "181004", - "tracking_number": "052800410000484", - }, [], ] @@ -141,61 +157,277 @@ def test_parse_cancel_shipment_response(self): [], ] +ShipmentRequest = { + "details": { + "destination": { + "address": { + "address_line_1": "1410 Fall River Rd", + "city": "Fall River", + "country": "CA", + "postal_code": "B2T1J1", + "region": "NS", + }, + "email_addresses": ["recipient@example.com"], + 'name': 'Test Company - Destination', + "phone_number": {"number": "(999) 999 9999"}, + "ready_at": { + "hour": 10, "minute": 0 + }, + "ready_until": { + "hour": 17, "minute": 0 + }, + "receives_email_updates": True, + "residential": False, + "signature_requirement": "required" + }, + "origin": { + "address": { + "address_line_1": "9, Van Der Graaf Court", + "city": "Brampton", + "country": "CA", + "postal_code": "L4T3T1", + "region": "ON", + }, + "name": "Test Company - From", + "email_addresses": ["shipper@example.com"], + "phone_number": {"number": "(123) 114 1499"}, + "residential": False + }, + "expected_ship_date": {"day": 25, "month": 2, "year": 2025}, + "packaging_type": "package", + "packaging_properties": { + "packages": [ + { + "description": "Package 1 Description", + "measurements": { + "cuboid": { + "h": 50.0, + "l": 50.0, + "unit": "cm", + "w": 12.0 + }, + "weight": { + "unit": "kg", + "value": 20.0 + } + } + }, + { + "description": "Package 2 Description", + "measurements": { + "cuboid": { + "h": 30.0, + "l": 50.0, + "unit": "cm", + "w": 12.0 + }, + "weight": { + "unit": "kg", + "value": 20.0 + } + } + } + ], + }, + "reference_codes": ["#Order 11111"] + }, + 'payment_method_id': 'string', + "service_id": "canpar.ground", + "unique_id": ANY +} -ShipmentRequestXML = """ - - - - - - - - - - - -""" +ShipmentCancelRequest = "shipment_id" -ShipmentResponseXML = """ - - - - - - - - [base-64 encoded String] - [base-64 encoded String] - - - - - - - - - - - -""" -ShipmentCancelRequestXML = """ - - - - +ShipmentResponse = """ +{ +"shipment": { + "id": "uQeh1XwbVIbIyP9mEPtVM2puAFZYmAYA", + "unique_id": "38a8b937-4262-497b-8f5c-b9d9d4c6bae6", + "state": "waiting-for-scheduling", + "transaction_number": "19989362", + "primary_tracking_number": "1ZXXXXXXXXXXXXXXXX", + "tracking_numbers": [ + "1ZXXXXXXXXXXXXXXXX", + "1ZXXXXXXXXXXXXXXXX" + ], + "tracking_url": "https://www.ups.com/WebTracking?trackingNumber=1ZXXXXXXXXXXXXXXXX", + "return_tracking_number": "", + "bolnumber": "", + "pickup_confirmation_number": "", + "details": { + "id": "HNrzG2iRHKJ6XN0CQwYgKBQnABvx2Yi5", + "expected_ship_date": { + "year": 2025, + "month": 2, + "day": 12 + }, + "origin": { + "searchable_id": "", + "name": "Cheques Plus", + "address": { + "address_line1": "4054 Rue Alfred Laliberté", + "address_line2": "", + "unit_number": "", + "city": "Boisbriand", + "region": "QC", + "country": "CA", + "postal_code": "J7H 1P8", + "validated": false + }, + "residential": false, + "business_type": "", + "tailgate_required": false, + "instructions": "", + "contact_name": "Shipping", + "phone_number": { + "number": "+1 450-323-6247", + "extension": "" + }, + "email_addresses": [ + "sales@chequesplus.com" + ], + "receives_email_updates": false, + "address_book_contact_id": "" + }, + "destination": { + "searchable_id": "", + "name": "ASAP Cheques", + "address": { + "address_line1": "623 Fortune Crescent #100", + "address_line2": "", + "unit_number": "", + "city": "Kingston", + "region": "ON", + "country": "CA", + "postal_code": "K7P 0L5", + "validated": false + }, + "residential": false, + "business_type": "", + "tailgate_required": false, + "instructions": "", + "contact_name": "ASAP Cheques Kingston", + "phone_number": { + "number": "+1 888-324-3783", + "extension": "" + }, + "email_addresses": [ + "admin@shipngo.ca" + ], + "receives_email_updates": false, + "address_book_contact_id": "", + "ready_at": { + "hour": 10, + "minute": 0, + "populated": true + }, + "ready_until": { + "hour": 17, + "minute": 0, + "populated": true + }, + "signature_requirement": "not-required" + }, + "alternate_destination": null, + "reference_codes": [ + "ss" + ], + "packaging_type": "package", + "packaging_properties": { + "packages": [ + { + "measurements": { + "cuboid": { + "l": 10, + "w": 20, + "h": 18.2, + "unit": "cm" + }, + "weight": { + "value": 1, + "unit": "kg" + } + }, + "description": "N/A", + "special_handling_required": false + }, + { + "measurements": { + "cuboid": { + "l": 10, + "w": 33.7, + "h": 18.2, + "unit": "cm" + }, + "weight": { + "value": 1, + "unit": "kg" + } + }, + "description": "N/A", + "special_handling_required": false + } + ], + "includes_return_label": false + }, + "insurance": null, + "billing_contact": null + }, + "transport_data": null, + "labels": [ + { + "size": "letter", + "format": "pdf", + "url": "https://s3.us-east-2.amazonaws.com/ssd-test-external/labels/uQeh1XwbVIbIyP9mEPtVM2puAFZYmAYA/yRWNRmUkCGMKIZOjMHNUSy9JlXPYjvVb/shipping-label-19989362-letter.pdf", + "padded": false + }, + { + "size": "a6", + "format": "zpl", + "url": "https://s3.us-east-2.amazonaws.com/ssd-test-external/labels/uQeh1XwbVIbIyP9mEPtVM2puAFZYmAYA/yRWNRmUkCGMKIZOjMHNUSy9JlXPYjvVb/shipping-label-19989362-a6.zpl", + "padded": false + }, + { + "size": "a6", + "format": "pdf", + "url": "https://s3.us-east-2.amazonaws.com/ssd-test-external/labels/uQeh1XwbVIbIyP9mEPtVM2puAFZYmAYA/yRWNRmUkCGMKIZOjMHNUSy9JlXPYjvVb/shipping-label-19989362-a6.pdf", + "padded": false + }, + { + "size": "a6", + "format": "pdf", + "url": "https://s3.us-east-2.amazonaws.com/ssd-test-external/labels/uQeh1XwbVIbIyP9mEPtVM2puAFZYmAYA/yRWNRmUkCGMKIZOjMHNUSy9JlXPYjvVb/shipping-label-19989362-a6-w-padding.pdf", + "padded": true + } + ], + "customs_invoice_url": "", + "rate": { + "service_id": "ups.standard", + "valid_until": { + "year": 2025, + "month": 2, + "day": 20 + }, + "total": { + "value": "1779", + "currency": "CAD" + }, + "base": { + "value": "1779", + "currency": "CAD" + }, + "surcharges": [], + "taxes": [], + "transit_time_days": 1, + "transit_time_not_available": false, + "carrier_name": "UPS", + "service_name": "Standard" + }, + "order_source": "Api" + } +} """ -ShipmentCancelResponseXML = """ - - - - - +ShipmentCancelResponse = """{} """ From 92be0a737f1fddebb8ec2957f74f1e14cb253366 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 24 Feb 2025 17:47:50 -0500 Subject: [PATCH 11/14] Fix Freightcom proxy to show the right Capabilities it was pulling None after we have a function without underscore --- .../freightcom/karrio/mappers/freightcom/proxy.py | 14 +++++++------- .../karrio/providers/freightcom/utils.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py index a0704df285..af5c248698 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py @@ -5,11 +5,11 @@ import karrio.api.proxy as proxy from karrio.mappers.freightcom.settings import Settings +MAX_RETRIES = 10 +POLL_INTERVAL = 2 # seconds class Proxy(proxy.Proxy): settings: Settings - MAX_RETRIES = 10 - POLL_INTERVAL = 2 # seconds def get_rates(self, request: lib.Serializable) -> lib.Deserializable: # Step 1: Submit rate request and get quote ID @@ -22,7 +22,7 @@ def get_rates(self, request: lib.Serializable) -> lib.Deserializable: return lib.Deserializable(response, lib.to_dict) # Step 2: Poll for rate results - for _ in range(self.MAX_RETRIES): + for _ in range(MAX_RETRIES): status_res = self._send_request( path=f"/rate/{rate_id}", method="GET" @@ -33,7 +33,7 @@ def get_rates(self, request: lib.Serializable) -> lib.Deserializable: if status: # Quote is complete return lib.Deserializable(status_res, lib.to_dict) - time.sleep(self.POLL_INTERVAL) + time.sleep(POLL_INTERVAL) # If we exceed max retries return lib.Deserializable({ @@ -53,7 +53,7 @@ def create_shipment(self, request: lib.Serializable) -> lib.Deserializable: # Step 2: retry because api return empty bytes if done to fast time.sleep(1) - for _ in range(self.MAX_RETRIES): + for _ in range(MAX_RETRIES): shipment_response = self._send_request(path=f"/shipment/{shipment_id}", method="GET") shipment_res = lib.failsafe(lambda :lib.to_dict(shipment_response)) or lib.decode(shipment_response) @@ -61,7 +61,7 @@ def create_shipment(self, request: lib.Serializable) -> lib.Deserializable: if shipment_res: # is complete return lib.Deserializable(shipment_res, lib.to_dict, request.ctx) - time.sleep(self.POLL_INTERVAL) + time.sleep(POLL_INTERVAL) # If we exceed max retries return lib.Deserializable({ @@ -75,7 +75,7 @@ def get_tracking(self, request: lib.Serializable) -> lib.Deserializable[str]: return lib.Deserializable(response, lib.to_dict) # TODO: not sure how this can be a dynamic unit Enum, and cached for now i hard code the id in the ship request - def get_payments_methods(self) -> lib.Deserializable[str]: + def _get_payments_methods(self) -> lib.Deserializable[str]: response = self._send_request( path="/finance/payment-methods", method="GET" diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index b6069824c3..263370c1a8 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -74,7 +74,7 @@ def get_payment_id(settings: Settings) -> dict: from karrio.mappers.freightcom.proxy import Proxy proxy = Proxy(settings) - response = proxy.get_payments_methods() + response = proxy._get_payments_methods() methods = response.deserialize() From 09300acf64d4ccb9c30750bf14c4f5c2a643f498 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 24 Mar 2025 17:16:57 -0400 Subject: [PATCH 12/14] Remove not needed changes to db --- .../providers/extension/models/freightcom.py | 2 -- .../0081_freightcomsettings_api_key.py | 18 ---------------- ...ve_freightcomsettings_password_and_more.py | 21 ------------------- 3 files changed, 41 deletions(-) delete mode 100644 modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py delete mode 100644 modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py diff --git a/modules/core/karrio/server/providers/extension/models/freightcom.py b/modules/core/karrio/server/providers/extension/models/freightcom.py index 2a499af189..c83e5c5dbb 100644 --- a/modules/core/karrio/server/providers/extension/models/freightcom.py +++ b/modules/core/karrio/server/providers/extension/models/freightcom.py @@ -10,8 +10,6 @@ class Meta: verbose_name = "Freightcom Settings" verbose_name_plural = "Freightcom Settings" - api_key = models.CharField(max_length=200, null=True) - @property def carrier_name(self) -> str: return self.CARRIER_NAME diff --git a/modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py b/modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py deleted file mode 100644 index 5b059bbb6a..0000000000 --- a/modules/core/karrio/server/providers/migrations/0081_freightcomsettings_api_key.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.16 on 2025-01-14 22:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("providers", "0080_alter_aramexsettings_account_country_code_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="freightcomsettings", - name="api_key", - field=models.CharField(max_length=200, null=True), - ), - ] diff --git a/modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py b/modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py deleted file mode 100644 index a1b0b79eaa..0000000000 --- a/modules/core/karrio/server/providers/migrations/0082_remove_freightcomsettings_password_and_more.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 4.2.16 on 2025-02-10 21:45 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("providers", "0081_freightcomsettings_api_key"), - ] - - operations = [ - migrations.RemoveField( - model_name="freightcomsettings", - name="password", - ), - migrations.RemoveField( - model_name="freightcomsettings", - name="username", - ), - ] From 4cbd25689ef0c778d01182cfb00296d52dcbfe1d Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Mon, 24 Mar 2025 18:00:24 -0400 Subject: [PATCH 13/14] Refactor payment method handling in Freightcom integration Moved `PaymentMethodType` to improve organization and restructured its usage via `connection_config` for flexibility. Enhanced error handling and streamlined payment method selection logic for better reliability and clarity. --- .../karrio/mappers/freightcom/proxy.py | 1 - .../karrio/mappers/freightcom/settings.py | 2 -- .../karrio/providers/freightcom/units.py | 7 +++--- .../karrio/providers/freightcom/utils.py | 25 +++++++++++-------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py index af5c248698..3d680f8b40 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/proxy.py @@ -74,7 +74,6 @@ def get_tracking(self, request: lib.Serializable) -> lib.Deserializable[str]: return lib.Deserializable(response, lib.to_dict) - # TODO: not sure how this can be a dynamic unit Enum, and cached for now i hard code the id in the ship request def _get_payments_methods(self) -> lib.Deserializable[str]: response = self._send_request( path="/finance/payment-methods", diff --git a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py index 8a131d608f..85509f5dc7 100644 --- a/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py +++ b/modules/connectors/freightcom/karrio/mappers/freightcom/settings.py @@ -2,7 +2,6 @@ import attr import karrio.providers.freightcom.utils as provider_utils -from karrio.providers.freightcom.units import PaymentMethodType @attr.s(auto_attribs=True) @@ -10,7 +9,6 @@ class Settings(provider_utils.Settings): """Freightcom connection settings.""" #carrier specific API connection properties here api_key: str - payment_method_type: PaymentMethodType = "net_terms" # generic properties id: str = None diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/units.py b/modules/connectors/freightcom/karrio/providers/freightcom/units.py index b619bcbd33..f8892ac073 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/units.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/units.py @@ -21,9 +21,13 @@ "dhl_e_commerce": "dhl_express", } +class PaymentMethodType(lib.StrEnum): + net_terms = "net-terms" + credit_card = "credit-card" class ConnectionConfig(lib.Enum): """Carrier specific connection configs""" + payment_method_type = lib.OptionEnum("payment_method_type", PaymentMethodType) shipping_options = lib.OptionEnum("shipping_options", list) shipping_services = lib.OptionEnum("shipping_services", list) @@ -55,9 +59,6 @@ class PackagingType(lib.StrEnum): your_packaging = freightcom_package -class PaymentMethodType(lib.StrEnum): - net_terms = "net-terms" - credit_card = "credit-card" class PaymentType(lib.StrEnum): # TODO:: retrieve the complete list of payment types sender = "shipper" diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py index 263370c1a8..faa8610ec8 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/utils.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/utils.py @@ -5,14 +5,12 @@ from karrio.lib import request from karrio import lib from karrio.core import Settings as BaseSettings -from karrio.providers.freightcom.units import PaymentMethodType class Settings(BaseSettings): """Freightcom connection settings.""" api_key: str - payment_method_type: PaymentMethodType = PaymentMethodType.net_terms account_country_code: str = None @@ -42,7 +40,11 @@ def connection_config(self) -> lib.units.Options: @property def payment_method(self): - cache_key = f"payment|{self.carrier_name}|{self.payment_method_type}|{self.api_key}" + + if not self.connection_config.payment_method_type.state: + raise Exception(f"Payment method type not set") + + cache_key = f"payment|{self.carrier_name}|{self.connection_config.payment_method_type.state}|{self.api_key}" payment = self.connection_cache.get(cache_key) or {} payment_id = payment.get("id") @@ -77,14 +79,17 @@ def get_payment_id(settings: Settings) -> dict: response = proxy._get_payments_methods() methods = response.deserialize() + selected_method = next(( + method for method in methods + if settings.connection_config.payment_method_type.type.map( + method.get('type')).name == settings.connection_config.payment_method_type.state + ), None) - except Exception as e: - raise + if not selected_method: + raise Exception(f"Payment method {settings.connection_config.payment_method_type.stat} not found in API") - for method in methods: - if PaymentMethodType.map(method.get('type')).name == settings.payment_method_type: - return method + return selected_method - else: - raise Exception(f"Payment method {settings.payment_method_type} not found") + except Exception as e: + raise From 2820f605c40f6625a07a93cf2f30bffcc8d61735 Mon Sep 17 00:00:00 2001 From: Jacob Shilitz Date: Thu, 27 Mar 2025 17:13:51 -0400 Subject: [PATCH 14/14] Remove debug print and adjust Freightcom gateway config structure. The debug `print` statement was removed for cleaner code, and the Freightcom gateway configuration was updated to nest `payment_method_type` within a `config` dictionary. This ensures better consistency and structure in the gateway setup. --- .../freightcom/karrio/providers/freightcom/shipment/create.py | 2 -- modules/connectors/freightcom/tests/freightcom/fixture.py | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py index bb766e8810..fac7b7932e 100644 --- a/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py +++ b/modules/connectors/freightcom/karrio/providers/freightcom/shipment/create.py @@ -48,7 +48,6 @@ def _extract_details( ) courier = provider_units.ShippingCourier.find(rate.service_id) - print(label) return models.ShipmentDetails( carrier_id=settings.carrier_id, carrier_name=settings.carrier_name, @@ -64,7 +63,6 @@ def _extract_details( service_name=service.name_or_key, freightcom_service_id=rate.service_id, freightcom_unique_id=shipment.unique_id, - ) ) diff --git a/modules/connectors/freightcom/tests/freightcom/fixture.py b/modules/connectors/freightcom/tests/freightcom/fixture.py index ea3cc9c8cb..4c631bc6bb 100644 --- a/modules/connectors/freightcom/tests/freightcom/fixture.py +++ b/modules/connectors/freightcom/tests/freightcom/fixture.py @@ -11,7 +11,9 @@ gateway = karrio.gateway["freightcom"].create( dict( api_key="api_key", - payment_method_type="net_terms" + config=dict( + payment_method_type="net_terms" + ) ), cache=lib.Cache(**cached_payment_method_id), )