diff --git a/.circleci/config.yml b/.circleci/config.yml index c8c63793886..304327fa286 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -883,6 +883,7 @@ commands: export ENVIRONMENT=test export FEATURE_FLAG_MULTI_MOVE=true export FEATURE_FLAG_PPM=true + export FEATURE_FLAG_PPM_SPR=false export FEATURE_FLAG_NTS=true export FEATURE_FLAG_NTSR=true export FEATURE_FLAG_BOAT=true diff --git a/.envrc b/.envrc index 420230d6e6e..8a7e15afe0c 100644 --- a/.envrc +++ b/.envrc @@ -167,6 +167,7 @@ export FEATURE_FLAG_QUEUE_MANAGEMENT=true # Feature flags to disable certain shipment types export FEATURE_FLAG_PPM=true +export FEATURE_FLAG_PPM_SPR=false export FEATURE_FLAG_NTS=true export FEATURE_FLAG_NTSR=true export FEATURE_FLAG_BOAT=true diff --git a/config/env/demo.app-client-tls.env b/config/env/demo.app-client-tls.env index 607a783835f..d7cfefc7794 100644 --- a/config/env/demo.app-client-tls.env +++ b/config/env/demo.app-client-tls.env @@ -32,6 +32,7 @@ TELEMETRY_USE_XRAY_ID=true TLS_ENABLED=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/demo.app.env b/config/env/demo.app.env index 018b1eacf47..22445b891f6 100644 --- a/config/env/demo.app.env +++ b/config/env/demo.app.env @@ -37,6 +37,7 @@ SERVE_API_SUPPORT=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_COUNSELOR_MOVE_CREATE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/exp.app-client-tls.env b/config/env/exp.app-client-tls.env index 4ea3d45fbd9..6d7367ae654 100644 --- a/config/env/exp.app-client-tls.env +++ b/config/env/exp.app-client-tls.env @@ -32,6 +32,7 @@ TELEMETRY_ENDPOINT=localhost:4317 TELEMETRY_USE_XRAY_ID=false FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/exp.app.env b/config/env/exp.app.env index 2b8a2a05787..21718e30fe3 100644 --- a/config/env/exp.app.env +++ b/config/env/exp.app.env @@ -37,6 +37,7 @@ TELEMETRY_USE_XRAY_ID=true FEATURE_FLAG_MULTI_MOVE=true FEATURE_FLAG_COUNSELOR_MOVE_CREATE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/loadtest.app-client-tls.env b/config/env/loadtest.app-client-tls.env index c121d3f8b8c..bdde5c7d1b6 100644 --- a/config/env/loadtest.app-client-tls.env +++ b/config/env/loadtest.app-client-tls.env @@ -30,6 +30,7 @@ TELEMETRY_USE_XRAY_ID=true TLS_ENABLED=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/loadtest.app.env b/config/env/loadtest.app.env index 50fc9439a6c..890d4660083 100644 --- a/config/env/loadtest.app.env +++ b/config/env/loadtest.app.env @@ -35,6 +35,7 @@ SERVE_API_SUPPORT=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_COUNSELOR_MOVE_CREATE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/prd.app-client-tls.env b/config/env/prd.app-client-tls.env index 3fa4fa27671..1a44df90cfd 100644 --- a/config/env/prd.app-client-tls.env +++ b/config/env/prd.app-client-tls.env @@ -29,6 +29,7 @@ TELEMETRY_USE_XRAY_ID=true TLS_ENABLED=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_PPM=false +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=false FEATURE_FLAG_NTSR=false FEATURE_FLAG_BOAT=false diff --git a/config/env/prd.app.env b/config/env/prd.app.env index e99c80d02b2..22b755e062f 100644 --- a/config/env/prd.app.env +++ b/config/env/prd.app.env @@ -36,6 +36,7 @@ SERVE_API_SUPPORT=false FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_COUNSELOR_MOVE_CREATE=false FEATURE_FLAG_PPM=false +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=false FEATURE_FLAG_NTSR=false FEATURE_FLAG_BOAT=false diff --git a/config/env/stg.app-client-tls.env b/config/env/stg.app-client-tls.env index 1264d120c82..024a4de2638 100644 --- a/config/env/stg.app-client-tls.env +++ b/config/env/stg.app-client-tls.env @@ -31,6 +31,7 @@ TELEMETRY_USE_XRAY_ID=true TLS_ENABLED=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/env/stg.app.env b/config/env/stg.app.env index 33ba71851ed..3228ea40103 100644 --- a/config/env/stg.app.env +++ b/config/env/stg.app.env @@ -37,6 +37,7 @@ SERVE_API_SUPPORT=true FEATURE_FLAG_MULTI_MOVE=false FEATURE_FLAG_COUNSELOR_MOVE_CREATE =false FEATURE_FLAG_PPM=true +FEATURE_FLAG_PPM_SPR=false FEATURE_FLAG_NTS=true FEATURE_FLAG_NTSR=true FEATURE_FLAG_BOAT=false diff --git a/config/flipt/storage/development.features.yaml b/config/flipt/storage/development.features.yaml index a7084f2574b..55bf7a44350 100644 --- a/config/flipt/storage/development.features.yaml +++ b/config/flipt/storage/development.features.yaml @@ -73,6 +73,14 @@ flags: - segment: key: mil-app value: false + - key: enable_hawaii + name: Enable Hawaii feature flag + type: BOOLEAN_FLAG_TYPE + enabled: false + rollouts: + - segment: + key: mil-app + value: false - key: okta_dodid_input name: Customer DODID input being pulled from Okta and disabling text input type: BOOLEAN_FLAG_TYPE @@ -89,6 +97,14 @@ flags: - segment: key: mil-app value: true + - key: ppm_spr + name: Enable PPM Small Package Reimbursement flag + type: BOOLEAN_FLAG_TYPE + enabled: false + rollouts: + - segment: + key: mil-app + value: false - key: nts name: NTS feature flag type: BOOLEAN_FLAG_TYPE diff --git a/migrations/app/ddl_functions_manifest.txt b/migrations/app/ddl_functions_manifest.txt index 237796e829e..e034b0a7981 100644 --- a/migrations/app/ddl_functions_manifest.txt +++ b/migrations/app/ddl_functions_manifest.txt @@ -1,3 +1,4 @@ # This is the functions(procedures) migrations manifest. # If a migration is not recorded here, then it will error. # Naming convention: fn_some_function.up.sql running will create this file. +20250223023132_fn_get_counseling_offices.up.sql diff --git a/migrations/app/ddl_migrations/ddl_functions/20250223023132_fn_get_counseling_offices.up.sql b/migrations/app/ddl_migrations/ddl_functions/20250223023132_fn_get_counseling_offices.up.sql new file mode 100644 index 00000000000..50dee4dd9e2 --- /dev/null +++ b/migrations/app/ddl_migrations/ddl_functions/20250223023132_fn_get_counseling_offices.up.sql @@ -0,0 +1,171 @@ +--B-22660 Daniel Jordan added get_duty_location_info +CREATE OR REPLACE FUNCTION get_duty_location_info(p_duty_location_id UUID) +RETURNS TABLE (duty_addr_id UUID, is_oconus BOOLEAN) +LANGUAGE plpgsql AS $$ +BEGIN + RETURN QUERY + SELECT dl.address_id, a.is_oconus + FROM duty_locations dl + JOIN addresses a ON a.id = dl.address_id + WHERE dl.id = p_duty_location_id; +END; +$$; + +--B-22660 Daniel Jordan added get_service_affiliation +CREATE OR REPLACE FUNCTION get_service_affiliation(p_service_member_id UUID) +RETURNS TEXT +LANGUAGE plpgsql AS $$ +DECLARE + service_affiliation TEXT; +BEGIN + SELECT affiliation INTO service_affiliation + FROM service_members + WHERE id = p_service_member_id; + + RETURN service_affiliation; +END; +$$; + +--B-22660 Daniel Jordan added get_department_indicator +CREATE OR REPLACE FUNCTION get_department_indicator(p_service_affiliation TEXT) +RETURNS TEXT +LANGUAGE plpgsql AS $$ +DECLARE + dept_indicator TEXT; +BEGIN + IF p_service_affiliation IN ('AIR_FORCE', 'SPACE_FORCE') THEN + dept_indicator := 'AIR_AND_SPACE_FORCE'; + ELSIF p_service_affiliation IN ('NAVY', 'MARINES') THEN + dept_indicator := 'NAVY_AND_MARINES'; + ELSIF p_service_affiliation = 'ARMY' THEN + dept_indicator := 'ARMY'; + ELSIF p_service_affiliation = 'COAST_GUARD' THEN + dept_indicator := 'COAST_GUARD'; + ELSE + RAISE EXCEPTION 'Invalid affiliation: %', p_service_affiliation; + END IF; + + RETURN dept_indicator; +END; +$$; + +--B-22660 Daniel Jordan added get_gbloc_indicator +CREATE OR REPLACE FUNCTION get_gbloc_indicator(p_duty_addr_id UUID, p_dept_indicator TEXT) +RETURNS TEXT +LANGUAGE plpgsql AS $$ +DECLARE + gbloc_indicator TEXT; +BEGIN + SELECT j.code INTO gbloc_indicator + FROM addresses a + JOIN v_locations v ON a.us_post_region_cities_id = v.uprc_id + JOIN re_oconus_rate_areas o ON v.uprc_id = o.us_post_region_cities_id + JOIN re_rate_areas r ON o.rate_area_id = r.id + JOIN gbloc_aors g ON o.id = g.oconus_rate_area_id + JOIN jppso_regions j ON g.jppso_regions_id = j.id + WHERE a.id = p_duty_addr_id + AND (g.department_indicator = p_dept_indicator OR g.department_indicator IS NULL) + LIMIT 1; + + IF gbloc_indicator IS NULL THEN + RAISE EXCEPTION 'Cannot determine GBLOC for duty location'; + END IF; + + RETURN gbloc_indicator; +END; +$$; + +--B-22660 Daniel Jordan added fetch_counseling_offices_for_oconus +CREATE OR REPLACE FUNCTION fetch_counseling_offices_for_oconus(p_duty_location_id UUID, p_gbloc_indicator TEXT) +RETURNS TABLE (id UUID, name TEXT) +LANGUAGE plpgsql AS $$ +BEGIN + RETURN QUERY + SELECT toff.id, toff.name + FROM duty_locations dl + JOIN addresses a ON dl.address_id = a.id + JOIN v_locations v ON (a.us_post_region_cities_id = v.uprc_id OR v.uprc_id IS NULL) + AND a.country_id = v.country_id + JOIN re_oconus_rate_areas r ON r.us_post_region_cities_id = v.uprc_id + JOIN gbloc_aors ga ON ga.oconus_rate_area_id = r.id + JOIN jppso_regions j ON ga.jppso_regions_id = j.id + JOIN transportation_offices toff ON j.code = toff.gbloc + JOIN addresses toff_addr ON toff.address_id = toff_addr.id + LEFT JOIN zip3_distances zd + ON ( + (substring(a.postal_code, 1, 3) = zd.from_zip3 AND substring(toff_addr.postal_code, 1, 3) = zd.to_zip3) + OR + (substring(a.postal_code, 1, 3) = zd.to_zip3 AND substring(toff_addr.postal_code, 1, 3) = zd.from_zip3) + ) + WHERE dl.provides_services_counseling = true + AND dl.id = p_duty_location_id + AND j.code = p_gbloc_indicator + AND toff.provides_ppm_closeout = true + ORDER BY COALESCE(zd.distance_miles, 0) ASC; +END; +$$; + +--B-22660 Daniel Jordan added fetch_counseling_offices_for_conus +CREATE OR REPLACE FUNCTION fetch_counseling_offices_for_conus(p_duty_location_id UUID) +RETURNS TABLE (id UUID, name TEXT) +LANGUAGE plpgsql AS $$ +BEGIN + RETURN QUERY + SELECT + toff.id, + toff.name + FROM postal_code_to_gblocs pcg + JOIN addresses a ON pcg.postal_code = a.postal_code + JOIN duty_locations dl ON a.id = dl.address_id + JOIN transportation_offices toff ON pcg.gbloc = toff.gbloc + JOIN addresses toff_addr ON toff.address_id = toff_addr.id + JOIN duty_locations d2 ON toff.id = d2.transportation_office_id + JOIN re_us_post_regions rup ON toff_addr.postal_code = rup.uspr_zip_id + LEFT JOIN zip3_distances zd + ON ( + (substring(a.postal_code, 1, 3) = zd.from_zip3 AND substring(toff_addr.postal_code, 1, 3) = zd.to_zip3) + OR + (substring(a.postal_code, 1, 3) = zd.to_zip3 AND substring(toff_addr.postal_code, 1, 3) = zd.from_zip3) + ) + WHERE dl.provides_services_counseling = true + AND dl.id = p_duty_location_id + AND d2.provides_services_counseling = true + GROUP BY toff.id, toff.name, zd.distance_miles + ORDER BY COALESCE(zd.distance_miles, 0), toff.name ASC; +END; +$$; + +--B-22660 Daniel Jordan added get_counseling_offices +CREATE OR REPLACE FUNCTION get_counseling_offices( + p_duty_location_id UUID, + p_service_member_id UUID +) +RETURNS TABLE (id UUID, name TEXT) +LANGUAGE plpgsql AS $$ +DECLARE + is_address_oconus BOOLEAN; + duty_address_id UUID; + service_affiliation TEXT; + dept_indicator TEXT; + gbloc_indicator TEXT; +BEGIN + + SELECT duty_addr_id, is_oconus INTO duty_address_id, is_address_oconus + FROM get_duty_location_info(p_duty_location_id); + + IF duty_address_id IS NULL THEN + RAISE EXCEPTION 'Duty location % not found when searching for counseling offices', p_duty_location_id; + END IF; + + IF is_address_oconus THEN + service_affiliation := get_service_affiliation(p_service_member_id); + dept_indicator := get_department_indicator(service_affiliation); + + gbloc_indicator := get_gbloc_indicator(duty_address_id, dept_indicator); + + RETURN QUERY SELECT * FROM fetch_counseling_offices_for_oconus(p_duty_location_id, gbloc_indicator); + ELSE + RETURN QUERY SELECT * FROM fetch_counseling_offices_for_conus(p_duty_location_id); + END IF; +END; +$$; diff --git a/migrations/app/ddl_migrations/ddl_tables/20250224200700_tbl_ppm_shipments.up.sql b/migrations/app/ddl_migrations/ddl_tables/20250224200700_tbl_ppm_shipments.up.sql new file mode 100644 index 00000000000..a23f7e68968 --- /dev/null +++ b/migrations/app/ddl_migrations/ddl_tables/20250224200700_tbl_ppm_shipments.up.sql @@ -0,0 +1,3 @@ +-- B-22653 Daniel Jordan add ppm_type column to ppm_shipments +ALTER TABLE ppm_shipments +ADD COLUMN IF NOT EXISTS ppm_type ppm_shipment_type NOT NULL DEFAULT 'INCENTIVE_BASED'; diff --git a/migrations/app/ddl_migrations/ddl_types/20250224202726_ty_ppm_shipment_type.up.sql b/migrations/app/ddl_migrations/ddl_types/20250224202726_ty_ppm_shipment_type.up.sql new file mode 100644 index 00000000000..8d06f35dec6 --- /dev/null +++ b/migrations/app/ddl_migrations/ddl_types/20250224202726_ty_ppm_shipment_type.up.sql @@ -0,0 +1,11 @@ +-- B-22653 Daniel Jordan add ppm_shipment_type +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ppm_shipment_type') THEN + CREATE TYPE ppm_shipment_type AS ENUM ( + 'INCENTIVE_BASED', + 'ACTUAL_EXPENSE', + 'SMALL_PACKAGE' + ); + END IF; +END $$; diff --git a/migrations/app/ddl_migrations/ddl_types/20250224202738_ty_moving_expenses_type.up.sql b/migrations/app/ddl_migrations/ddl_types/20250224202738_ty_moving_expenses_type.up.sql new file mode 100644 index 00000000000..2cad6fed1f4 --- /dev/null +++ b/migrations/app/ddl_migrations/ddl_types/20250224202738_ty_moving_expenses_type.up.sql @@ -0,0 +1,2 @@ +-- B-22653 Daniel Jordan update moving_expense_type to include SMALL_PACKAGE +ALTER TYPE moving_expense_type ADD VALUE IF NOT EXISTS 'SMALL_PACKAGE'; \ No newline at end of file diff --git a/migrations/app/ddl_tables_manifest.txt b/migrations/app/ddl_tables_manifest.txt index 8fd6841c337..9de3cbf4e7e 100644 --- a/migrations/app/ddl_tables_manifest.txt +++ b/migrations/app/ddl_tables_manifest.txt @@ -1,3 +1,4 @@ # This is the tables migrations manifest. # If a migration is not recorded here, then it will error. # Naming convention: tbl_some_table.up.sql running will create this file. +20250224200700_tbl_ppm_shipments.up.sql diff --git a/migrations/app/ddl_types_manifest.txt b/migrations/app/ddl_types_manifest.txt index 9229c96f599..6faaa8a3f24 100644 --- a/migrations/app/ddl_types_manifest.txt +++ b/migrations/app/ddl_types_manifest.txt @@ -1,3 +1,5 @@ # This is the types migrations manifest. # If a migration is not recorded here, then it will error. # Naming convention: ty_some_type.up.sql running will create this file. +20250224202726_ty_ppm_shipment_type.up.sql +20250224202738_ty_moving_expenses_type.up.sql diff --git a/pkg/factory/ppm_shipment_factory.go b/pkg/factory/ppm_shipment_factory.go index cc87032285e..dc0cbe809c6 100644 --- a/pkg/factory/ppm_shipment_factory.go +++ b/pkg/factory/ppm_shipment_factory.go @@ -57,6 +57,7 @@ func buildPPMShipmentWithBuildType(db *pop.Connection, customs []Customization, } ppmShipment := models.PPMShipment{ + PPMType: models.PPMType(models.PPMTypeIncentiveBased), ShipmentID: shipment.ID, Shipment: shipment, Status: models.PPMShipmentStatusDraft, diff --git a/pkg/gen/adminapi/embedded_spec.go b/pkg/gen/adminapi/embedded_spec.go index 3433894752a..27a0e153ff4 100644 --- a/pkg/gen/adminapi/embedded_spec.go +++ b/pkg/gen/adminapi/embedded_spec.go @@ -3296,16 +3296,6 @@ func init() { "format": "uuid", "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" }, - "latitude": { - "type": "number", - "format": "float", - "example": 29.382973 - }, - "longitude": { - "type": "number", - "format": "float", - "example": -98.62759 - }, "name": { "type": "string", "example": "Fort Bragg North Station" @@ -6988,16 +6978,6 @@ func init() { "format": "uuid", "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" }, - "latitude": { - "type": "number", - "format": "float", - "example": 29.382973 - }, - "longitude": { - "type": "number", - "format": "float", - "example": -98.62759 - }, "name": { "type": "string", "example": "Fort Bragg North Station" diff --git a/pkg/gen/adminmessages/transportation_office.go b/pkg/gen/adminmessages/transportation_office.go index f291b011d51..4468ea5b772 100644 --- a/pkg/gen/adminmessages/transportation_office.go +++ b/pkg/gen/adminmessages/transportation_office.go @@ -41,14 +41,6 @@ type TransportationOffice struct { // Format: uuid ID *strfmt.UUID `json:"id"` - // latitude - // Example: 29.382973 - Latitude float32 `json:"latitude,omitempty"` - - // longitude - // Example: -98.62759 - Longitude float32 `json:"longitude,omitempty"` - // name // Example: Fort Bragg North Station // Required: true diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 0f98b2a0d97..2b0f92b64a8 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -12320,6 +12320,9 @@ func init() { "pickupAddress": { "$ref": "#/definitions/Address" }, + "ppmType": { + "$ref": "#/definitions/PPMType" + }, "proGearWeight": { "description": "The estimated weight of the pro-gear being moved belonging to the service member.", "type": "integer", @@ -12534,6 +12537,17 @@ func init() { "COMPLETED" ] }, + "PPMType": { + "description": "Defines a PPM type", + "type": "string", + "title": "PPM Type", + "enum": [ + "INCENTIVE_BASED", + "ACTUAL_EXPENSE", + "SMALL_PACKAGE" + ], + "readOnly": true + }, "PWSViolation": { "description": "A PWS violation for an evaluation report", "type": "object", @@ -29916,6 +29930,9 @@ func init() { "pickupAddress": { "$ref": "#/definitions/Address" }, + "ppmType": { + "$ref": "#/definitions/PPMType" + }, "proGearWeight": { "description": "The estimated weight of the pro-gear being moved belonging to the service member.", "type": "integer", @@ -30130,6 +30147,17 @@ func init() { "COMPLETED" ] }, + "PPMType": { + "description": "Defines a PPM type", + "type": "string", + "title": "PPM Type", + "enum": [ + "INCENTIVE_BASED", + "ACTUAL_EXPENSE", + "SMALL_PACKAGE" + ], + "readOnly": true + }, "PWSViolation": { "description": "A PWS violation for an evaluation report", "type": "object", diff --git a/pkg/gen/ghcmessages/p_p_m_shipment.go b/pkg/gen/ghcmessages/p_p_m_shipment.go index 3b563ef0515..2b1228b27cf 100644 --- a/pkg/gen/ghcmessages/p_p_m_shipment.go +++ b/pkg/gen/ghcmessages/p_p_m_shipment.go @@ -136,6 +136,9 @@ type PPMShipment struct { // pickup address PickupAddress *Address `json:"pickupAddress,omitempty"` + // ppm type + PpmType PPMType `json:"ppmType,omitempty"` + // The estimated weight of the pro-gear being moved belonging to the service member. ProGearWeight *int64 `json:"proGearWeight"` @@ -272,6 +275,10 @@ func (m *PPMShipment) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validatePpmType(formats); err != nil { + res = append(res, err) + } + if err := m.validateProGearWeightTickets(formats); err != nil { res = append(res, err) } @@ -537,6 +544,23 @@ func (m *PPMShipment) validatePickupAddress(formats strfmt.Registry) error { return nil } +func (m *PPMShipment) validatePpmType(formats strfmt.Registry) error { + if swag.IsZero(m.PpmType) { // not required + return nil + } + + if err := m.PpmType.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ppmType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ppmType") + } + return err + } + + return nil +} + func (m *PPMShipment) validateProGearWeightTickets(formats strfmt.Registry) error { if swag.IsZero(m.ProGearWeightTickets) { // not required return nil @@ -849,6 +873,10 @@ func (m *PPMShipment) ContextValidate(ctx context.Context, formats strfmt.Regist res = append(res, err) } + if err := m.contextValidatePpmType(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateProGearWeightTickets(ctx, formats); err != nil { res = append(res, err) } @@ -1027,6 +1055,24 @@ func (m *PPMShipment) contextValidatePickupAddress(ctx context.Context, formats return nil } +func (m *PPMShipment) contextValidatePpmType(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.PpmType) { // not required + return nil + } + + if err := m.PpmType.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ppmType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ppmType") + } + return err + } + + return nil +} + func (m *PPMShipment) contextValidateProGearWeightTickets(ctx context.Context, formats strfmt.Registry) error { for i := 0; i < len(m.ProGearWeightTickets); i++ { diff --git a/pkg/gen/ghcmessages/p_p_m_type.go b/pkg/gen/ghcmessages/p_p_m_type.go new file mode 100644 index 00000000000..eb16d8cdaf2 --- /dev/null +++ b/pkg/gen/ghcmessages/p_p_m_type.go @@ -0,0 +1,92 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package ghcmessages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" +) + +// PPMType PPM Type +// +// # Defines a PPM type +// +// swagger:model PPMType +type PPMType string + +func NewPPMType(value PPMType) *PPMType { + return &value +} + +// Pointer returns a pointer to a freshly-allocated PPMType. +func (m PPMType) Pointer() *PPMType { + return &m +} + +const ( + + // PPMTypeINCENTIVEBASED captures enum value "INCENTIVE_BASED" + PPMTypeINCENTIVEBASED PPMType = "INCENTIVE_BASED" + + // PPMTypeACTUALEXPENSE captures enum value "ACTUAL_EXPENSE" + PPMTypeACTUALEXPENSE PPMType = "ACTUAL_EXPENSE" + + // PPMTypeSMALLPACKAGE captures enum value "SMALL_PACKAGE" + PPMTypeSMALLPACKAGE PPMType = "SMALL_PACKAGE" +) + +// for schema +var pPMTypeEnum []interface{} + +func init() { + var res []PPMType + if err := json.Unmarshal([]byte(`["INCENTIVE_BASED","ACTUAL_EXPENSE","SMALL_PACKAGE"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + pPMTypeEnum = append(pPMTypeEnum, v) + } +} + +func (m PPMType) validatePPMTypeEnum(path, location string, value PPMType) error { + if err := validate.EnumCase(path, location, value, pPMTypeEnum, true); err != nil { + return err + } + return nil +} + +// Validate validates this p p m type +func (m PPMType) Validate(formats strfmt.Registry) error { + var res []error + + // value enum + if err := m.validatePPMTypeEnum("", "body", m); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// ContextValidate validate this p p m type based on the context it is used +func (m PPMType) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := validate.ReadOnly(ctx, "", "body", PPMType(m)); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/pkg/gen/internalapi/embedded_spec.go b/pkg/gen/internalapi/embedded_spec.go index 0542ac177b6..5b366d3fae0 100644 --- a/pkg/gen/internalapi/embedded_spec.go +++ b/pkg/gen/internalapi/embedded_spec.go @@ -6562,6 +6562,9 @@ func init() { "pickupAddress": { "$ref": "#/definitions/Address" }, + "ppmType": { + "$ref": "#/definitions/PPMType" + }, "proGearWeight": { "description": "The estimated weight of the pro-gear being moved belonging to the service member.", "type": "integer", @@ -6735,6 +6738,17 @@ func init() { ], "readOnly": true }, + "PPMType": { + "description": "Defines a PPM type", + "type": "string", + "title": "PPM Type", + "enum": [ + "INCENTIVE_BASED", + "ACTUAL_EXPENSE", + "SMALL_PACKAGE" + ], + "readOnly": true + }, "PatchMovePayload": { "type": "object", "required": [ @@ -15755,6 +15769,9 @@ func init() { "pickupAddress": { "$ref": "#/definitions/Address" }, + "ppmType": { + "$ref": "#/definitions/PPMType" + }, "proGearWeight": { "description": "The estimated weight of the pro-gear being moved belonging to the service member.", "type": "integer", @@ -15928,6 +15945,17 @@ func init() { ], "readOnly": true }, + "PPMType": { + "description": "Defines a PPM type", + "type": "string", + "title": "PPM Type", + "enum": [ + "INCENTIVE_BASED", + "ACTUAL_EXPENSE", + "SMALL_PACKAGE" + ], + "readOnly": true + }, "PatchMovePayload": { "type": "object", "required": [ diff --git a/pkg/gen/internalmessages/p_p_m_shipment.go b/pkg/gen/internalmessages/p_p_m_shipment.go index 43181ef2904..294a0608532 100644 --- a/pkg/gen/internalmessages/p_p_m_shipment.go +++ b/pkg/gen/internalmessages/p_p_m_shipment.go @@ -136,6 +136,9 @@ type PPMShipment struct { // pickup address PickupAddress *Address `json:"pickupAddress,omitempty"` + // ppm type + PpmType PPMType `json:"ppmType,omitempty"` + // The estimated weight of the pro-gear being moved belonging to the service member. ProGearWeight *int64 `json:"proGearWeight"` @@ -272,6 +275,10 @@ func (m *PPMShipment) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validatePpmType(formats); err != nil { + res = append(res, err) + } + if err := m.validateProGearWeightTickets(formats); err != nil { res = append(res, err) } @@ -537,6 +544,23 @@ func (m *PPMShipment) validatePickupAddress(formats strfmt.Registry) error { return nil } +func (m *PPMShipment) validatePpmType(formats strfmt.Registry) error { + if swag.IsZero(m.PpmType) { // not required + return nil + } + + if err := m.PpmType.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ppmType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ppmType") + } + return err + } + + return nil +} + func (m *PPMShipment) validateProGearWeightTickets(formats strfmt.Registry) error { if swag.IsZero(m.ProGearWeightTickets) { // not required return nil @@ -849,6 +873,10 @@ func (m *PPMShipment) ContextValidate(ctx context.Context, formats strfmt.Regist res = append(res, err) } + if err := m.contextValidatePpmType(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateProGearWeightTickets(ctx, formats); err != nil { res = append(res, err) } @@ -1027,6 +1055,24 @@ func (m *PPMShipment) contextValidatePickupAddress(ctx context.Context, formats return nil } +func (m *PPMShipment) contextValidatePpmType(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.PpmType) { // not required + return nil + } + + if err := m.PpmType.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("ppmType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("ppmType") + } + return err + } + + return nil +} + func (m *PPMShipment) contextValidateProGearWeightTickets(ctx context.Context, formats strfmt.Registry) error { for i := 0; i < len(m.ProGearWeightTickets); i++ { diff --git a/pkg/gen/internalmessages/p_p_m_type.go b/pkg/gen/internalmessages/p_p_m_type.go new file mode 100644 index 00000000000..4ba102b4a09 --- /dev/null +++ b/pkg/gen/internalmessages/p_p_m_type.go @@ -0,0 +1,92 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package internalmessages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" +) + +// PPMType PPM Type +// +// # Defines a PPM type +// +// swagger:model PPMType +type PPMType string + +func NewPPMType(value PPMType) *PPMType { + return &value +} + +// Pointer returns a pointer to a freshly-allocated PPMType. +func (m PPMType) Pointer() *PPMType { + return &m +} + +const ( + + // PPMTypeINCENTIVEBASED captures enum value "INCENTIVE_BASED" + PPMTypeINCENTIVEBASED PPMType = "INCENTIVE_BASED" + + // PPMTypeACTUALEXPENSE captures enum value "ACTUAL_EXPENSE" + PPMTypeACTUALEXPENSE PPMType = "ACTUAL_EXPENSE" + + // PPMTypeSMALLPACKAGE captures enum value "SMALL_PACKAGE" + PPMTypeSMALLPACKAGE PPMType = "SMALL_PACKAGE" +) + +// for schema +var pPMTypeEnum []interface{} + +func init() { + var res []PPMType + if err := json.Unmarshal([]byte(`["INCENTIVE_BASED","ACTUAL_EXPENSE","SMALL_PACKAGE"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + pPMTypeEnum = append(pPMTypeEnum, v) + } +} + +func (m PPMType) validatePPMTypeEnum(path, location string, value PPMType) error { + if err := validate.EnumCase(path, location, value, pPMTypeEnum, true); err != nil { + return err + } + return nil +} + +// Validate validates this p p m type +func (m PPMType) Validate(formats strfmt.Registry) error { + var res []error + + // value enum + if err := m.validatePPMTypeEnum("", "body", m); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// ContextValidate validate this p p m type based on the context it is used +func (m PPMType) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := validate.ReadOnly(ctx, "", "body", PPMType(m)); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index 6b80d8d47a1..ac5b2533fc5 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -336,7 +336,7 @@ func init() { }, "/mto-service-items": { "post": { - "description": "Creates one or more MTOServiceItems. Not all service items may be created, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to create and the documentation will update with the new definition.\n\nUpon creation these items are associated with a Move Task Order and an MTO Shipment.\nThe request must include UUIDs for the MTO and MTO Shipment connected to this service item. Some service item types require\nadditional service items to be autogenerated when added - all created service items, autogenerated included,\nwill be returned in the response.\n\nTo update a service item, please use [updateMTOServiceItem](#operation/updateMTOServiceItem) endpoint.\n\n---\n\n**` + "`" + `MTOServiceItemOriginSIT` + "`" + `**\n\nMTOServiceItemOriginSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic origin SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DOFSIT**\n\n**1st day origin SIT service item**. When a DOFSIT is requested, the API will auto-create the following group of service items:\n * DOFSIT - Domestic origin 1st day SIT\n * DOASIT - Domestic origin Additional day SIT\n * DOPSIT - Domestic origin SIT pickup\n * DOSFSC - Domestic origin SIT fuel surcharge\n\n**DOASIT**\n\n**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item.\nAdditional DOASIT service items can be created and added to an existing shipment that **includes a DOFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemDestSIT` + "`" + `**\n\nMTOServiceItemDestSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic destination SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DDFSIT**\n\n**1st day destination SIT service item**.\n\nThese additional fields are optional for creating a DDFSIT:\n * ` + "`" + `firstAvailableDeliveryDate1` + "`" + `\n * string \u003cdate\u003e\n * First available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together\n * ` + "`" + `dateOfContact1` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `\n * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `timeMilitary1` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.\n * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `firstAvailableDeliveryDate2` + "`" + `\n * string \u003cdate\u003e\n * Second available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together\n * ` + "`" + `dateOfContact2` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact delivery by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `\n * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together\n * ` + "`" + `timeMilitary2` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.\n * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together\n\nWhen a DDFSIT is requested, the API will auto-create the following group of service items:\n * DDFSIT - Domestic destination 1st day SIT\n * DDASIT - Domestic destination Additional day SIT\n * DDDSIT - Domestic destination SIT delivery\n * DDSFSC - Domestic destination SIT fuel surcharge\n\n**NOTE** When providing the ` + "`" + `sitEntryDate` + "`" + ` value in the payload, please ensure that the date is not BEFORE\n` + "`" + `firstAvailableDeliveryDate1` + "`" + ` or ` + "`" + `firstAvailableDeliveryDate2` + "`" + `. If it is, you will receive an error response.\n\n**DDASIT**\n\n**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item.\nAdditional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**.\n", + "description": "Creates one or more MTOServiceItems. Not all service items may be created, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to create and the documentation will update with the new definition.\n\nUpon creation these items are associated with a Move Task Order and an MTO Shipment.\nThe request must include UUIDs for the MTO and MTO Shipment connected to this service item. Some service item types require\nadditional service items to be autogenerated when added - all created service items, autogenerated included,\nwill be returned in the response.\n\nTo update a service item, please use [updateMTOServiceItem](#operation/updateMTOServiceItem) endpoint.\n\n---\n\n**` + "`" + `MTOServiceItemOriginSIT` + "`" + `**\n\nMTOServiceItemOriginSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic origin SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DOFSIT**\n\n**1st day origin SIT service item**. When a DOFSIT is requested, the API will auto-create the following group of service items:\n * DOFSIT - Domestic origin 1st day SIT\n * DOASIT - Domestic origin Additional day SIT\n * DOPSIT - Domestic origin SIT pickup\n * DOSFSC - Domestic origin SIT fuel surcharge\n\n**DOASIT**\n\n**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item.\nAdditional DOASIT service items can be created and added to an existing shipment that **includes a DOFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemDestSIT` + "`" + `**\n\nMTOServiceItemDestSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic destination SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DDFSIT**\n\n**1st day destination SIT service item**.\n\nThese additional fields are optional for creating a DDFSIT:\n * ` + "`" + `firstAvailableDeliveryDate1` + "`" + `\n * string \u003cdate\u003e\n * First available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together\n * ` + "`" + `dateOfContact1` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `\n * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `timeMilitary1` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.\n * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `firstAvailableDeliveryDate2` + "`" + `\n * string \u003cdate\u003e\n * Second available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together\n * ` + "`" + `dateOfContact2` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact delivery by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `\n * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together\n * ` + "`" + `timeMilitary2` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.\n * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together\n\nWhen a DDFSIT is requested, the API will auto-create the following group of service items:\n * DDFSIT - Domestic destination 1st day SIT\n * DDASIT - Domestic destination Additional day SIT\n * DDDSIT - Domestic destination SIT delivery\n * DDSFSC - Domestic destination SIT fuel surcharge\n\n**NOTE** When providing the ` + "`" + `sitEntryDate` + "`" + ` value in the payload, please ensure that the date is not BEFORE\n` + "`" + `firstAvailableDeliveryDate1` + "`" + ` or ` + "`" + `firstAvailableDeliveryDate2` + "`" + `. If it is, you will receive an error response.\n\n**DDASIT**\n\n**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item.\nAdditional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemInternationalOriginSIT` + "`" + `**\n\nMTOServiceItemInternationalOriginSIT is a subtype of MTOServiceItem.\n\nThis model type describes a international origin SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**IOFSIT**\n\n**1st day origin SIT service item**. When a IOFSIT is requested, the API will auto-create the following group of service items:\n * IOFSIT - International origin 1st day SIT\n * IOASIT - International origin Additional day SIT\n * IOPSIT - International origin SIT pickup\n * IOSFSC - International origin SIT fuel surcharge\n\n**IOASIT**\n\n**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item.\nAdditional IOASIT service items can be created and added to an existing shipment that **includes a IOFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemInternationalDestSIT` + "`" + `**\n\nMTOServiceItemInternationalDestSIT is a subtype of MTOServiceItem.\n\nThis model type describes a international destination SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**IDFSIT**\n\n**1st day destination SIT service item**.\n\nThese additional fields are optional for creating a IDFSIT:\n * ` + "`" + `firstAvailableDeliveryDate1` + "`" + `\n * string \u003cdate\u003e\n * First available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together\n * ` + "`" + `dateOfContact1` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `\n * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `timeMilitary1` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.\n * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `firstAvailableDeliveryDate2` + "`" + `\n * string \u003cdate\u003e\n * Second available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together\n * ` + "`" + `dateOfContact2` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact delivery by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `\n * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together\n * ` + "`" + `timeMilitary2` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.\n * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together\n\nWhen a IDFSIT is requested, the API will auto-create the following group of service items:\n * IDFSIT - International destination 1st day SIT\n * IDASIT - International destination Additional day SIT\n * IDDSIT - International destination SIT delivery\n * IDSFSC - International destination SIT fuel surcharge\n\n**NOTE** When providing the ` + "`" + `sitEntryDate` + "`" + ` value in the payload, please ensure that the date is not BEFORE\n` + "`" + `firstAvailableDeliveryDate1` + "`" + ` or ` + "`" + `firstAvailableDeliveryDate2` + "`" + `. If it is, you will receive an error response.\n\n**IDASIT**\n\n**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item.\nAdditional IDASIT service items can be created and added to an existing shipment that **includes a IDFSIT service item**.\n", "consumes": [ "application/json" ], @@ -393,7 +393,7 @@ func init() { }, "/mto-service-items/{mtoServiceItemID}": { "patch": { - "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT/Accessorial service items: This endpoint will handle the logic of changing the status of rejected SIT/Accessorial service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT/Accessorial service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n\nThe following Accessorial service items can be resubmitted following a rejection:\n- IOSHUT\n- IDSHUT\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT/Accessorial service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following service items allow you to update the Port that the shipment will use:\n- PODFSC (Port of Debarkation can be updated)\n- POEFSC (Port of Embarkation can be updated)\n\nAt a MINIMUM, the payload for updating the port should contain the reServiceCode (PODFSC or POEFSC), modelType (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the service item.\nPlease see the example payload below:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"id\": \"1ed224b6-c65e-4616-b88e-8304d26c9562\",\n \"modelType\": \"UpdateMTOServiceItemInternationalPortFSC\",\n \"portCode\": \"SEA\",\n \"reServiceCode\": \"POEFSC\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following crating/uncrating service items can be resubmitted following a rejection:\n- ICRT\n- IUCRT\n\nAt a MINIMUM, the payload for resubmitting a rejected crating/uncrating service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"item\": {\n \"length\": 10000,\n \"width\": 10000,\n \"height\": 10000\n },\n \"crate\": {\n \"length\": 20000,\n \"width\": 20000,\n \"height\": 20000\n },\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemCrating\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n", + "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT/Accessorial service items: This endpoint will handle the logic of changing the status of rejected SIT/Accessorial service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT/Accessorial service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n- IDASIT\n- IDDSIT\n- IDFSIT\n- IOASIT\n- IOPSIT\n- IOFSIT\n- IDSFSC\n- IOSFSC\n\nThe following Accessorial service items can be resubmitted following a rejection:\n- IOSHUT\n- IDSHUT\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT/Accessorial service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following service items allow you to update the Port that the shipment will use:\n- PODFSC (Port of Debarkation can be updated)\n- POEFSC (Port of Embarkation can be updated)\n\nAt a MINIMUM, the payload for updating the port should contain the reServiceCode (PODFSC or POEFSC), modelType (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the service item.\nPlease see the example payload below:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"id\": \"1ed224b6-c65e-4616-b88e-8304d26c9562\",\n \"modelType\": \"UpdateMTOServiceItemInternationalPortFSC\",\n \"portCode\": \"SEA\",\n \"reServiceCode\": \"POEFSC\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following crating/uncrating service items can be resubmitted following a rejection:\n- ICRT\n- IUCRT\n\nAt a MINIMUM, the payload for resubmitting a rejected crating/uncrating service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"item\": {\n \"length\": 10000,\n \"width\": 10000,\n \"height\": 10000\n },\n \"crate\": {\n \"length\": 20000,\n \"width\": 20000,\n \"height\": 20000\n },\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemCrating\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n", "consumes": [ "application/json" ], @@ -2484,6 +2484,102 @@ func init() { } ] }, + "MTOServiceItemInternationalDestSIT": { + "description": "Describes a international destination SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "sitEntryDate", + "reason" + ], + "properties": { + "dateOfContact1": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "dateOfContact2": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate1": { + "description": "First available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate2": { + "description": "Second available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IDFSIT", + "IDASIT" + ] + }, + "reason": { + "description": "The reason item has been placed in SIT.\n", + "type": "string", + "x-nullable": true, + "x-omitempty": false + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDestinationFinalAddress": { + "$ref": "#/definitions/Address" + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "timeMilitary1": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + }, + "timeMilitary2": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + } + } + } + ] + }, "MTOServiceItemInternationalFuelSurcharge": { "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", "allOf": [ @@ -2509,6 +2605,76 @@ func init() { } ] }, + "MTOServiceItemInternationalOriginSIT": { + "description": "Describes a international origin SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "reason", + "sitPostalCode", + "sitEntryDate" + ], + "properties": { + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IOFSIT", + "IOASIT" + ] + }, + "reason": { + "description": "Explanation of why Prime is picking up SIT item.", + "type": "string", + "example": "Storage items need to be picked up" + }, + "requestApprovalsRequestedStatus": { + "type": "boolean" + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitHHGActualOrigin": { + "$ref": "#/definitions/Address" + }, + "sitHHGOriginalOrigin": { + "$ref": "#/definitions/Address" + }, + "sitPostalCode": { + "type": "string", + "format": "zip", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "90210" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + } + } + } + ] + }, "MTOServiceItemInternationalShuttle": { "description": "Describes an international shuttle service item.", "allOf": [ @@ -2568,12 +2734,14 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT\n * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", "MTOServiceItemOriginSIT", "MTOServiceItemDestSIT", + "MTOServiceItemInternationalOriginSIT", + "MTOServiceItemInternationalDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticShuttle", "MTOServiceItemInternationalShuttle", @@ -3888,7 +4056,7 @@ func init() { "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" }, "params": { - "description": "This should be populated for the following service items:\n * DOASIT(Domestic origin Additional day SIT)\n * DDASIT(Domestic destination Additional day SIT)\n\nBoth take in the following param keys:\n * ` + "`" + `SITPaymentRequestStart` + "`" + `\n * ` + "`" + `SITPaymentRequestEnd` + "`" + `\n\nThe value of each is a date string in the format \"YYYY-MM-DD\" (e.g. \"2023-01-15\")\n", + "description": "This should be populated for the following service items:\n * DOASIT(Domestic origin Additional day SIT)\n * DDASIT(Domestic destination Additional day SIT)\n * IOASIT(International origin Additional day SIT)\n * IDASIT(International destination Additional day SIT)\n\nBoth take in the following param keys:\n * ` + "`" + `SITPaymentRequestStart` + "`" + `\n * ` + "`" + `SITPaymentRequestEnd` + "`" + `\n\nThe value of each is a date string in the format \"YYYY-MM-DD\" (e.g. \"2023-01-15\")\n", "type": "array", "items": { "type": "object", @@ -4282,7 +4450,7 @@ func init() { ] }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * PODFSC - UpdateMTOServiceItemInternationalPortFSC\n * POEFSC - UpdateMTOServiceItemInternationalPortFSC\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n * ICRT - UpdateMTOServiceItemCrating\n * IUCRT - UpdateMTOServiceItemCrating\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * IDDSIT - UpdateMTOServiceItemSIT\n * IDFSIT - UpdateMTOServiceItemSIT\n * IDASIT - UpdateMTOServiceItemSIT\n * IOPSIT - UpdateMTOServiceItemSIT\n * IOASIT - UpdateMTOServiceItemSIT\n * IOFSIT - UpdateMTOServiceItemSIT\n * IOSFSC - UpdateMTOServiceItemSIT\n * IDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * PODFSC - UpdateMTOServiceItemInternationalPortFSC\n * POEFSC - UpdateMTOServiceItemInternationalPortFSC\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n * ICRT - UpdateMTOServiceItemCrating\n * IUCRT - UpdateMTOServiceItemCrating\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", @@ -4336,7 +4504,15 @@ func init() { "DOPSIT", "DOASIT", "DOFSIT", - "DOSFSC" + "DOSFSC", + "IDDSIT", + "IDASIT", + "IDFSIT", + "IDSFSC", + "IOPSIT", + "IOASIT", + "IOFSIT", + "IOSFSC" ] }, "requestApprovalsRequestedStatus": { @@ -5419,7 +5595,7 @@ func init() { }, "/mto-service-items": { "post": { - "description": "Creates one or more MTOServiceItems. Not all service items may be created, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to create and the documentation will update with the new definition.\n\nUpon creation these items are associated with a Move Task Order and an MTO Shipment.\nThe request must include UUIDs for the MTO and MTO Shipment connected to this service item. Some service item types require\nadditional service items to be autogenerated when added - all created service items, autogenerated included,\nwill be returned in the response.\n\nTo update a service item, please use [updateMTOServiceItem](#operation/updateMTOServiceItem) endpoint.\n\n---\n\n**` + "`" + `MTOServiceItemOriginSIT` + "`" + `**\n\nMTOServiceItemOriginSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic origin SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DOFSIT**\n\n**1st day origin SIT service item**. When a DOFSIT is requested, the API will auto-create the following group of service items:\n * DOFSIT - Domestic origin 1st day SIT\n * DOASIT - Domestic origin Additional day SIT\n * DOPSIT - Domestic origin SIT pickup\n * DOSFSC - Domestic origin SIT fuel surcharge\n\n**DOASIT**\n\n**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item.\nAdditional DOASIT service items can be created and added to an existing shipment that **includes a DOFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemDestSIT` + "`" + `**\n\nMTOServiceItemDestSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic destination SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DDFSIT**\n\n**1st day destination SIT service item**.\n\nThese additional fields are optional for creating a DDFSIT:\n * ` + "`" + `firstAvailableDeliveryDate1` + "`" + `\n * string \u003cdate\u003e\n * First available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together\n * ` + "`" + `dateOfContact1` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `\n * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `timeMilitary1` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.\n * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `firstAvailableDeliveryDate2` + "`" + `\n * string \u003cdate\u003e\n * Second available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together\n * ` + "`" + `dateOfContact2` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact delivery by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `\n * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together\n * ` + "`" + `timeMilitary2` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.\n * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together\n\nWhen a DDFSIT is requested, the API will auto-create the following group of service items:\n * DDFSIT - Domestic destination 1st day SIT\n * DDASIT - Domestic destination Additional day SIT\n * DDDSIT - Domestic destination SIT delivery\n * DDSFSC - Domestic destination SIT fuel surcharge\n\n**NOTE** When providing the ` + "`" + `sitEntryDate` + "`" + ` value in the payload, please ensure that the date is not BEFORE\n` + "`" + `firstAvailableDeliveryDate1` + "`" + ` or ` + "`" + `firstAvailableDeliveryDate2` + "`" + `. If it is, you will receive an error response.\n\n**DDASIT**\n\n**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item.\nAdditional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**.\n", + "description": "Creates one or more MTOServiceItems. Not all service items may be created, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to create and the documentation will update with the new definition.\n\nUpon creation these items are associated with a Move Task Order and an MTO Shipment.\nThe request must include UUIDs for the MTO and MTO Shipment connected to this service item. Some service item types require\nadditional service items to be autogenerated when added - all created service items, autogenerated included,\nwill be returned in the response.\n\nTo update a service item, please use [updateMTOServiceItem](#operation/updateMTOServiceItem) endpoint.\n\n---\n\n**` + "`" + `MTOServiceItemOriginSIT` + "`" + `**\n\nMTOServiceItemOriginSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic origin SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DOFSIT**\n\n**1st day origin SIT service item**. When a DOFSIT is requested, the API will auto-create the following group of service items:\n * DOFSIT - Domestic origin 1st day SIT\n * DOASIT - Domestic origin Additional day SIT\n * DOPSIT - Domestic origin SIT pickup\n * DOSFSC - Domestic origin SIT fuel surcharge\n\n**DOASIT**\n\n**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item.\nAdditional DOASIT service items can be created and added to an existing shipment that **includes a DOFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemDestSIT` + "`" + `**\n\nMTOServiceItemDestSIT is a subtype of MTOServiceItem.\n\nThis model type describes a domestic destination SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**DDFSIT**\n\n**1st day destination SIT service item**.\n\nThese additional fields are optional for creating a DDFSIT:\n * ` + "`" + `firstAvailableDeliveryDate1` + "`" + `\n * string \u003cdate\u003e\n * First available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together\n * ` + "`" + `dateOfContact1` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `\n * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `timeMilitary1` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.\n * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `firstAvailableDeliveryDate2` + "`" + `\n * string \u003cdate\u003e\n * Second available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together\n * ` + "`" + `dateOfContact2` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact delivery by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `\n * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together\n * ` + "`" + `timeMilitary2` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.\n * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together\n\nWhen a DDFSIT is requested, the API will auto-create the following group of service items:\n * DDFSIT - Domestic destination 1st day SIT\n * DDASIT - Domestic destination Additional day SIT\n * DDDSIT - Domestic destination SIT delivery\n * DDSFSC - Domestic destination SIT fuel surcharge\n\n**NOTE** When providing the ` + "`" + `sitEntryDate` + "`" + ` value in the payload, please ensure that the date is not BEFORE\n` + "`" + `firstAvailableDeliveryDate1` + "`" + ` or ` + "`" + `firstAvailableDeliveryDate2` + "`" + `. If it is, you will receive an error response.\n\n**DDASIT**\n\n**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item.\nAdditional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemInternationalOriginSIT` + "`" + `**\n\nMTOServiceItemInternationalOriginSIT is a subtype of MTOServiceItem.\n\nThis model type describes a international origin SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**IOFSIT**\n\n**1st day origin SIT service item**. When a IOFSIT is requested, the API will auto-create the following group of service items:\n * IOFSIT - International origin 1st day SIT\n * IOASIT - International origin Additional day SIT\n * IOPSIT - International origin SIT pickup\n * IOSFSC - International origin SIT fuel surcharge\n\n**IOASIT**\n\n**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item.\nAdditional IOASIT service items can be created and added to an existing shipment that **includes a IOFSIT service item**.\n\n---\n\n**` + "`" + `MTOServiceItemInternationalDestSIT` + "`" + `**\n\nMTOServiceItemInternationalDestSIT is a subtype of MTOServiceItem.\n\nThis model type describes a international destination SIT service item. Items can be created using this\nmodel type with the following codes:\n\n**IDFSIT**\n\n**1st day destination SIT service item**.\n\nThese additional fields are optional for creating a IDFSIT:\n * ` + "`" + `firstAvailableDeliveryDate1` + "`" + `\n * string \u003cdate\u003e\n * First available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together\n * ` + "`" + `dateOfContact1` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `\n * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `timeMilitary1` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.\n * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together\n * ` + "`" + `firstAvailableDeliveryDate2` + "`" + `\n * string \u003cdate\u003e\n * Second available date that Prime can deliver SIT service item.\n * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together\n * ` + "`" + `dateOfContact2` + "`" + `\n * string \u003cdate\u003e\n * Date of attempted contact delivery by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `\n * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together\n * ` + "`" + `timeMilitary2` + "`" + `\n * string\\d{4}Z\n * Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.\n * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together\n\nWhen a IDFSIT is requested, the API will auto-create the following group of service items:\n * IDFSIT - International destination 1st day SIT\n * IDASIT - International destination Additional day SIT\n * IDDSIT - International destination SIT delivery\n * IDSFSC - International destination SIT fuel surcharge\n\n**NOTE** When providing the ` + "`" + `sitEntryDate` + "`" + ` value in the payload, please ensure that the date is not BEFORE\n` + "`" + `firstAvailableDeliveryDate1` + "`" + ` or ` + "`" + `firstAvailableDeliveryDate2` + "`" + `. If it is, you will receive an error response.\n\n**IDASIT**\n\n**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item.\nAdditional IDASIT service items can be created and added to an existing shipment that **includes a IDFSIT service item**.\n", "consumes": [ "application/json" ], @@ -5497,7 +5673,7 @@ func init() { }, "/mto-service-items/{mtoServiceItemID}": { "patch": { - "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT/Accessorial service items: This endpoint will handle the logic of changing the status of rejected SIT/Accessorial service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT/Accessorial service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n\nThe following Accessorial service items can be resubmitted following a rejection:\n- IOSHUT\n- IDSHUT\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT/Accessorial service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following service items allow you to update the Port that the shipment will use:\n- PODFSC (Port of Debarkation can be updated)\n- POEFSC (Port of Embarkation can be updated)\n\nAt a MINIMUM, the payload for updating the port should contain the reServiceCode (PODFSC or POEFSC), modelType (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the service item.\nPlease see the example payload below:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"id\": \"1ed224b6-c65e-4616-b88e-8304d26c9562\",\n \"modelType\": \"UpdateMTOServiceItemInternationalPortFSC\",\n \"portCode\": \"SEA\",\n \"reServiceCode\": \"POEFSC\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following crating/uncrating service items can be resubmitted following a rejection:\n- ICRT\n- IUCRT\n\nAt a MINIMUM, the payload for resubmitting a rejected crating/uncrating service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"item\": {\n \"length\": 10000,\n \"width\": 10000,\n \"height\": 10000\n },\n \"crate\": {\n \"length\": 20000,\n \"width\": 20000,\n \"height\": 20000\n },\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemCrating\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n", + "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT/Accessorial service items: This endpoint will handle the logic of changing the status of rejected SIT/Accessorial service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT/Accessorial service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n- IDASIT\n- IDDSIT\n- IDFSIT\n- IOASIT\n- IOPSIT\n- IOFSIT\n- IDSFSC\n- IOSFSC\n\nThe following Accessorial service items can be resubmitted following a rejection:\n- IOSHUT\n- IDSHUT\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT/Accessorial service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following service items allow you to update the Port that the shipment will use:\n- PODFSC (Port of Debarkation can be updated)\n- POEFSC (Port of Embarkation can be updated)\n\nAt a MINIMUM, the payload for updating the port should contain the reServiceCode (PODFSC or POEFSC), modelType (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the service item.\nPlease see the example payload below:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"id\": \"1ed224b6-c65e-4616-b88e-8304d26c9562\",\n \"modelType\": \"UpdateMTOServiceItemInternationalPortFSC\",\n \"portCode\": \"SEA\",\n \"reServiceCode\": \"POEFSC\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following crating/uncrating service items can be resubmitted following a rejection:\n- ICRT\n- IUCRT\n\nAt a MINIMUM, the payload for resubmitting a rejected crating/uncrating service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"item\": {\n \"length\": 10000,\n \"width\": 10000,\n \"height\": 10000\n },\n \"crate\": {\n \"length\": 20000,\n \"width\": 20000,\n \"height\": 20000\n },\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemCrating\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n", "consumes": [ "application/json" ], @@ -7863,6 +8039,102 @@ func init() { } ] }, + "MTOServiceItemInternationalDestSIT": { + "description": "Describes a international destination SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "sitEntryDate", + "reason" + ], + "properties": { + "dateOfContact1": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "dateOfContact2": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate1": { + "description": "First available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate2": { + "description": "Second available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IDFSIT", + "IDASIT" + ] + }, + "reason": { + "description": "The reason item has been placed in SIT.\n", + "type": "string", + "x-nullable": true, + "x-omitempty": false + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDestinationFinalAddress": { + "$ref": "#/definitions/Address" + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "timeMilitary1": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + }, + "timeMilitary2": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + } + } + } + ] + }, "MTOServiceItemInternationalFuelSurcharge": { "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", "allOf": [ @@ -7888,6 +8160,76 @@ func init() { } ] }, + "MTOServiceItemInternationalOriginSIT": { + "description": "Describes a international origin SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "reason", + "sitPostalCode", + "sitEntryDate" + ], + "properties": { + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IOFSIT", + "IOASIT" + ] + }, + "reason": { + "description": "Explanation of why Prime is picking up SIT item.", + "type": "string", + "example": "Storage items need to be picked up" + }, + "requestApprovalsRequestedStatus": { + "type": "boolean" + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitHHGActualOrigin": { + "$ref": "#/definitions/Address" + }, + "sitHHGOriginalOrigin": { + "$ref": "#/definitions/Address" + }, + "sitPostalCode": { + "type": "string", + "format": "zip", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "90210" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + } + } + } + ] + }, "MTOServiceItemInternationalShuttle": { "description": "Describes an international shuttle service item.", "allOf": [ @@ -7947,12 +8289,14 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT\n * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", "MTOServiceItemOriginSIT", "MTOServiceItemDestSIT", + "MTOServiceItemInternationalOriginSIT", + "MTOServiceItemInternationalDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticShuttle", "MTOServiceItemInternationalShuttle", @@ -9267,7 +9611,7 @@ func init() { "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" }, "params": { - "description": "This should be populated for the following service items:\n * DOASIT(Domestic origin Additional day SIT)\n * DDASIT(Domestic destination Additional day SIT)\n\nBoth take in the following param keys:\n * ` + "`" + `SITPaymentRequestStart` + "`" + `\n * ` + "`" + `SITPaymentRequestEnd` + "`" + `\n\nThe value of each is a date string in the format \"YYYY-MM-DD\" (e.g. \"2023-01-15\")\n", + "description": "This should be populated for the following service items:\n * DOASIT(Domestic origin Additional day SIT)\n * DDASIT(Domestic destination Additional day SIT)\n * IOASIT(International origin Additional day SIT)\n * IDASIT(International destination Additional day SIT)\n\nBoth take in the following param keys:\n * ` + "`" + `SITPaymentRequestStart` + "`" + `\n * ` + "`" + `SITPaymentRequestEnd` + "`" + `\n\nThe value of each is a date string in the format \"YYYY-MM-DD\" (e.g. \"2023-01-15\")\n", "type": "array", "items": { "$ref": "#/definitions/ServiceItemParamsItems0" @@ -9666,7 +10010,7 @@ func init() { ] }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * PODFSC - UpdateMTOServiceItemInternationalPortFSC\n * POEFSC - UpdateMTOServiceItemInternationalPortFSC\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n * ICRT - UpdateMTOServiceItemCrating\n * IUCRT - UpdateMTOServiceItemCrating\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * IDDSIT - UpdateMTOServiceItemSIT\n * IDFSIT - UpdateMTOServiceItemSIT\n * IDASIT - UpdateMTOServiceItemSIT\n * IOPSIT - UpdateMTOServiceItemSIT\n * IOASIT - UpdateMTOServiceItemSIT\n * IOFSIT - UpdateMTOServiceItemSIT\n * IOSFSC - UpdateMTOServiceItemSIT\n * IDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * PODFSC - UpdateMTOServiceItemInternationalPortFSC\n * POEFSC - UpdateMTOServiceItemInternationalPortFSC\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n * ICRT - UpdateMTOServiceItemCrating\n * IUCRT - UpdateMTOServiceItemCrating\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", @@ -9720,7 +10064,15 @@ func init() { "DOPSIT", "DOASIT", "DOFSIT", - "DOSFSC" + "DOSFSC", + "IDDSIT", + "IDASIT", + "IDFSIT", + "IDSFSC", + "IOPSIT", + "IOASIT", + "IOFSIT", + "IOSFSC" ] }, "requestApprovalsRequestedStatus": { diff --git a/pkg/gen/primeapi/primeoperations/mto_service_item/create_m_t_o_service_item.go b/pkg/gen/primeapi/primeoperations/mto_service_item/create_m_t_o_service_item.go index 85456161f0c..88adde61f94 100644 --- a/pkg/gen/primeapi/primeoperations/mto_service_item/create_m_t_o_service_item.go +++ b/pkg/gen/primeapi/primeoperations/mto_service_item/create_m_t_o_service_item.go @@ -121,6 +121,81 @@ When a DDFSIT is requested, the API will auto-create the following group of serv **Addt'l days destination SIT service item**. This represents an additional day of storage for the same item. Additional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**. + +--- + +**`MTOServiceItemInternationalOriginSIT`** + +MTOServiceItemInternationalOriginSIT is a subtype of MTOServiceItem. + +This model type describes a international origin SIT service item. Items can be created using this +model type with the following codes: + +**IOFSIT** + +**1st day origin SIT service item**. When a IOFSIT is requested, the API will auto-create the following group of service items: + - IOFSIT - International origin 1st day SIT + - IOASIT - International origin Additional day SIT + - IOPSIT - International origin SIT pickup + - IOSFSC - International origin SIT fuel surcharge + +**IOASIT** + +**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item. +Additional IOASIT service items can be created and added to an existing shipment that **includes a IOFSIT service item**. + +--- + +**`MTOServiceItemInternationalDestSIT`** + +MTOServiceItemInternationalDestSIT is a subtype of MTOServiceItem. + +This model type describes a international destination SIT service item. Items can be created using this +model type with the following codes: + +**IDFSIT** + +**1st day destination SIT service item**. + +These additional fields are optional for creating a IDFSIT: + - `firstAvailableDeliveryDate1` + - string + - First available date that Prime can deliver SIT service item. + - firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together + - `dateOfContact1` + - string + - Date of attempted contact by the prime corresponding to `timeMilitary1` + - dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together + - `timeMilitary1` + - string\d{4}Z + - Time of attempted contact corresponding to `dateOfContact1`, in military format. + - timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together + - `firstAvailableDeliveryDate2` + - string + - Second available date that Prime can deliver SIT service item. + - firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together + - `dateOfContact2` + - string + - Date of attempted contact delivery by the prime corresponding to `timeMilitary2` + - dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together + - `timeMilitary2` + - string\d{4}Z + - Time of attempted contact corresponding to `dateOfContact2`, in military format. + - timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together + +When a IDFSIT is requested, the API will auto-create the following group of service items: + - IDFSIT - International destination 1st day SIT + - IDASIT - International destination Additional day SIT + - IDDSIT - International destination SIT delivery + - IDSFSC - International destination SIT fuel surcharge + +**NOTE** When providing the `sitEntryDate` value in the payload, please ensure that the date is not BEFORE +`firstAvailableDeliveryDate1` or `firstAvailableDeliveryDate2`. If it is, you will receive an error response. + +**IDASIT** + +**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item. +Additional IDASIT service items can be created and added to an existing shipment that **includes a IDFSIT service item**. */ type CreateMTOServiceItem struct { Context *middleware.Context diff --git a/pkg/gen/primeapi/primeoperations/mto_service_item/update_m_t_o_service_item.go b/pkg/gen/primeapi/primeoperations/mto_service_item/update_m_t_o_service_item.go index 884e2637045..c6215639acd 100644 --- a/pkg/gen/primeapi/primeoperations/mto_service_item/update_m_t_o_service_item.go +++ b/pkg/gen/primeapi/primeoperations/mto_service_item/update_m_t_o_service_item.go @@ -64,6 +64,14 @@ The following SIT service items can be resubmitted following a rejection: - DOFSIT - DDSFSC - DOSFSC +- IDASIT +- IDDSIT +- IDFSIT +- IOASIT +- IOPSIT +- IOFSIT +- IDSFSC +- IOSFSC The following Accessorial service items can be resubmitted following a rejection: - IOSHUT diff --git a/pkg/gen/primeclient/mto_service_item/mto_service_item_client.go b/pkg/gen/primeclient/mto_service_item/mto_service_item_client.go index 07040bad20e..af261a8501c 100644 --- a/pkg/gen/primeclient/mto_service_item/mto_service_item_client.go +++ b/pkg/gen/primeclient/mto_service_item/mto_service_item_client.go @@ -129,6 +129,81 @@ When a DDFSIT is requested, the API will auto-create the following group of serv **Addt'l days destination SIT service item**. This represents an additional day of storage for the same item. Additional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**. + +--- + +**`MTOServiceItemInternationalOriginSIT`** + +MTOServiceItemInternationalOriginSIT is a subtype of MTOServiceItem. + +This model type describes a international origin SIT service item. Items can be created using this +model type with the following codes: + +**IOFSIT** + +**1st day origin SIT service item**. When a IOFSIT is requested, the API will auto-create the following group of service items: + - IOFSIT - International origin 1st day SIT + - IOASIT - International origin Additional day SIT + - IOPSIT - International origin SIT pickup + - IOSFSC - International origin SIT fuel surcharge + +**IOASIT** + +**Addt'l days origin SIT service item**. This represents an additional day of storage for the same item. +Additional IOASIT service items can be created and added to an existing shipment that **includes a IOFSIT service item**. + +--- + +**`MTOServiceItemInternationalDestSIT`** + +MTOServiceItemInternationalDestSIT is a subtype of MTOServiceItem. + +This model type describes a international destination SIT service item. Items can be created using this +model type with the following codes: + +**IDFSIT** + +**1st day destination SIT service item**. + +These additional fields are optional for creating a IDFSIT: + - `firstAvailableDeliveryDate1` + - string + - First available date that Prime can deliver SIT service item. + - firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together + - `dateOfContact1` + - string + - Date of attempted contact by the prime corresponding to `timeMilitary1` + - dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together + - `timeMilitary1` + - string\d{4}Z + - Time of attempted contact corresponding to `dateOfContact1`, in military format. + - timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together + - `firstAvailableDeliveryDate2` + - string + - Second available date that Prime can deliver SIT service item. + - firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together + - `dateOfContact2` + - string + - Date of attempted contact delivery by the prime corresponding to `timeMilitary2` + - dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together + - `timeMilitary2` + - string\d{4}Z + - Time of attempted contact corresponding to `dateOfContact2`, in military format. + - timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together + +When a IDFSIT is requested, the API will auto-create the following group of service items: + - IDFSIT - International destination 1st day SIT + - IDASIT - International destination Additional day SIT + - IDDSIT - International destination SIT delivery + - IDSFSC - International destination SIT fuel surcharge + +**NOTE** When providing the `sitEntryDate` value in the payload, please ensure that the date is not BEFORE +`firstAvailableDeliveryDate1` or `firstAvailableDeliveryDate2`. If it is, you will receive an error response. + +**IDASIT** + +**Addt'l days destination SIT service item**. This represents an additional day of storage for the same item. +Additional IDASIT service items can be created and added to an existing shipment that **includes a IDFSIT service item**. */ func (a *Client) CreateMTOServiceItem(params *CreateMTOServiceItemParams, opts ...ClientOption) (*CreateMTOServiceItemOK, error) { // TODO: Validate the params before sending @@ -247,6 +322,14 @@ The following SIT service items can be resubmitted following a rejection: - DOFSIT - DDSFSC - DOSFSC +- IDASIT +- IDDSIT +- IDFSIT +- IOASIT +- IOPSIT +- IOFSIT +- IDSFSC +- IOSFSC The following Accessorial service items can be resubmitted following a rejection: - IOSHUT diff --git a/pkg/gen/primemessages/m_t_o_service_item.go b/pkg/gen/primemessages/m_t_o_service_item.go index 028e219d5df..568ee5954c6 100644 --- a/pkg/gen/primemessages/m_t_o_service_item.go +++ b/pkg/gen/primemessages/m_t_o_service_item.go @@ -285,12 +285,24 @@ func unmarshalMTOServiceItem(data []byte, consumer runtime.Consumer) (MTOService return nil, err } return &result, nil + case "MTOServiceItemInternationalDestSIT": + var result MTOServiceItemInternationalDestSIT + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil case "MTOServiceItemInternationalFuelSurcharge": var result MTOServiceItemInternationalFuelSurcharge if err := consumer.Consume(buf2, &result); err != nil { return nil, err } return &result, nil + case "MTOServiceItemInternationalOriginSIT": + var result MTOServiceItemInternationalOriginSIT + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil case "MTOServiceItemInternationalShuttle": var result MTOServiceItemInternationalShuttle if err := consumer.Consume(buf2, &result); err != nil { diff --git a/pkg/gen/primemessages/m_t_o_service_item_international_dest_s_i_t.go b/pkg/gen/primemessages/m_t_o_service_item_international_dest_s_i_t.go new file mode 100644 index 00000000000..07ab443e34d --- /dev/null +++ b/pkg/gen/primemessages/m_t_o_service_item_international_dest_s_i_t.go @@ -0,0 +1,987 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primemessages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalDestSIT Describes a international destination SIT service item. Subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalDestSIT +type MTOServiceItemInternationalDestSIT struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalDestSIT) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalDestSIT) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalDestSIT) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalDestSIT) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalDestSIT" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalDestSIT) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalDestSIT) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalDestSIT) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalDestSIT) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalDestSIT) UnmarshalJSON(raw []byte) error { + var data struct { + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalDestSIT + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.DateOfContact1 = data.DateOfContact1 + result.DateOfContact2 = data.DateOfContact2 + result.FirstAvailableDeliveryDate1 = data.FirstAvailableDeliveryDate1 + result.FirstAvailableDeliveryDate2 = data.FirstAvailableDeliveryDate2 + result.ReServiceCode = data.ReServiceCode + result.Reason = data.Reason + result.SitCustomerContacted = data.SitCustomerContacted + result.SitDepartureDate = data.SitDepartureDate + result.SitDestinationFinalAddress = data.SitDestinationFinalAddress + result.SitEntryDate = data.SitEntryDate + result.SitRequestedDelivery = data.SitRequestedDelivery + result.TimeMilitary1 = data.TimeMilitary1 + result.TimeMilitary2 = data.TimeMilitary2 + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalDestSIT) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` + }{ + + DateOfContact1: m.DateOfContact1, + + DateOfContact2: m.DateOfContact2, + + FirstAvailableDeliveryDate1: m.FirstAvailableDeliveryDate1, + + FirstAvailableDeliveryDate2: m.FirstAvailableDeliveryDate2, + + ReServiceCode: m.ReServiceCode, + + Reason: m.Reason, + + SitCustomerContacted: m.SitCustomerContacted, + + SitDepartureDate: m.SitDepartureDate, + + SitDestinationFinalAddress: m.SitDestinationFinalAddress, + + SitEntryDate: m.SitEntryDate, + + SitRequestedDelivery: m.SitRequestedDelivery, + + TimeMilitary1: m.TimeMilitary1, + + TimeMilitary2: m.TimeMilitary2, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international dest s i t +func (m *MTOServiceItemInternationalDestSIT) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateDateOfContact1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateDateOfContact2(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFirstAvailableDeliveryDate1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFirstAvailableDeliveryDate2(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReason(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitCustomerContacted(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDepartureDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDestinationFinalAddress(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitEntryDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitRequestedDelivery(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTimeMilitary1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTimeMilitary2(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateID(formats strfmt.Registry) error { + + if swag.IsZero(m.ID()) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateDateOfContact1(formats strfmt.Registry) error { + + if swag.IsZero(m.DateOfContact1) { // not required + return nil + } + + if err := validate.FormatOf("dateOfContact1", "body", "date", m.DateOfContact1.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateDateOfContact2(formats strfmt.Registry) error { + + if swag.IsZero(m.DateOfContact2) { // not required + return nil + } + + if err := validate.FormatOf("dateOfContact2", "body", "date", m.DateOfContact2.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateFirstAvailableDeliveryDate1(formats strfmt.Registry) error { + + if swag.IsZero(m.FirstAvailableDeliveryDate1) { // not required + return nil + } + + if err := validate.FormatOf("firstAvailableDeliveryDate1", "body", "date", m.FirstAvailableDeliveryDate1.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateFirstAvailableDeliveryDate2(formats strfmt.Registry) error { + + if swag.IsZero(m.FirstAvailableDeliveryDate2) { // not required + return nil + } + + if err := validate.FormatOf("firstAvailableDeliveryDate2", "body", "date", m.FirstAvailableDeliveryDate2.String(), formats); err != nil { + return err + } + + return nil +} + +var mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["IDFSIT","IDASIT"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum = append(mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalDestSIT) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateReServiceCode(formats strfmt.Registry) error { + + if err := validate.Required("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", *m.ReServiceCode); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateReason(formats strfmt.Registry) error { + + if err := validate.Required("reason", "body", m.Reason); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitCustomerContacted(formats strfmt.Registry) error { + + if swag.IsZero(m.SitCustomerContacted) { // not required + return nil + } + + if err := validate.FormatOf("sitCustomerContacted", "body", "date", m.SitCustomerContacted.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitDepartureDate(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDepartureDate) { // not required + return nil + } + + if err := validate.FormatOf("sitDepartureDate", "body", "date", m.SitDepartureDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitDestinationFinalAddress(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDestinationFinalAddress) { // not required + return nil + } + + if m.SitDestinationFinalAddress != nil { + if err := m.SitDestinationFinalAddress.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitDestinationFinalAddress") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitDestinationFinalAddress") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitEntryDate(formats strfmt.Registry) error { + + if err := validate.Required("sitEntryDate", "body", m.SitEntryDate); err != nil { + return err + } + + if err := validate.FormatOf("sitEntryDate", "body", "date", m.SitEntryDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitRequestedDelivery(formats strfmt.Registry) error { + + if swag.IsZero(m.SitRequestedDelivery) { // not required + return nil + } + + if err := validate.FormatOf("sitRequestedDelivery", "body", "date", m.SitRequestedDelivery.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateTimeMilitary1(formats strfmt.Registry) error { + + if swag.IsZero(m.TimeMilitary1) { // not required + return nil + } + + if err := validate.Pattern("timeMilitary1", "body", *m.TimeMilitary1, `\d{4}Z`); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateTimeMilitary2(formats strfmt.Registry) error { + + if swag.IsZero(m.TimeMilitary2) { // not required + return nil + } + + if err := validate.Pattern("timeMilitary2", "body", *m.TimeMilitary2, `\d{4}Z`); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international dest s i t based on the context it is used +func (m *MTOServiceItemInternationalDestSIT) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitDestinationFinalAddress(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateSitDestinationFinalAddress(ctx context.Context, formats strfmt.Registry) error { + + if m.SitDestinationFinalAddress != nil { + + if swag.IsZero(m.SitDestinationFinalAddress) { // not required + return nil + } + + if err := m.SitDestinationFinalAddress.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitDestinationFinalAddress") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitDestinationFinalAddress") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalDestSIT) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalDestSIT) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalDestSIT + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primemessages/m_t_o_service_item_international_origin_s_i_t.go b/pkg/gen/primemessages/m_t_o_service_item_international_origin_s_i_t.go new file mode 100644 index 00000000000..96392736360 --- /dev/null +++ b/pkg/gen/primemessages/m_t_o_service_item_international_origin_s_i_t.go @@ -0,0 +1,900 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primemessages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalOriginSIT Describes a international origin SIT service item. Subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalOriginSIT +type MTOServiceItemInternationalOriginSIT struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalOriginSIT" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalOriginSIT) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalOriginSIT) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalOriginSIT) UnmarshalJSON(raw []byte) error { + var data struct { + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalOriginSIT + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.ReServiceCode = data.ReServiceCode + result.Reason = data.Reason + result.RequestApprovalsRequestedStatus = data.RequestApprovalsRequestedStatus + result.SitCustomerContacted = data.SitCustomerContacted + result.SitDepartureDate = data.SitDepartureDate + result.SitEntryDate = data.SitEntryDate + result.SitHHGActualOrigin = data.SitHHGActualOrigin + result.SitHHGOriginalOrigin = data.SitHHGOriginalOrigin + result.SitPostalCode = data.SitPostalCode + result.SitRequestedDelivery = data.SitRequestedDelivery + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalOriginSIT) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + }{ + + ReServiceCode: m.ReServiceCode, + + Reason: m.Reason, + + RequestApprovalsRequestedStatus: m.RequestApprovalsRequestedStatus, + + SitCustomerContacted: m.SitCustomerContacted, + + SitDepartureDate: m.SitDepartureDate, + + SitEntryDate: m.SitEntryDate, + + SitHHGActualOrigin: m.SitHHGActualOrigin, + + SitHHGOriginalOrigin: m.SitHHGOriginalOrigin, + + SitPostalCode: m.SitPostalCode, + + SitRequestedDelivery: m.SitRequestedDelivery, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international origin s i t +func (m *MTOServiceItemInternationalOriginSIT) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReason(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitCustomerContacted(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDepartureDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitEntryDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitHHGActualOrigin(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitHHGOriginalOrigin(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitPostalCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitRequestedDelivery(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateID(formats strfmt.Registry) error { + + if swag.IsZero(m.ID()) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +var mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["IOFSIT","IOASIT"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum = append(mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalOriginSIT) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateReServiceCode(formats strfmt.Registry) error { + + if err := validate.Required("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", *m.ReServiceCode); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateReason(formats strfmt.Registry) error { + + if err := validate.Required("reason", "body", m.Reason); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitCustomerContacted(formats strfmt.Registry) error { + + if swag.IsZero(m.SitCustomerContacted) { // not required + return nil + } + + if err := validate.FormatOf("sitCustomerContacted", "body", "date", m.SitCustomerContacted.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitDepartureDate(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDepartureDate) { // not required + return nil + } + + if err := validate.FormatOf("sitDepartureDate", "body", "date", m.SitDepartureDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitEntryDate(formats strfmt.Registry) error { + + if err := validate.Required("sitEntryDate", "body", m.SitEntryDate); err != nil { + return err + } + + if err := validate.FormatOf("sitEntryDate", "body", "date", m.SitEntryDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitHHGActualOrigin(formats strfmt.Registry) error { + + if swag.IsZero(m.SitHHGActualOrigin) { // not required + return nil + } + + if m.SitHHGActualOrigin != nil { + if err := m.SitHHGActualOrigin.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGActualOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGActualOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitHHGOriginalOrigin(formats strfmt.Registry) error { + + if swag.IsZero(m.SitHHGOriginalOrigin) { // not required + return nil + } + + if m.SitHHGOriginalOrigin != nil { + if err := m.SitHHGOriginalOrigin.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGOriginalOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGOriginalOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitPostalCode(formats strfmt.Registry) error { + + if err := validate.Required("sitPostalCode", "body", m.SitPostalCode); err != nil { + return err + } + + if err := validate.Pattern("sitPostalCode", "body", *m.SitPostalCode, `^(\d{5}([\-]\d{4})?)$`); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitRequestedDelivery(formats strfmt.Registry) error { + + if swag.IsZero(m.SitRequestedDelivery) { // not required + return nil + } + + if err := validate.FormatOf("sitRequestedDelivery", "body", "date", m.SitRequestedDelivery.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international origin s i t based on the context it is used +func (m *MTOServiceItemInternationalOriginSIT) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitHHGActualOrigin(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitHHGOriginalOrigin(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateSitHHGActualOrigin(ctx context.Context, formats strfmt.Registry) error { + + if m.SitHHGActualOrigin != nil { + + if swag.IsZero(m.SitHHGActualOrigin) { // not required + return nil + } + + if err := m.SitHHGActualOrigin.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGActualOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGActualOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateSitHHGOriginalOrigin(ctx context.Context, formats strfmt.Registry) error { + + if m.SitHHGOriginalOrigin != nil { + + if swag.IsZero(m.SitHHGOriginalOrigin) { // not required + return nil + } + + if err := m.SitHHGOriginalOrigin.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGOriginalOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGOriginalOrigin") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalOriginSIT) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalOriginSIT) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalOriginSIT + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primemessages/m_t_o_service_item_model_type.go b/pkg/gen/primemessages/m_t_o_service_item_model_type.go index 3c494ac62f3..0e273fe2bd3 100644 --- a/pkg/gen/primemessages/m_t_o_service_item_model_type.go +++ b/pkg/gen/primemessages/m_t_o_service_item_model_type.go @@ -19,6 +19,8 @@ import ( // Using this list, choose the correct modelType in the dropdown, corresponding to the service item type. // - DOFSIT, DOASIT - MTOServiceItemOriginSIT // - DDFSIT, DDASIT - MTOServiceItemDestSIT +// - IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT +// - IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT // - DOSHUT, DDSHUT - MTOServiceItemShuttle // - DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle // - IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -51,6 +53,12 @@ const ( // MTOServiceItemModelTypeMTOServiceItemDestSIT captures enum value "MTOServiceItemDestSIT" MTOServiceItemModelTypeMTOServiceItemDestSIT MTOServiceItemModelType = "MTOServiceItemDestSIT" + // MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT captures enum value "MTOServiceItemInternationalOriginSIT" + MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT MTOServiceItemModelType = "MTOServiceItemInternationalOriginSIT" + + // MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT captures enum value "MTOServiceItemInternationalDestSIT" + MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT MTOServiceItemModelType = "MTOServiceItemInternationalDestSIT" + // MTOServiceItemModelTypeMTOServiceItemShuttle captures enum value "MTOServiceItemShuttle" MTOServiceItemModelTypeMTOServiceItemShuttle MTOServiceItemModelType = "MTOServiceItemShuttle" @@ -75,7 +83,7 @@ var mTOServiceItemModelTypeEnum []interface{} func init() { var res []MTOServiceItemModelType - if err := json.Unmarshal([]byte(`["MTOServiceItemBasic","MTOServiceItemOriginSIT","MTOServiceItemDestSIT","MTOServiceItemShuttle","MTOServiceItemDomesticShuttle","MTOServiceItemInternationalShuttle","MTOServiceItemDomesticCrating","MTOServiceItemInternationalCrating","MTOSerivceItemInternationalFuelSurcharge"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["MTOServiceItemBasic","MTOServiceItemOriginSIT","MTOServiceItemDestSIT","MTOServiceItemInternationalOriginSIT","MTOServiceItemInternationalDestSIT","MTOServiceItemShuttle","MTOServiceItemDomesticShuttle","MTOServiceItemInternationalShuttle","MTOServiceItemDomesticCrating","MTOServiceItemInternationalCrating","MTOSerivceItemInternationalFuelSurcharge"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primemessages/service_item.go b/pkg/gen/primemessages/service_item.go index 9f41d0b13e2..6c29dbc0d40 100644 --- a/pkg/gen/primemessages/service_item.go +++ b/pkg/gen/primemessages/service_item.go @@ -32,6 +32,8 @@ type ServiceItem struct { // This should be populated for the following service items: // * DOASIT(Domestic origin Additional day SIT) // * DDASIT(Domestic destination Additional day SIT) + // * IOASIT(International origin Additional day SIT) + // * IDASIT(International destination Additional day SIT) // // Both take in the following param keys: // * `SITPaymentRequestStart` diff --git a/pkg/gen/primemessages/update_m_t_o_service_item_model_type.go b/pkg/gen/primemessages/update_m_t_o_service_item_model_type.go index 24f9aa5707e..3a41327a34b 100644 --- a/pkg/gen/primemessages/update_m_t_o_service_item_model_type.go +++ b/pkg/gen/primemessages/update_m_t_o_service_item_model_type.go @@ -23,6 +23,14 @@ import ( // - DOFSIT - UpdateMTOServiceItemSIT // - DOSFSC - UpdateMTOServiceItemSIT // - DDSFSC - UpdateMTOServiceItemSIT +// - IDDSIT - UpdateMTOServiceItemSIT +// - IDFSIT - UpdateMTOServiceItemSIT +// - IDASIT - UpdateMTOServiceItemSIT +// - IOPSIT - UpdateMTOServiceItemSIT +// - IOASIT - UpdateMTOServiceItemSIT +// - IOFSIT - UpdateMTOServiceItemSIT +// - IOSFSC - UpdateMTOServiceItemSIT +// - IDSFSC - UpdateMTOServiceItemSIT // - DDSHUT - UpdateMTOServiceItemShuttle // - DOSHUT - UpdateMTOServiceItemShuttle // - PODFSC - UpdateMTOServiceItemInternationalPortFSC diff --git a/pkg/gen/primemessages/update_m_t_o_service_item_s_i_t.go b/pkg/gen/primemessages/update_m_t_o_service_item_s_i_t.go index 34fed36c1aa..5c76260ea6a 100644 --- a/pkg/gen/primemessages/update_m_t_o_service_item_s_i_t.go +++ b/pkg/gen/primemessages/update_m_t_o_service_item_s_i_t.go @@ -39,7 +39,7 @@ type UpdateMTOServiceItemSIT struct { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DDASIT DDFSIT DDSFSC DOPSIT DOASIT DOFSIT DOSFSC] + // Enum: [DDDSIT DDASIT DDFSIT DDSFSC DOPSIT DOASIT DOFSIT DOSFSC IDDSIT IDASIT IDFSIT IDSFSC IOPSIT IOASIT IOFSIT IOSFSC] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -123,7 +123,7 @@ func (m *UpdateMTOServiceItemSIT) UnmarshalJSON(raw []byte) error { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DDASIT DDFSIT DDSFSC DOPSIT DOASIT DOFSIT DOSFSC] + // Enum: [DDDSIT DDASIT DDFSIT DDSFSC DOPSIT DOASIT DOFSIT DOSFSC IDDSIT IDASIT IDFSIT IDSFSC IOPSIT IOASIT IOFSIT IOSFSC] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -242,7 +242,7 @@ func (m UpdateMTOServiceItemSIT) MarshalJSON() ([]byte, error) { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DDASIT DDFSIT DDSFSC DOPSIT DOASIT DOFSIT DOSFSC] + // Enum: [DDDSIT DDASIT DDFSIT DDSFSC DOPSIT DOASIT DOFSIT DOSFSC IDDSIT IDASIT IDFSIT IDSFSC IOPSIT IOASIT IOFSIT IOSFSC] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -471,7 +471,7 @@ var updateMTOServiceItemSITTypeReServiceCodePropEnum []interface{} func init() { var res []string - if err := json.Unmarshal([]byte(`["DDDSIT","DDASIT","DDFSIT","DDSFSC","DOPSIT","DOASIT","DOFSIT","DOSFSC"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["DDDSIT","DDASIT","DDFSIT","DDSFSC","DOPSIT","DOASIT","DOFSIT","DOSFSC","IDDSIT","IDASIT","IDFSIT","IDSFSC","IOPSIT","IOASIT","IOFSIT","IOSFSC"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primev2api/embedded_spec.go b/pkg/gen/primev2api/embedded_spec.go index 8a15212de76..85afde7f3e3 100644 --- a/pkg/gen/primev2api/embedded_spec.go +++ b/pkg/gen/primev2api/embedded_spec.go @@ -1551,6 +1551,172 @@ func init() { } ] }, + "MTOServiceItemInternationalDestSIT": { + "description": "Describes a international destination SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "sitEntryDate", + "reason" + ], + "properties": { + "dateOfContact1": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "dateOfContact2": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate1": { + "description": "First available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate2": { + "description": "Second available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IDFSIT", + "IDASIT" + ] + }, + "reason": { + "description": "The reason item has been placed in SIT.\n", + "type": "string", + "x-nullable": true, + "x-omitempty": false + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDestinationFinalAddress": { + "$ref": "#/definitions/Address" + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "timeMilitary1": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + }, + "timeMilitary2": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + } + } + } + ] + }, + "MTOServiceItemInternationalOriginSIT": { + "description": "Describes a international origin SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "reason", + "sitPostalCode", + "sitEntryDate" + ], + "properties": { + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IOFSIT", + "IOASIT" + ] + }, + "reason": { + "description": "Explanation of why Prime is picking up SIT item.", + "type": "string", + "example": "Storage items need to be picked up" + }, + "requestApprovalsRequestedStatus": { + "type": "boolean" + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitHHGActualOrigin": { + "$ref": "#/definitions/Address" + }, + "sitHHGOriginalOrigin": { + "$ref": "#/definitions/Address" + }, + "sitPostalCode": { + "type": "string", + "format": "zip", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "90210" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + } + } + } + ] + }, "MTOServiceItemInternationalShuttle": { "description": "Describes an international shuttle service item.", "allOf": [ @@ -1610,12 +1776,14 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT\n * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", "MTOServiceItemOriginSIT", "MTOServiceItemDestSIT", + "MTOServiceItemInternationalOriginSIT", + "MTOServiceItemInternationalDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticShuttle", "MTOServiceItemInternationalShuttle", @@ -3224,7 +3392,7 @@ func init() { ] }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * IDDSIT - UpdateMTOServiceItemSIT\n * IOPSIT - UpdateMTOServiceItemSIT\n * IOASIT - UpdateMTOServiceItemSIT\n * IOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", @@ -3272,7 +3440,11 @@ func init() { "DDDSIT", "DOPSIT", "DOASIT", - "DOFSIT" + "DOFSIT", + "IDDSIT", + "IOPSIT", + "IOASIT", + "IOFSIT" ] }, "requestApprovalsRequestedStatus": { @@ -5360,6 +5532,172 @@ func init() { } ] }, + "MTOServiceItemInternationalDestSIT": { + "description": "Describes a international destination SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "sitEntryDate", + "reason" + ], + "properties": { + "dateOfContact1": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "dateOfContact2": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate1": { + "description": "First available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate2": { + "description": "Second available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IDFSIT", + "IDASIT" + ] + }, + "reason": { + "description": "The reason item has been placed in SIT.\n", + "type": "string", + "x-nullable": true, + "x-omitempty": false + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDestinationFinalAddress": { + "$ref": "#/definitions/Address" + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "timeMilitary1": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + }, + "timeMilitary2": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + } + } + } + ] + }, + "MTOServiceItemInternationalOriginSIT": { + "description": "Describes a international origin SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "reason", + "sitPostalCode", + "sitEntryDate" + ], + "properties": { + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IOFSIT", + "IOASIT" + ] + }, + "reason": { + "description": "Explanation of why Prime is picking up SIT item.", + "type": "string", + "example": "Storage items need to be picked up" + }, + "requestApprovalsRequestedStatus": { + "type": "boolean" + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitHHGActualOrigin": { + "$ref": "#/definitions/Address" + }, + "sitHHGOriginalOrigin": { + "$ref": "#/definitions/Address" + }, + "sitPostalCode": { + "type": "string", + "format": "zip", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "90210" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + } + } + } + ] + }, "MTOServiceItemInternationalShuttle": { "description": "Describes an international shuttle service item.", "allOf": [ @@ -5419,12 +5757,14 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT\n * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", "MTOServiceItemOriginSIT", "MTOServiceItemDestSIT", + "MTOServiceItemInternationalOriginSIT", + "MTOServiceItemInternationalDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticShuttle", "MTOServiceItemInternationalShuttle", @@ -7035,7 +7375,7 @@ func init() { ] }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * IDDSIT - UpdateMTOServiceItemSIT\n * IOPSIT - UpdateMTOServiceItemSIT\n * IOASIT - UpdateMTOServiceItemSIT\n * IOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", @@ -7083,7 +7423,11 @@ func init() { "DDDSIT", "DOPSIT", "DOASIT", - "DOFSIT" + "DOFSIT", + "IDDSIT", + "IOPSIT", + "IOASIT", + "IOFSIT" ] }, "requestApprovalsRequestedStatus": { diff --git a/pkg/gen/primev2messages/m_t_o_service_item.go b/pkg/gen/primev2messages/m_t_o_service_item.go index c06f87e420c..1cd148dfd39 100644 --- a/pkg/gen/primev2messages/m_t_o_service_item.go +++ b/pkg/gen/primev2messages/m_t_o_service_item.go @@ -285,6 +285,18 @@ func unmarshalMTOServiceItem(data []byte, consumer runtime.Consumer) (MTOService return nil, err } return &result, nil + case "MTOServiceItemInternationalDestSIT": + var result MTOServiceItemInternationalDestSIT + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil + case "MTOServiceItemInternationalOriginSIT": + var result MTOServiceItemInternationalOriginSIT + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil case "MTOServiceItemInternationalShuttle": var result MTOServiceItemInternationalShuttle if err := consumer.Consume(buf2, &result); err != nil { diff --git a/pkg/gen/primev2messages/m_t_o_service_item_international_dest_s_i_t.go b/pkg/gen/primev2messages/m_t_o_service_item_international_dest_s_i_t.go new file mode 100644 index 00000000000..fb503d39a43 --- /dev/null +++ b/pkg/gen/primev2messages/m_t_o_service_item_international_dest_s_i_t.go @@ -0,0 +1,987 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primev2messages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalDestSIT Describes a international destination SIT service item. Subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalDestSIT +type MTOServiceItemInternationalDestSIT struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalDestSIT) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalDestSIT) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalDestSIT) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalDestSIT) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalDestSIT" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalDestSIT) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalDestSIT) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalDestSIT) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalDestSIT) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalDestSIT) UnmarshalJSON(raw []byte) error { + var data struct { + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalDestSIT + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.DateOfContact1 = data.DateOfContact1 + result.DateOfContact2 = data.DateOfContact2 + result.FirstAvailableDeliveryDate1 = data.FirstAvailableDeliveryDate1 + result.FirstAvailableDeliveryDate2 = data.FirstAvailableDeliveryDate2 + result.ReServiceCode = data.ReServiceCode + result.Reason = data.Reason + result.SitCustomerContacted = data.SitCustomerContacted + result.SitDepartureDate = data.SitDepartureDate + result.SitDestinationFinalAddress = data.SitDestinationFinalAddress + result.SitEntryDate = data.SitEntryDate + result.SitRequestedDelivery = data.SitRequestedDelivery + result.TimeMilitary1 = data.TimeMilitary1 + result.TimeMilitary2 = data.TimeMilitary2 + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalDestSIT) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` + }{ + + DateOfContact1: m.DateOfContact1, + + DateOfContact2: m.DateOfContact2, + + FirstAvailableDeliveryDate1: m.FirstAvailableDeliveryDate1, + + FirstAvailableDeliveryDate2: m.FirstAvailableDeliveryDate2, + + ReServiceCode: m.ReServiceCode, + + Reason: m.Reason, + + SitCustomerContacted: m.SitCustomerContacted, + + SitDepartureDate: m.SitDepartureDate, + + SitDestinationFinalAddress: m.SitDestinationFinalAddress, + + SitEntryDate: m.SitEntryDate, + + SitRequestedDelivery: m.SitRequestedDelivery, + + TimeMilitary1: m.TimeMilitary1, + + TimeMilitary2: m.TimeMilitary2, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international dest s i t +func (m *MTOServiceItemInternationalDestSIT) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateDateOfContact1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateDateOfContact2(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFirstAvailableDeliveryDate1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFirstAvailableDeliveryDate2(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReason(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitCustomerContacted(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDepartureDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDestinationFinalAddress(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitEntryDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitRequestedDelivery(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTimeMilitary1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTimeMilitary2(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateID(formats strfmt.Registry) error { + + if swag.IsZero(m.ID()) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateDateOfContact1(formats strfmt.Registry) error { + + if swag.IsZero(m.DateOfContact1) { // not required + return nil + } + + if err := validate.FormatOf("dateOfContact1", "body", "date", m.DateOfContact1.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateDateOfContact2(formats strfmt.Registry) error { + + if swag.IsZero(m.DateOfContact2) { // not required + return nil + } + + if err := validate.FormatOf("dateOfContact2", "body", "date", m.DateOfContact2.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateFirstAvailableDeliveryDate1(formats strfmt.Registry) error { + + if swag.IsZero(m.FirstAvailableDeliveryDate1) { // not required + return nil + } + + if err := validate.FormatOf("firstAvailableDeliveryDate1", "body", "date", m.FirstAvailableDeliveryDate1.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateFirstAvailableDeliveryDate2(formats strfmt.Registry) error { + + if swag.IsZero(m.FirstAvailableDeliveryDate2) { // not required + return nil + } + + if err := validate.FormatOf("firstAvailableDeliveryDate2", "body", "date", m.FirstAvailableDeliveryDate2.String(), formats); err != nil { + return err + } + + return nil +} + +var mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["IDFSIT","IDASIT"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum = append(mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalDestSIT) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateReServiceCode(formats strfmt.Registry) error { + + if err := validate.Required("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", *m.ReServiceCode); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateReason(formats strfmt.Registry) error { + + if err := validate.Required("reason", "body", m.Reason); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitCustomerContacted(formats strfmt.Registry) error { + + if swag.IsZero(m.SitCustomerContacted) { // not required + return nil + } + + if err := validate.FormatOf("sitCustomerContacted", "body", "date", m.SitCustomerContacted.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitDepartureDate(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDepartureDate) { // not required + return nil + } + + if err := validate.FormatOf("sitDepartureDate", "body", "date", m.SitDepartureDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitDestinationFinalAddress(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDestinationFinalAddress) { // not required + return nil + } + + if m.SitDestinationFinalAddress != nil { + if err := m.SitDestinationFinalAddress.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitDestinationFinalAddress") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitDestinationFinalAddress") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitEntryDate(formats strfmt.Registry) error { + + if err := validate.Required("sitEntryDate", "body", m.SitEntryDate); err != nil { + return err + } + + if err := validate.FormatOf("sitEntryDate", "body", "date", m.SitEntryDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitRequestedDelivery(formats strfmt.Registry) error { + + if swag.IsZero(m.SitRequestedDelivery) { // not required + return nil + } + + if err := validate.FormatOf("sitRequestedDelivery", "body", "date", m.SitRequestedDelivery.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateTimeMilitary1(formats strfmt.Registry) error { + + if swag.IsZero(m.TimeMilitary1) { // not required + return nil + } + + if err := validate.Pattern("timeMilitary1", "body", *m.TimeMilitary1, `\d{4}Z`); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateTimeMilitary2(formats strfmt.Registry) error { + + if swag.IsZero(m.TimeMilitary2) { // not required + return nil + } + + if err := validate.Pattern("timeMilitary2", "body", *m.TimeMilitary2, `\d{4}Z`); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international dest s i t based on the context it is used +func (m *MTOServiceItemInternationalDestSIT) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitDestinationFinalAddress(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateSitDestinationFinalAddress(ctx context.Context, formats strfmt.Registry) error { + + if m.SitDestinationFinalAddress != nil { + + if swag.IsZero(m.SitDestinationFinalAddress) { // not required + return nil + } + + if err := m.SitDestinationFinalAddress.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitDestinationFinalAddress") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitDestinationFinalAddress") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalDestSIT) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalDestSIT) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalDestSIT + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primev2messages/m_t_o_service_item_international_origin_s_i_t.go b/pkg/gen/primev2messages/m_t_o_service_item_international_origin_s_i_t.go new file mode 100644 index 00000000000..37e22af66af --- /dev/null +++ b/pkg/gen/primev2messages/m_t_o_service_item_international_origin_s_i_t.go @@ -0,0 +1,900 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primev2messages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalOriginSIT Describes a international origin SIT service item. Subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalOriginSIT +type MTOServiceItemInternationalOriginSIT struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalOriginSIT" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalOriginSIT) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalOriginSIT) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalOriginSIT) UnmarshalJSON(raw []byte) error { + var data struct { + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalOriginSIT + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.ReServiceCode = data.ReServiceCode + result.Reason = data.Reason + result.RequestApprovalsRequestedStatus = data.RequestApprovalsRequestedStatus + result.SitCustomerContacted = data.SitCustomerContacted + result.SitDepartureDate = data.SitDepartureDate + result.SitEntryDate = data.SitEntryDate + result.SitHHGActualOrigin = data.SitHHGActualOrigin + result.SitHHGOriginalOrigin = data.SitHHGOriginalOrigin + result.SitPostalCode = data.SitPostalCode + result.SitRequestedDelivery = data.SitRequestedDelivery + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalOriginSIT) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + }{ + + ReServiceCode: m.ReServiceCode, + + Reason: m.Reason, + + RequestApprovalsRequestedStatus: m.RequestApprovalsRequestedStatus, + + SitCustomerContacted: m.SitCustomerContacted, + + SitDepartureDate: m.SitDepartureDate, + + SitEntryDate: m.SitEntryDate, + + SitHHGActualOrigin: m.SitHHGActualOrigin, + + SitHHGOriginalOrigin: m.SitHHGOriginalOrigin, + + SitPostalCode: m.SitPostalCode, + + SitRequestedDelivery: m.SitRequestedDelivery, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international origin s i t +func (m *MTOServiceItemInternationalOriginSIT) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReason(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitCustomerContacted(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDepartureDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitEntryDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitHHGActualOrigin(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitHHGOriginalOrigin(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitPostalCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitRequestedDelivery(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateID(formats strfmt.Registry) error { + + if swag.IsZero(m.ID()) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +var mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["IOFSIT","IOASIT"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum = append(mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalOriginSIT) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateReServiceCode(formats strfmt.Registry) error { + + if err := validate.Required("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", *m.ReServiceCode); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateReason(formats strfmt.Registry) error { + + if err := validate.Required("reason", "body", m.Reason); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitCustomerContacted(formats strfmt.Registry) error { + + if swag.IsZero(m.SitCustomerContacted) { // not required + return nil + } + + if err := validate.FormatOf("sitCustomerContacted", "body", "date", m.SitCustomerContacted.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitDepartureDate(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDepartureDate) { // not required + return nil + } + + if err := validate.FormatOf("sitDepartureDate", "body", "date", m.SitDepartureDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitEntryDate(formats strfmt.Registry) error { + + if err := validate.Required("sitEntryDate", "body", m.SitEntryDate); err != nil { + return err + } + + if err := validate.FormatOf("sitEntryDate", "body", "date", m.SitEntryDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitHHGActualOrigin(formats strfmt.Registry) error { + + if swag.IsZero(m.SitHHGActualOrigin) { // not required + return nil + } + + if m.SitHHGActualOrigin != nil { + if err := m.SitHHGActualOrigin.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGActualOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGActualOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitHHGOriginalOrigin(formats strfmt.Registry) error { + + if swag.IsZero(m.SitHHGOriginalOrigin) { // not required + return nil + } + + if m.SitHHGOriginalOrigin != nil { + if err := m.SitHHGOriginalOrigin.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGOriginalOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGOriginalOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitPostalCode(formats strfmt.Registry) error { + + if err := validate.Required("sitPostalCode", "body", m.SitPostalCode); err != nil { + return err + } + + if err := validate.Pattern("sitPostalCode", "body", *m.SitPostalCode, `^(\d{5}([\-]\d{4})?)$`); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitRequestedDelivery(formats strfmt.Registry) error { + + if swag.IsZero(m.SitRequestedDelivery) { // not required + return nil + } + + if err := validate.FormatOf("sitRequestedDelivery", "body", "date", m.SitRequestedDelivery.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international origin s i t based on the context it is used +func (m *MTOServiceItemInternationalOriginSIT) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitHHGActualOrigin(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitHHGOriginalOrigin(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateSitHHGActualOrigin(ctx context.Context, formats strfmt.Registry) error { + + if m.SitHHGActualOrigin != nil { + + if swag.IsZero(m.SitHHGActualOrigin) { // not required + return nil + } + + if err := m.SitHHGActualOrigin.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGActualOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGActualOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateSitHHGOriginalOrigin(ctx context.Context, formats strfmt.Registry) error { + + if m.SitHHGOriginalOrigin != nil { + + if swag.IsZero(m.SitHHGOriginalOrigin) { // not required + return nil + } + + if err := m.SitHHGOriginalOrigin.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGOriginalOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGOriginalOrigin") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalOriginSIT) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalOriginSIT) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalOriginSIT + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primev2messages/m_t_o_service_item_model_type.go b/pkg/gen/primev2messages/m_t_o_service_item_model_type.go index 77247b78fe0..b443afec65b 100644 --- a/pkg/gen/primev2messages/m_t_o_service_item_model_type.go +++ b/pkg/gen/primev2messages/m_t_o_service_item_model_type.go @@ -19,6 +19,8 @@ import ( // Using this list, choose the correct modelType in the dropdown, corresponding to the service item type. // - DOFSIT, DOASIT - MTOServiceItemOriginSIT // - DDFSIT, DDASIT - MTOServiceItemDestSIT +// - IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT +// - IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT // - DOSHUT, DDSHUT - MTOServiceItemShuttle // - DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle // - IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -51,6 +53,12 @@ const ( // MTOServiceItemModelTypeMTOServiceItemDestSIT captures enum value "MTOServiceItemDestSIT" MTOServiceItemModelTypeMTOServiceItemDestSIT MTOServiceItemModelType = "MTOServiceItemDestSIT" + // MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT captures enum value "MTOServiceItemInternationalOriginSIT" + MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT MTOServiceItemModelType = "MTOServiceItemInternationalOriginSIT" + + // MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT captures enum value "MTOServiceItemInternationalDestSIT" + MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT MTOServiceItemModelType = "MTOServiceItemInternationalDestSIT" + // MTOServiceItemModelTypeMTOServiceItemShuttle captures enum value "MTOServiceItemShuttle" MTOServiceItemModelTypeMTOServiceItemShuttle MTOServiceItemModelType = "MTOServiceItemShuttle" @@ -75,7 +83,7 @@ var mTOServiceItemModelTypeEnum []interface{} func init() { var res []MTOServiceItemModelType - if err := json.Unmarshal([]byte(`["MTOServiceItemBasic","MTOServiceItemOriginSIT","MTOServiceItemDestSIT","MTOServiceItemShuttle","MTOServiceItemDomesticShuttle","MTOServiceItemInternationalShuttle","MTOServiceItemDomesticCrating","MTOServiceItemInternationalCrating","MTOSerivceItemInternationalFuelSurcharge"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["MTOServiceItemBasic","MTOServiceItemOriginSIT","MTOServiceItemDestSIT","MTOServiceItemInternationalOriginSIT","MTOServiceItemInternationalDestSIT","MTOServiceItemShuttle","MTOServiceItemDomesticShuttle","MTOServiceItemInternationalShuttle","MTOServiceItemDomesticCrating","MTOServiceItemInternationalCrating","MTOSerivceItemInternationalFuelSurcharge"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primev2messages/update_m_t_o_service_item_model_type.go b/pkg/gen/primev2messages/update_m_t_o_service_item_model_type.go index 8b865cfec1f..ce2195310c9 100644 --- a/pkg/gen/primev2messages/update_m_t_o_service_item_model_type.go +++ b/pkg/gen/primev2messages/update_m_t_o_service_item_model_type.go @@ -19,6 +19,10 @@ import ( // - DOPSIT - UpdateMTOServiceItemSIT // - DOASIT - UpdateMTOServiceItemSIT // - DOFSIT - UpdateMTOServiceItemSIT +// - IDDSIT - UpdateMTOServiceItemSIT +// - IOPSIT - UpdateMTOServiceItemSIT +// - IOASIT - UpdateMTOServiceItemSIT +// - IOFSIT - UpdateMTOServiceItemSIT // - DDSHUT - UpdateMTOServiceItemShuttle // - DOSHUT - UpdateMTOServiceItemShuttle // - IDSHUT - UpdateMTOServiceItemInternationalShuttle diff --git a/pkg/gen/primev2messages/update_m_t_o_service_item_s_i_t.go b/pkg/gen/primev2messages/update_m_t_o_service_item_s_i_t.go index 558e84ba19c..9accd54333f 100644 --- a/pkg/gen/primev2messages/update_m_t_o_service_item_s_i_t.go +++ b/pkg/gen/primev2messages/update_m_t_o_service_item_s_i_t.go @@ -39,7 +39,7 @@ type UpdateMTOServiceItemSIT struct { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DOPSIT DOASIT DOFSIT] + // Enum: [DDDSIT DOPSIT DOASIT DOFSIT IDDSIT IOPSIT IOASIT IOFSIT] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -123,7 +123,7 @@ func (m *UpdateMTOServiceItemSIT) UnmarshalJSON(raw []byte) error { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DOPSIT DOASIT DOFSIT] + // Enum: [DDDSIT DOPSIT DOASIT DOFSIT IDDSIT IOPSIT IOASIT IOFSIT] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -242,7 +242,7 @@ func (m UpdateMTOServiceItemSIT) MarshalJSON() ([]byte, error) { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DOPSIT DOASIT DOFSIT] + // Enum: [DDDSIT DOPSIT DOASIT DOFSIT IDDSIT IOPSIT IOASIT IOFSIT] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -471,7 +471,7 @@ var updateMTOServiceItemSITTypeReServiceCodePropEnum []interface{} func init() { var res []string - if err := json.Unmarshal([]byte(`["DDDSIT","DOPSIT","DOASIT","DOFSIT"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["DDDSIT","DOPSIT","DOASIT","DOFSIT","IDDSIT","IOPSIT","IOASIT","IOFSIT"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index b926e318a3e..582a95400fd 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -1713,6 +1713,102 @@ func init() { } ] }, + "MTOServiceItemInternationalDestSIT": { + "description": "Describes a international destination SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "sitEntryDate", + "reason" + ], + "properties": { + "dateOfContact1": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "dateOfContact2": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate1": { + "description": "First available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate2": { + "description": "Second available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IDFSIT", + "IDASIT" + ] + }, + "reason": { + "description": "The reason item has been placed in SIT.\n", + "type": "string", + "x-nullable": true, + "x-omitempty": false + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDestinationFinalAddress": { + "$ref": "#/definitions/Address" + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "timeMilitary1": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + }, + "timeMilitary2": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + } + } + } + ] + }, "MTOServiceItemInternationalFuelSurcharge": { "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", "allOf": [ @@ -1738,6 +1834,76 @@ func init() { } ] }, + "MTOServiceItemInternationalOriginSIT": { + "description": "Describes a international origin SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "reason", + "sitPostalCode", + "sitEntryDate" + ], + "properties": { + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IOFSIT", + "IOASIT" + ] + }, + "reason": { + "description": "Explanation of why Prime is picking up SIT item.", + "type": "string", + "example": "Storage items need to be picked up" + }, + "requestApprovalsRequestedStatus": { + "type": "boolean" + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitHHGActualOrigin": { + "$ref": "#/definitions/Address" + }, + "sitHHGOriginalOrigin": { + "$ref": "#/definitions/Address" + }, + "sitPostalCode": { + "type": "string", + "format": "zip", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "90210" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + } + } + } + ] + }, "MTOServiceItemInternationalShuttle": { "description": "Describes an international shuttle service item.", "allOf": [ @@ -1797,12 +1963,14 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT\n * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", "MTOServiceItemOriginSIT", "MTOServiceItemDestSIT", + "MTOServiceItemInternationalOriginSIT", + "MTOServiceItemInternationalDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticShuttle", "MTOServiceItemInternationalShuttle", @@ -3842,7 +4010,7 @@ func init() { ] }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * IDDSIT - UpdateMTOServiceItemSIT\n * IOPSIT - UpdateMTOServiceItemSIT\n * IOASIT - UpdateMTOServiceItemSIT\n * IOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", @@ -3890,7 +4058,11 @@ func init() { "DDDSIT", "DOPSIT", "DOASIT", - "DOFSIT" + "DOFSIT", + "IDDSIT", + "IOPSIT", + "IOASIT", + "IOFSIT" ] }, "requestApprovalsRequestedStatus": { @@ -6232,6 +6404,102 @@ func init() { } ] }, + "MTOServiceItemInternationalDestSIT": { + "description": "Describes a international destination SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "sitEntryDate", + "reason" + ], + "properties": { + "dateOfContact1": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary1` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "dateOfContact2": { + "description": "Date of attempted contact by the prime corresponding to ` + "`" + `timeMilitary2` + "`" + `.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate1": { + "description": "First available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "firstAvailableDeliveryDate2": { + "description": "Second available date that Prime can deliver SIT service item.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IDFSIT", + "IDASIT" + ] + }, + "reason": { + "description": "The reason item has been placed in SIT.\n", + "type": "string", + "x-nullable": true, + "x-omitempty": false + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDestinationFinalAddress": { + "$ref": "#/definitions/Address" + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "timeMilitary1": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact1` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + }, + "timeMilitary2": { + "description": "Time of attempted contact corresponding to ` + "`" + `dateOfContact2` + "`" + `, in military format.", + "type": "string", + "pattern": "\\d{4}Z", + "x-nullable": true, + "example": "1400Z" + } + } + } + ] + }, "MTOServiceItemInternationalFuelSurcharge": { "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", "allOf": [ @@ -6257,6 +6525,76 @@ func init() { } ] }, + "MTOServiceItemInternationalOriginSIT": { + "description": "Describes a international origin SIT service item. Subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "required": [ + "reServiceCode", + "reason", + "sitPostalCode", + "sitEntryDate" + ], + "properties": { + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "IOFSIT", + "IOASIT" + ] + }, + "reason": { + "description": "Explanation of why Prime is picking up SIT item.", + "type": "string", + "example": "Storage items need to be picked up" + }, + "requestApprovalsRequestedStatus": { + "type": "boolean" + }, + "sitCustomerContacted": { + "description": "Date when the customer contacted the prime for a delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitDepartureDate": { + "description": "Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date.", + "type": "string", + "format": "date", + "x-nullable": true + }, + "sitEntryDate": { + "description": "Entry date for the SIT", + "type": "string", + "format": "date" + }, + "sitHHGActualOrigin": { + "$ref": "#/definitions/Address" + }, + "sitHHGOriginalOrigin": { + "$ref": "#/definitions/Address" + }, + "sitPostalCode": { + "type": "string", + "format": "zip", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "90210" + }, + "sitRequestedDelivery": { + "description": "Date when the customer has requested delivery out of SIT.", + "type": "string", + "format": "date", + "x-nullable": true + } + } + } + ] + }, "MTOServiceItemInternationalShuttle": { "description": "Describes an international shuttle service item.", "allOf": [ @@ -6316,12 +6654,14 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT\n * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle\n * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", "MTOServiceItemOriginSIT", "MTOServiceItemDestSIT", + "MTOServiceItemInternationalOriginSIT", + "MTOServiceItemInternationalDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticShuttle", "MTOServiceItemInternationalShuttle", @@ -8363,7 +8703,7 @@ func init() { ] }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * IDDSIT - UpdateMTOServiceItemSIT\n * IOPSIT - UpdateMTOServiceItemSIT\n * IOASIT - UpdateMTOServiceItemSIT\n * IOFSIT - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * IDSHUT - UpdateMTOServiceItemInternationalShuttle\n * IOSHUT - UpdateMTOServiceItemInternationalShuttle\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", @@ -8411,7 +8751,11 @@ func init() { "DDDSIT", "DOPSIT", "DOASIT", - "DOFSIT" + "DOFSIT", + "IDDSIT", + "IOPSIT", + "IOASIT", + "IOFSIT" ] }, "requestApprovalsRequestedStatus": { diff --git a/pkg/gen/primev3messages/m_t_o_service_item.go b/pkg/gen/primev3messages/m_t_o_service_item.go index 06f0d63c776..93880d33231 100644 --- a/pkg/gen/primev3messages/m_t_o_service_item.go +++ b/pkg/gen/primev3messages/m_t_o_service_item.go @@ -285,12 +285,24 @@ func unmarshalMTOServiceItem(data []byte, consumer runtime.Consumer) (MTOService return nil, err } return &result, nil + case "MTOServiceItemInternationalDestSIT": + var result MTOServiceItemInternationalDestSIT + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil case "MTOServiceItemInternationalFuelSurcharge": var result MTOServiceItemInternationalFuelSurcharge if err := consumer.Consume(buf2, &result); err != nil { return nil, err } return &result, nil + case "MTOServiceItemInternationalOriginSIT": + var result MTOServiceItemInternationalOriginSIT + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil case "MTOServiceItemInternationalShuttle": var result MTOServiceItemInternationalShuttle if err := consumer.Consume(buf2, &result); err != nil { diff --git a/pkg/gen/primev3messages/m_t_o_service_item_international_dest_s_i_t.go b/pkg/gen/primev3messages/m_t_o_service_item_international_dest_s_i_t.go new file mode 100644 index 00000000000..cd60e27e3d1 --- /dev/null +++ b/pkg/gen/primev3messages/m_t_o_service_item_international_dest_s_i_t.go @@ -0,0 +1,987 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primev3messages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalDestSIT Describes a international destination SIT service item. Subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalDestSIT +type MTOServiceItemInternationalDestSIT struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalDestSIT) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalDestSIT) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalDestSIT) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalDestSIT) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalDestSIT" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalDestSIT) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalDestSIT) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalDestSIT) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalDestSIT) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalDestSIT) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalDestSIT) UnmarshalJSON(raw []byte) error { + var data struct { + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalDestSIT + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.DateOfContact1 = data.DateOfContact1 + result.DateOfContact2 = data.DateOfContact2 + result.FirstAvailableDeliveryDate1 = data.FirstAvailableDeliveryDate1 + result.FirstAvailableDeliveryDate2 = data.FirstAvailableDeliveryDate2 + result.ReServiceCode = data.ReServiceCode + result.Reason = data.Reason + result.SitCustomerContacted = data.SitCustomerContacted + result.SitDepartureDate = data.SitDepartureDate + result.SitDestinationFinalAddress = data.SitDestinationFinalAddress + result.SitEntryDate = data.SitEntryDate + result.SitRequestedDelivery = data.SitRequestedDelivery + result.TimeMilitary1 = data.TimeMilitary1 + result.TimeMilitary2 = data.TimeMilitary2 + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalDestSIT) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // Date of attempted contact by the prime corresponding to `timeMilitary1`. + // Format: date + DateOfContact1 *strfmt.Date `json:"dateOfContact1,omitempty"` + + // Date of attempted contact by the prime corresponding to `timeMilitary2`. + // Format: date + DateOfContact2 *strfmt.Date `json:"dateOfContact2,omitempty"` + + // First available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate1 *strfmt.Date `json:"firstAvailableDeliveryDate1,omitempty"` + + // Second available date that Prime can deliver SIT service item. + // Format: date + FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` + + // Service code allowed for this model type. + // Required: true + // Enum: [IDFSIT IDASIT] + ReServiceCode *string `json:"reServiceCode"` + + // The reason item has been placed in SIT. + // + // Required: true + Reason *string `json:"reason"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // sit destination final address + SitDestinationFinalAddress *Address `json:"sitDestinationFinalAddress,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact1`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary1 *string `json:"timeMilitary1,omitempty"` + + // Time of attempted contact corresponding to `dateOfContact2`, in military format. + // Example: 1400Z + // Pattern: \d{4}Z + TimeMilitary2 *string `json:"timeMilitary2,omitempty"` + }{ + + DateOfContact1: m.DateOfContact1, + + DateOfContact2: m.DateOfContact2, + + FirstAvailableDeliveryDate1: m.FirstAvailableDeliveryDate1, + + FirstAvailableDeliveryDate2: m.FirstAvailableDeliveryDate2, + + ReServiceCode: m.ReServiceCode, + + Reason: m.Reason, + + SitCustomerContacted: m.SitCustomerContacted, + + SitDepartureDate: m.SitDepartureDate, + + SitDestinationFinalAddress: m.SitDestinationFinalAddress, + + SitEntryDate: m.SitEntryDate, + + SitRequestedDelivery: m.SitRequestedDelivery, + + TimeMilitary1: m.TimeMilitary1, + + TimeMilitary2: m.TimeMilitary2, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international dest s i t +func (m *MTOServiceItemInternationalDestSIT) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateDateOfContact1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateDateOfContact2(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFirstAvailableDeliveryDate1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateFirstAvailableDeliveryDate2(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReason(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitCustomerContacted(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDepartureDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDestinationFinalAddress(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitEntryDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitRequestedDelivery(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTimeMilitary1(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTimeMilitary2(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateID(formats strfmt.Registry) error { + + if swag.IsZero(m.ID()) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateDateOfContact1(formats strfmt.Registry) error { + + if swag.IsZero(m.DateOfContact1) { // not required + return nil + } + + if err := validate.FormatOf("dateOfContact1", "body", "date", m.DateOfContact1.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateDateOfContact2(formats strfmt.Registry) error { + + if swag.IsZero(m.DateOfContact2) { // not required + return nil + } + + if err := validate.FormatOf("dateOfContact2", "body", "date", m.DateOfContact2.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateFirstAvailableDeliveryDate1(formats strfmt.Registry) error { + + if swag.IsZero(m.FirstAvailableDeliveryDate1) { // not required + return nil + } + + if err := validate.FormatOf("firstAvailableDeliveryDate1", "body", "date", m.FirstAvailableDeliveryDate1.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateFirstAvailableDeliveryDate2(formats strfmt.Registry) error { + + if swag.IsZero(m.FirstAvailableDeliveryDate2) { // not required + return nil + } + + if err := validate.FormatOf("firstAvailableDeliveryDate2", "body", "date", m.FirstAvailableDeliveryDate2.String(), formats); err != nil { + return err + } + + return nil +} + +var mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["IDFSIT","IDASIT"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum = append(mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalDestSIT) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalDestSITTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateReServiceCode(formats strfmt.Registry) error { + + if err := validate.Required("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", *m.ReServiceCode); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateReason(formats strfmt.Registry) error { + + if err := validate.Required("reason", "body", m.Reason); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitCustomerContacted(formats strfmt.Registry) error { + + if swag.IsZero(m.SitCustomerContacted) { // not required + return nil + } + + if err := validate.FormatOf("sitCustomerContacted", "body", "date", m.SitCustomerContacted.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitDepartureDate(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDepartureDate) { // not required + return nil + } + + if err := validate.FormatOf("sitDepartureDate", "body", "date", m.SitDepartureDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitDestinationFinalAddress(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDestinationFinalAddress) { // not required + return nil + } + + if m.SitDestinationFinalAddress != nil { + if err := m.SitDestinationFinalAddress.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitDestinationFinalAddress") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitDestinationFinalAddress") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitEntryDate(formats strfmt.Registry) error { + + if err := validate.Required("sitEntryDate", "body", m.SitEntryDate); err != nil { + return err + } + + if err := validate.FormatOf("sitEntryDate", "body", "date", m.SitEntryDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateSitRequestedDelivery(formats strfmt.Registry) error { + + if swag.IsZero(m.SitRequestedDelivery) { // not required + return nil + } + + if err := validate.FormatOf("sitRequestedDelivery", "body", "date", m.SitRequestedDelivery.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateTimeMilitary1(formats strfmt.Registry) error { + + if swag.IsZero(m.TimeMilitary1) { // not required + return nil + } + + if err := validate.Pattern("timeMilitary1", "body", *m.TimeMilitary1, `\d{4}Z`); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) validateTimeMilitary2(formats strfmt.Registry) error { + + if swag.IsZero(m.TimeMilitary2) { // not required + return nil + } + + if err := validate.Pattern("timeMilitary2", "body", *m.TimeMilitary2, `\d{4}Z`); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international dest s i t based on the context it is used +func (m *MTOServiceItemInternationalDestSIT) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitDestinationFinalAddress(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalDestSIT) contextValidateSitDestinationFinalAddress(ctx context.Context, formats strfmt.Registry) error { + + if m.SitDestinationFinalAddress != nil { + + if swag.IsZero(m.SitDestinationFinalAddress) { // not required + return nil + } + + if err := m.SitDestinationFinalAddress.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitDestinationFinalAddress") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitDestinationFinalAddress") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalDestSIT) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalDestSIT) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalDestSIT + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primev3messages/m_t_o_service_item_international_origin_s_i_t.go b/pkg/gen/primev3messages/m_t_o_service_item_international_origin_s_i_t.go new file mode 100644 index 00000000000..de349763f20 --- /dev/null +++ b/pkg/gen/primev3messages/m_t_o_service_item_international_origin_s_i_t.go @@ -0,0 +1,900 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primev3messages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalOriginSIT Describes a international origin SIT service item. Subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalOriginSIT +type MTOServiceItemInternationalOriginSIT struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalOriginSIT" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalOriginSIT) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalOriginSIT) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalOriginSIT) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalOriginSIT) UnmarshalJSON(raw []byte) error { + var data struct { + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalOriginSIT + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.ReServiceCode = data.ReServiceCode + result.Reason = data.Reason + result.RequestApprovalsRequestedStatus = data.RequestApprovalsRequestedStatus + result.SitCustomerContacted = data.SitCustomerContacted + result.SitDepartureDate = data.SitDepartureDate + result.SitEntryDate = data.SitEntryDate + result.SitHHGActualOrigin = data.SitHHGActualOrigin + result.SitHHGOriginalOrigin = data.SitHHGOriginalOrigin + result.SitPostalCode = data.SitPostalCode + result.SitRequestedDelivery = data.SitRequestedDelivery + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalOriginSIT) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // Service code allowed for this model type. + // Required: true + // Enum: [IOFSIT IOASIT] + ReServiceCode *string `json:"reServiceCode"` + + // Explanation of why Prime is picking up SIT item. + // Example: Storage items need to be picked up + // Required: true + Reason *string `json:"reason"` + + // request approvals requested status + RequestApprovalsRequestedStatus bool `json:"requestApprovalsRequestedStatus,omitempty"` + + // Date when the customer contacted the prime for a delivery out of SIT. + // Format: date + SitCustomerContacted *strfmt.Date `json:"sitCustomerContacted,omitempty"` + + // Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + // Format: date + SitDepartureDate *strfmt.Date `json:"sitDepartureDate,omitempty"` + + // Entry date for the SIT + // Required: true + // Format: date + SitEntryDate *strfmt.Date `json:"sitEntryDate"` + + // sit h h g actual origin + SitHHGActualOrigin *Address `json:"sitHHGActualOrigin,omitempty"` + + // sit h h g original origin + SitHHGOriginalOrigin *Address `json:"sitHHGOriginalOrigin,omitempty"` + + // sit postal code + // Example: 90210 + // Required: true + // Pattern: ^(\d{5}([\-]\d{4})?)$ + SitPostalCode *string `json:"sitPostalCode"` + + // Date when the customer has requested delivery out of SIT. + // Format: date + SitRequestedDelivery *strfmt.Date `json:"sitRequestedDelivery,omitempty"` + }{ + + ReServiceCode: m.ReServiceCode, + + Reason: m.Reason, + + RequestApprovalsRequestedStatus: m.RequestApprovalsRequestedStatus, + + SitCustomerContacted: m.SitCustomerContacted, + + SitDepartureDate: m.SitDepartureDate, + + SitEntryDate: m.SitEntryDate, + + SitHHGActualOrigin: m.SitHHGActualOrigin, + + SitHHGOriginalOrigin: m.SitHHGOriginalOrigin, + + SitPostalCode: m.SitPostalCode, + + SitRequestedDelivery: m.SitRequestedDelivery, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international origin s i t +func (m *MTOServiceItemInternationalOriginSIT) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReason(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitCustomerContacted(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitDepartureDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitEntryDate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitHHGActualOrigin(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitHHGOriginalOrigin(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitPostalCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSitRequestedDelivery(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateID(formats strfmt.Registry) error { + + if swag.IsZero(m.ID()) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +var mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["IOFSIT","IOASIT"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum = append(mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalOriginSIT) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalOriginSITTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateReServiceCode(formats strfmt.Registry) error { + + if err := validate.Required("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", *m.ReServiceCode); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateReason(formats strfmt.Registry) error { + + if err := validate.Required("reason", "body", m.Reason); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitCustomerContacted(formats strfmt.Registry) error { + + if swag.IsZero(m.SitCustomerContacted) { // not required + return nil + } + + if err := validate.FormatOf("sitCustomerContacted", "body", "date", m.SitCustomerContacted.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitDepartureDate(formats strfmt.Registry) error { + + if swag.IsZero(m.SitDepartureDate) { // not required + return nil + } + + if err := validate.FormatOf("sitDepartureDate", "body", "date", m.SitDepartureDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitEntryDate(formats strfmt.Registry) error { + + if err := validate.Required("sitEntryDate", "body", m.SitEntryDate); err != nil { + return err + } + + if err := validate.FormatOf("sitEntryDate", "body", "date", m.SitEntryDate.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitHHGActualOrigin(formats strfmt.Registry) error { + + if swag.IsZero(m.SitHHGActualOrigin) { // not required + return nil + } + + if m.SitHHGActualOrigin != nil { + if err := m.SitHHGActualOrigin.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGActualOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGActualOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitHHGOriginalOrigin(formats strfmt.Registry) error { + + if swag.IsZero(m.SitHHGOriginalOrigin) { // not required + return nil + } + + if m.SitHHGOriginalOrigin != nil { + if err := m.SitHHGOriginalOrigin.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGOriginalOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGOriginalOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitPostalCode(formats strfmt.Registry) error { + + if err := validate.Required("sitPostalCode", "body", m.SitPostalCode); err != nil { + return err + } + + if err := validate.Pattern("sitPostalCode", "body", *m.SitPostalCode, `^(\d{5}([\-]\d{4})?)$`); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) validateSitRequestedDelivery(formats strfmt.Registry) error { + + if swag.IsZero(m.SitRequestedDelivery) { // not required + return nil + } + + if err := validate.FormatOf("sitRequestedDelivery", "body", "date", m.SitRequestedDelivery.String(), formats); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international origin s i t based on the context it is used +func (m *MTOServiceItemInternationalOriginSIT) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitHHGActualOrigin(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSitHHGOriginalOrigin(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateSitHHGActualOrigin(ctx context.Context, formats strfmt.Registry) error { + + if m.SitHHGActualOrigin != nil { + + if swag.IsZero(m.SitHHGActualOrigin) { // not required + return nil + } + + if err := m.SitHHGActualOrigin.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGActualOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGActualOrigin") + } + return err + } + } + + return nil +} + +func (m *MTOServiceItemInternationalOriginSIT) contextValidateSitHHGOriginalOrigin(ctx context.Context, formats strfmt.Registry) error { + + if m.SitHHGOriginalOrigin != nil { + + if swag.IsZero(m.SitHHGOriginalOrigin) { // not required + return nil + } + + if err := m.SitHHGOriginalOrigin.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("sitHHGOriginalOrigin") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("sitHHGOriginalOrigin") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalOriginSIT) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalOriginSIT) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalOriginSIT + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primev3messages/m_t_o_service_item_model_type.go b/pkg/gen/primev3messages/m_t_o_service_item_model_type.go index 4dea531b524..7301906a417 100644 --- a/pkg/gen/primev3messages/m_t_o_service_item_model_type.go +++ b/pkg/gen/primev3messages/m_t_o_service_item_model_type.go @@ -19,6 +19,8 @@ import ( // Using this list, choose the correct modelType in the dropdown, corresponding to the service item type. // - DOFSIT, DOASIT - MTOServiceItemOriginSIT // - DDFSIT, DDASIT - MTOServiceItemDestSIT +// - IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT +// - IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT // - DOSHUT, DDSHUT - MTOServiceItemShuttle // - DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle // - IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -51,6 +53,12 @@ const ( // MTOServiceItemModelTypeMTOServiceItemDestSIT captures enum value "MTOServiceItemDestSIT" MTOServiceItemModelTypeMTOServiceItemDestSIT MTOServiceItemModelType = "MTOServiceItemDestSIT" + // MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT captures enum value "MTOServiceItemInternationalOriginSIT" + MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT MTOServiceItemModelType = "MTOServiceItemInternationalOriginSIT" + + // MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT captures enum value "MTOServiceItemInternationalDestSIT" + MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT MTOServiceItemModelType = "MTOServiceItemInternationalDestSIT" + // MTOServiceItemModelTypeMTOServiceItemShuttle captures enum value "MTOServiceItemShuttle" MTOServiceItemModelTypeMTOServiceItemShuttle MTOServiceItemModelType = "MTOServiceItemShuttle" @@ -75,7 +83,7 @@ var mTOServiceItemModelTypeEnum []interface{} func init() { var res []MTOServiceItemModelType - if err := json.Unmarshal([]byte(`["MTOServiceItemBasic","MTOServiceItemOriginSIT","MTOServiceItemDestSIT","MTOServiceItemShuttle","MTOServiceItemDomesticShuttle","MTOServiceItemInternationalShuttle","MTOServiceItemDomesticCrating","MTOServiceItemInternationalCrating","MTOSerivceItemInternationalFuelSurcharge"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["MTOServiceItemBasic","MTOServiceItemOriginSIT","MTOServiceItemDestSIT","MTOServiceItemInternationalOriginSIT","MTOServiceItemInternationalDestSIT","MTOServiceItemShuttle","MTOServiceItemDomesticShuttle","MTOServiceItemInternationalShuttle","MTOServiceItemDomesticCrating","MTOServiceItemInternationalCrating","MTOSerivceItemInternationalFuelSurcharge"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primev3messages/update_m_t_o_service_item_model_type.go b/pkg/gen/primev3messages/update_m_t_o_service_item_model_type.go index a1bc8152ec6..e1ad72b1e4e 100644 --- a/pkg/gen/primev3messages/update_m_t_o_service_item_model_type.go +++ b/pkg/gen/primev3messages/update_m_t_o_service_item_model_type.go @@ -19,6 +19,10 @@ import ( // - DOPSIT - UpdateMTOServiceItemSIT // - DOASIT - UpdateMTOServiceItemSIT // - DOFSIT - UpdateMTOServiceItemSIT +// - IDDSIT - UpdateMTOServiceItemSIT +// - IOPSIT - UpdateMTOServiceItemSIT +// - IOASIT - UpdateMTOServiceItemSIT +// - IOFSIT - UpdateMTOServiceItemSIT // - DDSHUT - UpdateMTOServiceItemShuttle // - DOSHUT - UpdateMTOServiceItemShuttle // - IDSHUT - UpdateMTOServiceItemInternationalShuttle diff --git a/pkg/gen/primev3messages/update_m_t_o_service_item_s_i_t.go b/pkg/gen/primev3messages/update_m_t_o_service_item_s_i_t.go index 7012106e91e..ea432a5d501 100644 --- a/pkg/gen/primev3messages/update_m_t_o_service_item_s_i_t.go +++ b/pkg/gen/primev3messages/update_m_t_o_service_item_s_i_t.go @@ -39,7 +39,7 @@ type UpdateMTOServiceItemSIT struct { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DOPSIT DOASIT DOFSIT] + // Enum: [DDDSIT DOPSIT DOASIT DOFSIT IDDSIT IOPSIT IOASIT IOFSIT] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -123,7 +123,7 @@ func (m *UpdateMTOServiceItemSIT) UnmarshalJSON(raw []byte) error { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DOPSIT DOASIT DOFSIT] + // Enum: [DDDSIT DOPSIT DOASIT DOFSIT IDDSIT IOPSIT IOASIT IOFSIT] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -242,7 +242,7 @@ func (m UpdateMTOServiceItemSIT) MarshalJSON() ([]byte, error) { FirstAvailableDeliveryDate2 *strfmt.Date `json:"firstAvailableDeliveryDate2,omitempty"` // Service code allowed for this model type. - // Enum: [DDDSIT DOPSIT DOASIT DOFSIT] + // Enum: [DDDSIT DOPSIT DOASIT DOFSIT IDDSIT IOPSIT IOASIT IOFSIT] ReServiceCode string `json:"reServiceCode,omitempty"` // Indicates if "Approvals Requested" status is being requested. @@ -471,7 +471,7 @@ var updateMTOServiceItemSITTypeReServiceCodePropEnum []interface{} func init() { var res []string - if err := json.Unmarshal([]byte(`["DDDSIT","DOPSIT","DOASIT","DOFSIT"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["DDDSIT","DOPSIT","DOASIT","DOFSIT","IDDSIT","IOPSIT","IOASIT","IOFSIT"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/handlers/adminapi/offices.go b/pkg/handlers/adminapi/offices.go index 5a189d7348e..c5f2aff5609 100644 --- a/pkg/handlers/adminapi/offices.go +++ b/pkg/handlers/adminapi/offices.go @@ -22,8 +22,6 @@ func payloadForOfficeModel(o models.TransportationOffice) *adminmessages.Transpo Address: payloadForAddressModel(&o.Address), Gbloc: o.Gbloc, PhoneLines: payloadForPhoneLines(o.PhoneLines), - Latitude: o.Latitude, - Longitude: o.Longitude, } } diff --git a/pkg/handlers/primeapi/mto_service_item.go b/pkg/handlers/primeapi/mto_service_item.go index c78f37b6950..577afccaa08 100644 --- a/pkg/handlers/primeapi/mto_service_item.go +++ b/pkg/handlers/primeapi/mto_service_item.go @@ -25,13 +25,14 @@ import ( // THIS WILL NEED TO BE UPDATED AS WE CONTINUE TO ADD MORE SERVICE ITEMS. // We will eventually remove this when all service items are added. var CreateableServiceItemMap = map[primemessages.MTOServiceItemModelType]bool{ - primemessages.MTOServiceItemModelTypeMTOServiceItemOriginSIT: true, - primemessages.MTOServiceItemModelTypeMTOServiceItemDestSIT: true, - primemessages.MTOServiceItemModelTypeMTOServiceItemShuttle: true, - primemessages.MTOServiceItemModelTypeMTOServiceItemDomesticShuttle: true, - primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalShuttle: true, - primemessages.MTOServiceItemModelTypeMTOServiceItemDomesticCrating: true, - primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalCrating: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemOriginSIT: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemDestSIT: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemDomesticShuttle: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalShuttle: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemDomesticCrating: true, + primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalCrating: true, } // CreateMTOServiceItemHandler is the handler to create MTO service items diff --git a/pkg/handlers/primeapi/mto_service_item_test.go b/pkg/handlers/primeapi/mto_service_item_test.go index 8f58d9a096b..68fe0b8e23b 100644 --- a/pkg/handlers/primeapi/mto_service_item_test.go +++ b/pkg/handlers/primeapi/mto_service_item_test.go @@ -43,7 +43,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { mtoServiceItem models.MTOServiceItem } - makeSubtestDataWithPPMShipmentType := func(isPPM bool) (subtestData *localSubtestData) { + makeSubtestDataWithPPMShipmentType := func(isPPM bool, isInternational bool) (subtestData *localSubtestData) { subtestData = &localSubtestData{} mtoShipmentID, _ := uuid.NewV4() @@ -62,15 +62,34 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { }, }, nil) } else { - subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ - { - Model: mto, - LinkOnly: true, - }, - }, nil) + if isInternational { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + }, nil) + } else { + subtestData.mtoShipment = factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: mto, + LinkOnly: true, + }, + }, nil) + } + } + + if isInternational { + factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeIOFSIT) + } else { + factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOFSIT) } - factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOFSIT) req := httptest.NewRequest("POST", "/mto-service-items", nil) sitEntryDate := time.Now() sitPostalCode := "00000" @@ -84,10 +103,16 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { // that we properly create the address coming in from the API. actualPickupAddress := factory.BuildAddress(nil, nil, []factory.Trait{factory.GetTraitAddress2}) + serviceCode := models.ReService{Code: models.ReServiceCodeDOFSIT} + + if isInternational { + serviceCode = models.ReService{Code: models.ReServiceCodeIOFSIT} + } + subtestData.mtoServiceItem = models.MTOServiceItem{ MoveTaskOrderID: mto.ID, MTOShipmentID: &subtestData.mtoShipment.ID, - ReService: models.ReService{Code: models.ReServiceCodeDOFSIT}, + ReService: serviceCode, Reason: models.StringPointer("lorem ipsum"), SITEntryDate: &sitEntryDate, SITPostalCode: &sitPostalCode, @@ -104,7 +129,11 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { } makeSubtestData := func() (subtestData *localSubtestData) { - return makeSubtestDataWithPPMShipmentType(false) + return makeSubtestDataWithPPMShipmentType(false, false) + } + + makeSubtestInternationalData := func() (subtestData *localSubtestData) { + return makeSubtestDataWithPPMShipmentType(false, true) } suite.Run("Successful POST - Integration Test", func() { @@ -143,6 +172,34 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { suite.NotZero(okResponse.Payload[0].ID()) }) + suite.Run("Successful POST International - Integration Test", func() { + subtestData := makeSubtestInternationalData() + moveRouter := moverouter.NewMoveRouter() + planner := &routemocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + false, + ).Return(400, nil) + creator := mtoserviceitem.NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + handler := CreateMTOServiceItemHandler{ + suite.HandlerConfig(), + creator, + mtoChecker, + } + + // Validate incoming payload + suite.NoError(subtestData.params.Body.Validate(strfmt.Default)) + + response := handler.Handle(subtestData.params) + suite.IsType(&mtoserviceitemops.CreateMTOServiceItemOK{}, response) + okResponse := response.(*mtoserviceitemops.CreateMTOServiceItemOK) + + suite.NotZero(okResponse.Payload[0].ID()) + }) + suite.Run("Successful POST for Creating Shuttling without PrimeEstimatedWeight set - Integration Test", func() { mto := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ @@ -200,7 +257,13 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { Model: mto, LinkOnly: true, }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, }, nil) + mtoShipment.PrimeEstimatedWeight = nil req := httptest.NewRequest("POST", "/mto-service-items", nil) reason := "lorem ipsum" @@ -502,7 +565,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { }) suite.Run("POST failure - Shipment fetch not found", func() { - subtestData := makeSubtestDataWithPPMShipmentType(true) + subtestData := makeSubtestDataWithPPMShipmentType(true, false) moveRouter := moverouter.NewMoveRouter() planner := &routemocks.Planner{} planner.On("ZipTransitDistance", @@ -534,7 +597,7 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { }) suite.Run("POST failure - 422 - PPM not allowed to create service item", func() { - subtestData := makeSubtestDataWithPPMShipmentType(true) + subtestData := makeSubtestDataWithPPMShipmentType(true, false) moveRouter := moverouter.NewMoveRouter() planner := &routemocks.Planner{} planner.On("ZipTransitDistance", diff --git a/pkg/handlers/primeapi/payloads/model_to_payload.go b/pkg/handlers/primeapi/payloads/model_to_payload.go index abe1b64a920..5f5106e6569 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload.go @@ -706,6 +706,23 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primemessages.MTOServ SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), } + case models.ReServiceCodeIOFSIT, models.ReServiceCodeIOASIT, models.ReServiceCodeIOPSIT, models.ReServiceCodeIOSFSC: + var sitDepartureDate time.Time + if mtoServiceItem.SITDepartureDate != nil { + sitDepartureDate = *mtoServiceItem.SITDepartureDate + } + payload = &primemessages.MTOServiceItemInternationalOriginSIT{ + ReServiceCode: handlers.FmtString(string(mtoServiceItem.ReService.Code)), + Reason: mtoServiceItem.Reason, + SitDepartureDate: handlers.FmtDate(sitDepartureDate), + SitEntryDate: handlers.FmtDatePtr(mtoServiceItem.SITEntryDate), + SitPostalCode: mtoServiceItem.SITPostalCode, + SitHHGActualOrigin: Address(mtoServiceItem.SITOriginHHGActualAddress), + SitHHGOriginalOrigin: Address(mtoServiceItem.SITOriginHHGOriginalAddress), + RequestApprovalsRequestedStatus: *mtoServiceItem.RequestedApprovalsRequestedStatus, + SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), + SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), + } case models.ReServiceCodeDDFSIT, models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDSFSC: var sitDepartureDate, firstAvailableDeliveryDate1, firstAvailableDeliveryDate2, dateOfContact1, dateOfContact2 time.Time var timeMilitary1, timeMilitary2 *string @@ -750,6 +767,50 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primemessages.MTOServ SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), } + case models.ReServiceCodeIDFSIT, models.ReServiceCodeIDASIT, models.ReServiceCodeIDDSIT, models.ReServiceCodeIDSFSC: + var sitDepartureDate, firstAvailableDeliveryDate1, firstAvailableDeliveryDate2, dateOfContact1, dateOfContact2 time.Time + var timeMilitary1, timeMilitary2 *string + + if mtoServiceItem.SITDepartureDate != nil { + sitDepartureDate = *mtoServiceItem.SITDepartureDate + } + + firstContact := GetCustomerContact(mtoServiceItem.CustomerContacts, models.CustomerContactTypeFirst) + secondContact := GetCustomerContact(mtoServiceItem.CustomerContacts, models.CustomerContactTypeSecond) + timeMilitary1 = &firstContact.TimeMilitary + timeMilitary2 = &secondContact.TimeMilitary + + if !firstContact.DateOfContact.IsZero() { + dateOfContact1 = firstContact.DateOfContact + } + + if !secondContact.DateOfContact.IsZero() { + dateOfContact2 = secondContact.DateOfContact + } + + if !firstContact.FirstAvailableDeliveryDate.IsZero() { + firstAvailableDeliveryDate1 = firstContact.FirstAvailableDeliveryDate + } + + if !secondContact.FirstAvailableDeliveryDate.IsZero() { + firstAvailableDeliveryDate2 = secondContact.FirstAvailableDeliveryDate + } + + payload = &primemessages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: handlers.FmtString(string(mtoServiceItem.ReService.Code)), + Reason: mtoServiceItem.Reason, + DateOfContact1: handlers.FmtDate(dateOfContact1), + TimeMilitary1: handlers.FmtStringPtrNonEmpty(timeMilitary1), + FirstAvailableDeliveryDate1: handlers.FmtDate(firstAvailableDeliveryDate1), + DateOfContact2: handlers.FmtDate(dateOfContact2), + TimeMilitary2: handlers.FmtStringPtrNonEmpty(timeMilitary2), + FirstAvailableDeliveryDate2: handlers.FmtDate(firstAvailableDeliveryDate2), + SitDepartureDate: handlers.FmtDate(sitDepartureDate), + SitEntryDate: handlers.FmtDatePtr(mtoServiceItem.SITEntryDate), + SitDestinationFinalAddress: Address(mtoServiceItem.SITDestinationFinalAddress), + SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), + SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), + } case models.ReServiceCodeDCRT, models.ReServiceCodeDUCRT: item := GetDimension(mtoServiceItem.Dimensions, models.DimensionTypeItem) diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index e94d78b063a..3ec3fda6327 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -740,6 +740,136 @@ func (suite *PayloadsSuite) TestAddress() { suite.Equal(strfmt.UUID(""), result.UsPostRegionCitiesID) } +func (suite *PayloadsSuite) TestMTOServiceItemDestSIT() { + reServiceCode := models.ReServiceCodeDDFSIT + reason := "reason" + dateOfContact1 := time.Now() + timeMilitary1 := "1500Z" + firstAvailableDeliveryDate1 := dateOfContact1.AddDate(0, 0, 10) + dateOfContact2 := time.Now().AddDate(0, 0, 5) + timeMilitary2 := "1300Z" + firstAvailableDeliveryDate2 := dateOfContact2.AddDate(0, 0, 10) + sitDepartureDate := time.Now().AddDate(0, 1, 0) + sitEntryDate := time.Now().AddDate(0, 0, -30) + finalAddress := models.Address{ + StreetAddress1: "dummyStreet", + City: "dummyCity", + State: "FL", + PostalCode: "55555", + } + mtoShipmentID := uuid.Must(uuid.NewV4()) + + mtoServiceItemDestSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCode}, + Reason: &reason, + SITDepartureDate: &sitDepartureDate, + SITEntryDate: &sitEntryDate, + SITDestinationFinalAddress: &finalAddress, + MTOShipmentID: &mtoShipmentID, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + + resultDestSIT := MTOServiceItem(mtoServiceItemDestSIT) + suite.NotNil(resultDestSIT) + destSIT, ok := resultDestSIT.(*primemessages.MTOServiceItemDestSIT) + suite.True(ok) + + suite.Equal(string(reServiceCode), string(*destSIT.ReServiceCode)) + suite.Equal(reason, *destSIT.Reason) + suite.Equal(strfmt.Date(sitDepartureDate).String(), destSIT.SitDepartureDate.String()) + suite.Equal(strfmt.Date(sitEntryDate).String(), destSIT.SitEntryDate.String()) + suite.Equal(strfmt.Date(dateOfContact1).String(), destSIT.DateOfContact1.String()) + suite.Equal(timeMilitary1, *destSIT.TimeMilitary1) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate1).String(), destSIT.FirstAvailableDeliveryDate1.String()) + suite.Equal(strfmt.Date(dateOfContact2).String(), destSIT.DateOfContact2.String()) + suite.Equal(timeMilitary2, *destSIT.TimeMilitary2) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate2).String(), destSIT.FirstAvailableDeliveryDate2.String()) + suite.Equal(finalAddress.StreetAddress1, *destSIT.SitDestinationFinalAddress.StreetAddress1) + suite.Equal(finalAddress.City, *destSIT.SitDestinationFinalAddress.City) + suite.Equal(finalAddress.State, *destSIT.SitDestinationFinalAddress.State) + suite.Equal(finalAddress.PostalCode, *destSIT.SitDestinationFinalAddress.PostalCode) + suite.Equal(mtoShipmentID.String(), destSIT.MtoShipmentID().String()) +} + +func (suite *PayloadsSuite) TestMTOServiceItemInternationalDestSIT() { + reServiceCode := models.ReServiceCodeIDFSIT + reason := "reason" + dateOfContact1 := time.Now() + timeMilitary1 := "1500Z" + firstAvailableDeliveryDate1 := dateOfContact1.AddDate(0, 0, 10) + dateOfContact2 := time.Now().AddDate(0, 0, 5) + timeMilitary2 := "1300Z" + firstAvailableDeliveryDate2 := dateOfContact2.AddDate(0, 0, 10) + sitDepartureDate := time.Now().AddDate(0, 1, 0) + sitEntryDate := time.Now().AddDate(0, 0, -30) + finalAddress := models.Address{ + StreetAddress1: "dummyStreet", + City: "dummyCity", + State: "FL", + PostalCode: "55555", + } + mtoShipmentID := uuid.Must(uuid.NewV4()) + + mtoServiceItemDestSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCode}, + Reason: &reason, + SITDepartureDate: &sitDepartureDate, + SITEntryDate: &sitEntryDate, + SITDestinationFinalAddress: &finalAddress, + MTOShipmentID: &mtoShipmentID, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + + resultDestSIT := MTOServiceItem(mtoServiceItemDestSIT) + suite.NotNil(resultDestSIT) + destSIT, ok := resultDestSIT.(*primemessages.MTOServiceItemInternationalDestSIT) + suite.True(ok) + + suite.Equal(string(reServiceCode), string(*destSIT.ReServiceCode)) + suite.Equal(reason, *destSIT.Reason) + suite.Equal(strfmt.Date(sitDepartureDate).String(), destSIT.SitDepartureDate.String()) + suite.Equal(strfmt.Date(sitEntryDate).String(), destSIT.SitEntryDate.String()) + suite.Equal(strfmt.Date(dateOfContact1).String(), destSIT.DateOfContact1.String()) + suite.Equal(timeMilitary1, *destSIT.TimeMilitary1) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate1).String(), destSIT.FirstAvailableDeliveryDate1.String()) + suite.Equal(strfmt.Date(dateOfContact2).String(), destSIT.DateOfContact2.String()) + suite.Equal(timeMilitary2, *destSIT.TimeMilitary2) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate2).String(), destSIT.FirstAvailableDeliveryDate2.String()) + suite.Equal(finalAddress.StreetAddress1, *destSIT.SitDestinationFinalAddress.StreetAddress1) + suite.Equal(finalAddress.City, *destSIT.SitDestinationFinalAddress.City) + suite.Equal(finalAddress.State, *destSIT.SitDestinationFinalAddress.State) + suite.Equal(finalAddress.PostalCode, *destSIT.SitDestinationFinalAddress.PostalCode) + suite.Equal(mtoShipmentID.String(), destSIT.MtoShipmentID().String()) +} + func (suite *PayloadsSuite) TestMTOServiceItemDCRTandDOFSITandDDFSIT() { reServiceCode := models.ReServiceCodeDCRT reServiceCodeSIT := models.ReServiceCodeDOFSIT @@ -854,6 +984,120 @@ func (suite *PayloadsSuite) TestMTOServiceItemDCRTandDOFSITandDDFSIT() { suite.True(ok) } +func (suite *PayloadsSuite) TestMTOServiceItemICRTandIOFSITandIDFSIT() { + reServiceCode := models.ReServiceCodeICRT + reServiceCodeSIT := models.ReServiceCodeIOFSIT + reServiceCodeIDFSIT := models.ReServiceCodeIDFSIT + + reason := "reason" + dateOfContact1 := time.Now() + timeMilitary1 := "1500Z" + firstAvailableDeliveryDate1 := dateOfContact1.AddDate(0, 0, 10) + dateOfContact2 := time.Now().AddDate(0, 0, 5) + timeMilitary2 := "1300Z" + firstAvailableDeliveryDate2 := dateOfContact2.AddDate(0, 0, 10) + + mtoServiceItemICRT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCode}, + Reason: &reason, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + year, month, day := time.Now().Date() + aWeekAgo := time.Date(year, month, day-7, 0, 0, 0, 0, time.UTC) + departureDate := aWeekAgo.Add(time.Hour * 24 * 30) + actualPickupAddress := factory.BuildAddress(nil, nil, []factory.Trait{factory.GetTraitAddress2}) + requestApprovalRequestedStatus := false + mtoServiceItemIOFSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCodeSIT}, + Reason: &reason, + SITDepartureDate: &departureDate, + SITEntryDate: &aWeekAgo, + SITPostalCode: models.StringPointer("90210"), + SITOriginHHGActualAddress: &actualPickupAddress, + SITCustomerContacted: &aWeekAgo, + SITRequestedDelivery: &aWeekAgo, + SITOriginHHGOriginalAddress: &models.Address{ + StreetAddress1: "dummyStreet2", + City: "dummyCity2", + State: "FL", + PostalCode: "55555", + }, + RequestedApprovalsRequestedStatus: &requestApprovalRequestedStatus, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + mtoServiceItemIDFSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCodeIDFSIT}, + Reason: &reason, + SITDepartureDate: &departureDate, + SITEntryDate: &aWeekAgo, + SITPostalCode: models.StringPointer("90210"), + SITOriginHHGActualAddress: &actualPickupAddress, + SITCustomerContacted: &aWeekAgo, + SITRequestedDelivery: &aWeekAgo, + SITOriginHHGOriginalAddress: &models.Address{ + StreetAddress1: "dummyStreet2", + City: "dummyCity2", + State: "FL", + PostalCode: "55555", + }, + RequestedApprovalsRequestedStatus: &requestApprovalRequestedStatus, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + + resultICRT := MTOServiceItem(mtoServiceItemICRT) + resultIOFSIT := MTOServiceItem(mtoServiceItemIOFSIT) + resultIDFSIT := MTOServiceItem(mtoServiceItemIDFSIT) + + suite.NotNil(resultICRT) + suite.NotNil(resultIOFSIT) + suite.NotNil(resultIDFSIT) + _, ok := resultICRT.(*primemessages.MTOServiceItemInternationalCrating) + + suite.True(ok) +} + func (suite *PayloadsSuite) TestMTOServiceItemICRTandIUCRT() { icrtReServiceCode := models.ReServiceCodeICRT iucrtReServiceCode := models.ReServiceCodeIUCRT diff --git a/pkg/handlers/primeapi/payloads/payload_to_model.go b/pkg/handlers/primeapi/payloads/payload_to_model.go index 5f2bfa9bada..c01b4913c18 100644 --- a/pkg/handlers/primeapi/payloads/payload_to_model.go +++ b/pkg/handlers/primeapi/payloads/payload_to_model.go @@ -470,6 +470,49 @@ func MTOServiceItemModel(mtoServiceItem primemessages.MTOServiceItem) (*models.M model.SITOriginHHGActualAddressID = &model.SITOriginHHGActualAddress.ID } + case primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT: + + originsit := mtoServiceItem.(*primemessages.MTOServiceItemInternationalOriginSIT) + + if originsit.ReServiceCode != nil { + model.ReService.Code = models.ReServiceCode(*originsit.ReServiceCode) + } + + model.Reason = originsit.Reason + // Check for reason required field on a IOASIT + if model.ReService.Code == models.ReServiceCodeIOASIT { + reasonVerrs := validateReasonInternationalOriginSIT(*originsit) + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + if model.ReService.Code == models.ReServiceCodeIOFSIT { + reasonVerrs := validateReasonInternationalOriginSIT(*originsit) + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + sitEntryDate := handlers.FmtDatePtrToPopPtr(originsit.SitEntryDate) + + if sitEntryDate != nil { + model.SITEntryDate = sitEntryDate + } + + if originsit.SitDepartureDate != nil { + model.SITDepartureDate = handlers.FmtDatePtrToPopPtr(originsit.SitDepartureDate) + } + + model.SITPostalCode = originsit.SitPostalCode + + model.SITOriginHHGActualAddress = AddressModel(originsit.SitHHGActualOrigin) + if model.SITOriginHHGActualAddress != nil { + model.SITOriginHHGActualAddressID = &model.SITOriginHHGActualAddress.ID + } + case primemessages.MTOServiceItemModelTypeMTOServiceItemDestSIT: destsit := mtoServiceItem.(*primemessages.MTOServiceItemDestSIT) @@ -529,6 +572,65 @@ func MTOServiceItemModel(mtoServiceItem primemessages.MTOServiceItem) (*models.M model.SITDestinationFinalAddressID = &model.SITDestinationFinalAddress.ID } + case primemessages.MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT: + destsit := mtoServiceItem.(*primemessages.MTOServiceItemInternationalDestSIT) + + if destsit.ReServiceCode != nil { + model.ReService.Code = models.ReServiceCode(*destsit.ReServiceCode) + + } + + model.Reason = destsit.Reason + sitEntryDate := handlers.FmtDatePtrToPopPtr(destsit.SitEntryDate) + + // Check for required fields on a IDFSIT + if model.ReService.Code == models.ReServiceCodeIDFSIT { + verrs := validateIDFSITForCreate(*destsit) + reasonVerrs := validateReasonInternationalDestSIT(*destsit) + + if verrs.HasAny() { + return nil, verrs + } + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + var customerContacts models.MTOServiceItemCustomerContacts + + if destsit.TimeMilitary1 != nil && destsit.FirstAvailableDeliveryDate1 != nil && destsit.DateOfContact1 != nil { + customerContacts = append(customerContacts, models.MTOServiceItemCustomerContact{ + Type: models.CustomerContactTypeFirst, + DateOfContact: time.Time(*destsit.DateOfContact1), + TimeMilitary: *destsit.TimeMilitary1, + FirstAvailableDeliveryDate: time.Time(*destsit.FirstAvailableDeliveryDate1), + }) + } + if destsit.TimeMilitary2 != nil && destsit.FirstAvailableDeliveryDate2 != nil && destsit.DateOfContact2 != nil { + customerContacts = append(customerContacts, models.MTOServiceItemCustomerContact{ + Type: models.CustomerContactTypeSecond, + DateOfContact: time.Time(*destsit.DateOfContact2), + TimeMilitary: *destsit.TimeMilitary2, + FirstAvailableDeliveryDate: time.Time(*destsit.FirstAvailableDeliveryDate2), + }) + } + + model.CustomerContacts = customerContacts + + if sitEntryDate != nil { + model.SITEntryDate = sitEntryDate + } + + if destsit.SitDepartureDate != nil { + model.SITDepartureDate = handlers.FmtDatePtrToPopPtr(destsit.SitDepartureDate) + } + + model.SITDestinationFinalAddress = AddressModel(destsit.SitDestinationFinalAddress) + if model.SITDestinationFinalAddress != nil { + model.SITDestinationFinalAddressID = &model.SITDestinationFinalAddress.ID + } + case primemessages.MTOServiceItemModelTypeMTOServiceItemShuttle: shuttleService := mtoServiceItem.(*primemessages.MTOServiceItemShuttle) // values to get from payload @@ -860,6 +962,31 @@ func validateDDFSITForCreate(m primemessages.MTOServiceItemDestSIT) *validate.Er return verrs } +// validateIDFSITForCreate validates IDFSIT service item has all required fields +func validateIDFSITForCreate(m primemessages.MTOServiceItemInternationalDestSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.FirstAvailableDeliveryDate1 == nil && m.DateOfContact1 != nil && m.TimeMilitary1 != nil { + verrs.Add("firstAvailableDeliveryDate1", "firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 must be provided together in body.") + } + if m.DateOfContact1 == nil && m.TimeMilitary1 != nil && m.FirstAvailableDeliveryDate1 != nil { + verrs.Add("DateOfContact1", "dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 must be provided together in body.") + } + if m.TimeMilitary1 == nil && m.DateOfContact1 != nil && m.FirstAvailableDeliveryDate1 != nil { + verrs.Add("timeMilitary1", "timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 must be provided together in body.") + } + if m.FirstAvailableDeliveryDate2 == nil && m.DateOfContact2 != nil && m.TimeMilitary2 != nil { + verrs.Add("firstAvailableDeliveryDate2", "firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 must be provided together in body.") + } + if m.DateOfContact2 == nil && m.TimeMilitary2 != nil && m.FirstAvailableDeliveryDate2 != nil { + verrs.Add("DateOfContact2", "dateOfContact2, firstAvailableDeliveryDate2, and timeMilitary2 must be provided together in body.") + } + if m.TimeMilitary2 == nil && m.DateOfContact2 != nil && m.FirstAvailableDeliveryDate2 != nil { + verrs.Add("timeMilitary2", "timeMilitary2, firstAvailableDeliveryDate2, and dateOfContact2 must be provided together in body.") + } + return verrs +} + // validateDestSITForUpdate validates DDDSIT service item has all required fields func validateDestSITForUpdate(m primemessages.UpdateMTOServiceItemSIT) *validate.Errors { verrs := validate.NewErrors() @@ -895,6 +1022,16 @@ func validateReasonDestSIT(m primemessages.MTOServiceItemDestSIT) *validate.Erro return verrs } +// validateReasonInternationalDestSIT validates that International Destination SIT service items have required Reason field +func validateReasonInternationalDestSIT(m primemessages.MTOServiceItemInternationalDestSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.Reason == nil || m.Reason == models.StringPointer("") { + verrs.Add("reason", "reason is required in body.") + } + return verrs +} + // validateReasonOriginSIT validates that Origin SIT service items have required Reason field func validateReasonOriginSIT(m primemessages.MTOServiceItemOriginSIT) *validate.Errors { verrs := validate.NewErrors() @@ -920,3 +1057,13 @@ func VLocationModel(vLocation *primemessages.VLocation) *models.VLocation { UsPostRegionCitiesID: &usPostRegionCitiesID, } } + +// validateReasonInternationalOriginSIT validates that International Origin SIT service items have required Reason field +func validateReasonInternationalOriginSIT(m primemessages.MTOServiceItemInternationalOriginSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.Reason == nil || m.Reason == models.StringPointer("") { + verrs.Add("reason", "reason is required in body.") + } + return verrs +} diff --git a/pkg/handlers/primeapi/payloads/payload_to_model_test.go b/pkg/handlers/primeapi/payloads/payload_to_model_test.go index 2f18cec241d..667bad2439f 100644 --- a/pkg/handlers/primeapi/payloads/payload_to_model_test.go +++ b/pkg/handlers/primeapi/payloads/payload_to_model_test.go @@ -397,6 +397,31 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(originSITDepartureDate, *handlers.FmtDatePtr(returnedModel.SITDepartureDate)) }) + suite.Run("Success - Returns international SIT origin service item model", func() { + originSITServiceItem := &primemessages.MTOServiceItemInternationalOriginSIT{ + ReServiceCode: &originServiceCode, + SitEntryDate: &originSITEntryDate, + SitDepartureDate: &originSITDepartureDate, + SitHHGActualOrigin: &sitHHGActualOriginAddress, + Reason: &originReason, + } + + originSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + originSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(originSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDOFSIT, returnedModel.ReService.Code) + suite.Equal(originStreet1, returnedModel.SITOriginHHGActualAddress.StreetAddress1) + suite.Equal(originCity, returnedModel.SITOriginHHGActualAddress.City) + suite.Equal(originState, returnedModel.SITOriginHHGActualAddress.State) + suite.Equal(originPostalCode, returnedModel.SITOriginHHGActualAddress.PostalCode) + suite.Equal(originSITEntryDate, *handlers.FmtDatePtr(returnedModel.SITEntryDate)) + suite.Equal(originSITDepartureDate, *handlers.FmtDatePtr(returnedModel.SITDepartureDate)) + }) + suite.Run("Success - Returns SIT destination service item model", func() { destSITServiceItem := &primemessages.MTOServiceItemDestSIT{ ReServiceCode: &destServiceCode, @@ -423,6 +448,32 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) }) + suite.Run("Success - Returns international SIT destination service item model", func() { + destSITServiceItem := &primemessages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: &destServiceCode, + FirstAvailableDeliveryDate1: &destDate, + FirstAvailableDeliveryDate2: &destDate, + DateOfContact1: &destDate, + DateOfContact2: &destDate, + TimeMilitary1: &destTime, + TimeMilitary2: &destTime, + SitDestinationFinalAddress: &sitFinalDestAddress, + Reason: &destReason, + } + + destSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + destSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(destSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDDFSIT, returnedModel.ReService.Code) + suite.Equal(destPostalCode, returnedModel.SITDestinationFinalAddress.PostalCode) + suite.Equal(destStreet, returnedModel.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) + }) + suite.Run("Success - Returns SIT destination service item model without customer contact fields", func() { destSITServiceItem := &primemessages.MTOServiceItemDestSIT{ ReServiceCode: &destServiceCode, @@ -443,6 +494,27 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) suite.Equal(destReason, *returnedModel.Reason) }) + + suite.Run("Success - Returns internatonal SIT destination service item model without customer contact fields", func() { + destSITServiceItem := &primemessages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: &destServiceCode, + SitDestinationFinalAddress: &sitFinalDestAddress, + Reason: &destReason, + } + + destSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + destSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(destSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDDFSIT, returnedModel.ReService.Code) + suite.Equal(destPostalCode, returnedModel.SITDestinationFinalAddress.PostalCode) + suite.Equal(destStreet, returnedModel.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) + suite.Equal(destReason, *returnedModel.Reason) + }) } func (suite *PayloadsSuite) TestReweighModelFromUpdate() { diff --git a/pkg/handlers/primeapiv2/mto_service_item_test.go b/pkg/handlers/primeapiv2/mto_service_item_test.go index a48c9bfe87d..376353adfa4 100644 --- a/pkg/handlers/primeapiv2/mto_service_item_test.go +++ b/pkg/handlers/primeapiv2/mto_service_item_test.go @@ -194,6 +194,11 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { Model: mto, LinkOnly: true, }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, }, nil) mtoShipment.PrimeEstimatedWeight = nil factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOSHUT) diff --git a/pkg/handlers/primeapiv2/payloads/model_to_payload.go b/pkg/handlers/primeapiv2/payloads/model_to_payload.go index 09f107a9e04..7b39c88c803 100644 --- a/pkg/handlers/primeapiv2/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv2/payloads/model_to_payload.go @@ -617,6 +617,20 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primev2messages.MTOSe SitHHGActualOrigin: Address(mtoServiceItem.SITOriginHHGActualAddress), SitHHGOriginalOrigin: Address(mtoServiceItem.SITOriginHHGOriginalAddress), } + case models.ReServiceCodeIOFSIT, models.ReServiceCodeIOASIT, models.ReServiceCodeIOPSIT, models.ReServiceCodeIOSFSC: + var sitDepartureDate time.Time + if mtoServiceItem.SITDepartureDate != nil { + sitDepartureDate = *mtoServiceItem.SITDepartureDate + } + payload = &primev2messages.MTOServiceItemInternationalOriginSIT{ + ReServiceCode: handlers.FmtString(string(mtoServiceItem.ReService.Code)), + Reason: mtoServiceItem.Reason, + SitDepartureDate: handlers.FmtDate(sitDepartureDate), + SitEntryDate: handlers.FmtDatePtr(mtoServiceItem.SITEntryDate), + SitPostalCode: mtoServiceItem.SITPostalCode, + SitHHGActualOrigin: Address(mtoServiceItem.SITOriginHHGActualAddress), + SitHHGOriginalOrigin: Address(mtoServiceItem.SITOriginHHGOriginalAddress), + } case models.ReServiceCodeDDFSIT, models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDSFSC: var sitDepartureDate, firstAvailableDeliveryDate1, firstAvailableDeliveryDate2, dateOfContact1, dateOfContact2 time.Time var timeMilitary1, timeMilitary2 *string @@ -661,6 +675,50 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primev2messages.MTOSe SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), } + case models.ReServiceCodeIDFSIT, models.ReServiceCodeIDASIT, models.ReServiceCodeIDDSIT, models.ReServiceCodeIDSFSC: + var sitDepartureDate, firstAvailableDeliveryDate1, firstAvailableDeliveryDate2, dateOfContact1, dateOfContact2 time.Time + var timeMilitary1, timeMilitary2 *string + + if mtoServiceItem.SITDepartureDate != nil { + sitDepartureDate = *mtoServiceItem.SITDepartureDate + } + + firstContact := GetCustomerContact(mtoServiceItem.CustomerContacts, models.CustomerContactTypeFirst) + secondContact := GetCustomerContact(mtoServiceItem.CustomerContacts, models.CustomerContactTypeSecond) + timeMilitary1 = &firstContact.TimeMilitary + timeMilitary2 = &secondContact.TimeMilitary + + if !firstContact.DateOfContact.IsZero() { + dateOfContact1 = firstContact.DateOfContact + } + + if !secondContact.DateOfContact.IsZero() { + dateOfContact2 = secondContact.DateOfContact + } + + if !firstContact.FirstAvailableDeliveryDate.IsZero() { + firstAvailableDeliveryDate1 = firstContact.FirstAvailableDeliveryDate + } + + if !secondContact.FirstAvailableDeliveryDate.IsZero() { + firstAvailableDeliveryDate2 = secondContact.FirstAvailableDeliveryDate + } + + payload = &primev2messages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: handlers.FmtString(string(mtoServiceItem.ReService.Code)), + Reason: mtoServiceItem.Reason, + DateOfContact1: handlers.FmtDate(dateOfContact1), + TimeMilitary1: handlers.FmtStringPtrNonEmpty(timeMilitary1), + FirstAvailableDeliveryDate1: handlers.FmtDate(firstAvailableDeliveryDate1), + DateOfContact2: handlers.FmtDate(dateOfContact2), + TimeMilitary2: handlers.FmtStringPtrNonEmpty(timeMilitary2), + FirstAvailableDeliveryDate2: handlers.FmtDate(firstAvailableDeliveryDate2), + SitDepartureDate: handlers.FmtDate(sitDepartureDate), + SitEntryDate: handlers.FmtDatePtr(mtoServiceItem.SITEntryDate), + SitDestinationFinalAddress: Address(mtoServiceItem.SITDestinationFinalAddress), + SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), + SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), + } case models.ReServiceCodeDCRT, models.ReServiceCodeDUCRT: item := GetDimension(mtoServiceItem.Dimensions, models.DimensionTypeItem) diff --git a/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go b/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go index 2119ecd1a8e..ec53f8a3457 100644 --- a/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go @@ -640,6 +640,50 @@ func (suite *PayloadsSuite) TestMTOServiceItem() { suite.Equal(mtoServiceItemDefault.MoveTaskOrderID.String(), basicItem.MoveTaskOrderID().String()) } +func (suite *PayloadsSuite) TestMTOServiceInternationalItem() { + sitPostalCode := "55555" + mtoServiceItemIOFSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: models.ReServiceCodeIOFSIT}, + SITDepartureDate: nil, + SITEntryDate: nil, + SITPostalCode: &sitPostalCode, + SITOriginHHGActualAddress: &models.Address{ + StreetAddress1: "dummyStreet", + City: "dummyCity", + State: "FL", + PostalCode: "55555", + }, + SITOriginHHGOriginalAddress: &models.Address{ + StreetAddress1: "dummyStreet2", + City: "dummyCity2", + State: "FL", + PostalCode: "55555", + }, + } + + resultIOFSIT := MTOServiceItem(mtoServiceItemIOFSIT) + suite.NotNil(resultIOFSIT) + sitOrigin, ok := resultIOFSIT.(*primev2messages.MTOServiceItemInternationalOriginSIT) + suite.True(ok) + suite.Equal("55555", *sitOrigin.SitPostalCode) + suite.Equal("dummyStreet", *sitOrigin.SitHHGActualOrigin.StreetAddress1) + suite.Equal("dummyStreet2", *sitOrigin.SitHHGOriginalOrigin.StreetAddress1) + + mtoServiceItemDefault := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: "SOME_OTHER_SERVICE_CODE"}, + MoveTaskOrderID: uuid.Must(uuid.NewV4()), + } + + resultDefault := MTOServiceItem(mtoServiceItemDefault) + suite.NotNil(resultDefault) + basicItem, ok := resultDefault.(*primev2messages.MTOServiceItemBasic) + suite.True(ok) + suite.Equal("SOME_OTHER_SERVICE_CODE", string(*basicItem.ReServiceCode)) + suite.Equal(mtoServiceItemDefault.MoveTaskOrderID.String(), basicItem.MoveTaskOrderID().String()) +} + func (suite *PayloadsSuite) TestGetCustomerContact() { customerContacts := models.MTOServiceItemCustomerContacts{ models.MTOServiceItemCustomerContact{Type: models.CustomerContactTypeFirst}, @@ -725,6 +769,72 @@ func (suite *PayloadsSuite) TestMTOServiceItemDestSIT() { suite.Equal(finalAddress.PostalCode, *destSIT.SitDestinationFinalAddress.PostalCode) suite.Equal(mtoShipmentID.String(), destSIT.MtoShipmentID().String()) } + +func (suite *PayloadsSuite) TestMTOServiceItemInternationalDestSIT() { + reServiceCode := models.ReServiceCodeIDFSIT + reason := "reason" + dateOfContact1 := time.Now() + timeMilitary1 := "1500Z" + firstAvailableDeliveryDate1 := dateOfContact1.AddDate(0, 0, 10) + dateOfContact2 := time.Now().AddDate(0, 0, 5) + timeMilitary2 := "1300Z" + firstAvailableDeliveryDate2 := dateOfContact2.AddDate(0, 0, 10) + sitDepartureDate := time.Now().AddDate(0, 1, 0) + sitEntryDate := time.Now().AddDate(0, 0, -30) + finalAddress := models.Address{ + StreetAddress1: "dummyStreet", + City: "dummyCity", + State: "FL", + PostalCode: "55555", + } + mtoShipmentID := uuid.Must(uuid.NewV4()) + + mtoServiceItemDestSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCode}, + Reason: &reason, + SITDepartureDate: &sitDepartureDate, + SITEntryDate: &sitEntryDate, + SITDestinationFinalAddress: &finalAddress, + MTOShipmentID: &mtoShipmentID, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + + resultDestSIT := MTOServiceItem(mtoServiceItemDestSIT) + suite.NotNil(resultDestSIT) + destSIT, ok := resultDestSIT.(*primev2messages.MTOServiceItemInternationalDestSIT) + suite.True(ok) + + suite.Equal(string(reServiceCode), string(*destSIT.ReServiceCode)) + suite.Equal(reason, *destSIT.Reason) + suite.Equal(strfmt.Date(sitDepartureDate).String(), destSIT.SitDepartureDate.String()) + suite.Equal(strfmt.Date(sitEntryDate).String(), destSIT.SitEntryDate.String()) + suite.Equal(strfmt.Date(dateOfContact1).String(), destSIT.DateOfContact1.String()) + suite.Equal(timeMilitary1, *destSIT.TimeMilitary1) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate1).String(), destSIT.FirstAvailableDeliveryDate1.String()) + suite.Equal(strfmt.Date(dateOfContact2).String(), destSIT.DateOfContact2.String()) + suite.Equal(timeMilitary2, *destSIT.TimeMilitary2) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate2).String(), destSIT.FirstAvailableDeliveryDate2.String()) + suite.Equal(finalAddress.StreetAddress1, *destSIT.SitDestinationFinalAddress.StreetAddress1) + suite.Equal(finalAddress.City, *destSIT.SitDestinationFinalAddress.City) + suite.Equal(finalAddress.State, *destSIT.SitDestinationFinalAddress.State) + suite.Equal(finalAddress.PostalCode, *destSIT.SitDestinationFinalAddress.PostalCode) + suite.Equal(mtoShipmentID.String(), destSIT.MtoShipmentID().String()) +} + func (suite *PayloadsSuite) TestMTOServiceItemDCRT() { reServiceCode := models.ReServiceCodeDCRT reason := "reason" diff --git a/pkg/handlers/primeapiv2/payloads/payload_to_model.go b/pkg/handlers/primeapiv2/payloads/payload_to_model.go index 2b2f5e420c8..33c1d26c453 100644 --- a/pkg/handlers/primeapiv2/payloads/payload_to_model.go +++ b/pkg/handlers/primeapiv2/payloads/payload_to_model.go @@ -562,7 +562,44 @@ func MTOServiceItemModel(mtoServiceItem primev2messages.MTOServiceItem) (*models if model.SITOriginHHGActualAddress != nil { model.SITOriginHHGActualAddressID = &model.SITOriginHHGActualAddress.ID } + case primev2messages.MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT: + originsit := mtoServiceItem.(*primev2messages.MTOServiceItemInternationalOriginSIT) + + if originsit.ReServiceCode != nil { + model.ReService.Code = models.ReServiceCode(*originsit.ReServiceCode) + } + + model.Reason = originsit.Reason + // Check for reason required field on a IOASIT + if model.ReService.Code == models.ReServiceCodeIOASIT { + reasonVerrs := validateReasonInternationalOriginSIT(*originsit) + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + if model.ReService.Code == models.ReServiceCodeIOFSIT { + reasonVerrs := validateReasonInternationalOriginSIT(*originsit) + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + sitEntryDate := handlers.FmtDatePtrToPopPtr(originsit.SitEntryDate) + + if sitEntryDate != nil { + model.SITEntryDate = sitEntryDate + } + + model.SITPostalCode = originsit.SitPostalCode + + model.SITOriginHHGActualAddress = AddressModel(originsit.SitHHGActualOrigin) + if model.SITOriginHHGActualAddress != nil { + model.SITOriginHHGActualAddressID = &model.SITOriginHHGActualAddress.ID + } case primev2messages.MTOServiceItemModelTypeMTOServiceItemDestSIT: destsit := mtoServiceItem.(*primev2messages.MTOServiceItemDestSIT) @@ -617,6 +654,64 @@ func MTOServiceItemModel(mtoServiceItem primev2messages.MTOServiceItem) (*models model.SITDepartureDate = handlers.FmtDatePtrToPopPtr(destsit.SitDepartureDate) } + model.SITDestinationFinalAddress = AddressModel(destsit.SitDestinationFinalAddress) + if model.SITDestinationFinalAddress != nil { + model.SITDestinationFinalAddressID = &model.SITDestinationFinalAddress.ID + } + case primev2messages.MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT: + destsit := mtoServiceItem.(*primev2messages.MTOServiceItemInternationalDestSIT) + + if destsit.ReServiceCode != nil { + model.ReService.Code = models.ReServiceCode(*destsit.ReServiceCode) + + } + + model.Reason = destsit.Reason + sitEntryDate := handlers.FmtDatePtrToPopPtr(destsit.SitEntryDate) + + // Check for required fields on a IDFSIT + if model.ReService.Code == models.ReServiceCodeIDFSIT { + verrs := validateIDFSITForCreate(*destsit) + reasonVerrs := validateReasonInternationalDestSIT(*destsit) + + if verrs.HasAny() { + return nil, verrs + } + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + var customerContacts models.MTOServiceItemCustomerContacts + + if destsit.TimeMilitary1 != nil && destsit.FirstAvailableDeliveryDate1 != nil && destsit.DateOfContact1 != nil { + customerContacts = append(customerContacts, models.MTOServiceItemCustomerContact{ + Type: models.CustomerContactTypeFirst, + DateOfContact: time.Time(*destsit.DateOfContact1), + TimeMilitary: *destsit.TimeMilitary1, + FirstAvailableDeliveryDate: time.Time(*destsit.FirstAvailableDeliveryDate1), + }) + } + if destsit.TimeMilitary2 != nil && destsit.FirstAvailableDeliveryDate2 != nil && destsit.DateOfContact2 != nil { + customerContacts = append(customerContacts, models.MTOServiceItemCustomerContact{ + Type: models.CustomerContactTypeSecond, + DateOfContact: time.Time(*destsit.DateOfContact2), + TimeMilitary: *destsit.TimeMilitary2, + FirstAvailableDeliveryDate: time.Time(*destsit.FirstAvailableDeliveryDate2), + }) + } + + model.CustomerContacts = customerContacts + + if sitEntryDate != nil { + model.SITEntryDate = sitEntryDate + } + + if destsit.SitDepartureDate != nil { + model.SITDepartureDate = handlers.FmtDatePtrToPopPtr(destsit.SitDepartureDate) + } + model.SITDestinationFinalAddress = AddressModel(destsit.SitDestinationFinalAddress) if model.SITDestinationFinalAddress != nil { model.SITDestinationFinalAddressID = &model.SITDestinationFinalAddress.ID @@ -932,6 +1027,31 @@ func validateDDFSITForCreate(m primev2messages.MTOServiceItemDestSIT) *validate. return verrs } +// validateIDFSITForCreate validates IDFSIT service item has all required fields +func validateIDFSITForCreate(m primev2messages.MTOServiceItemInternationalDestSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.FirstAvailableDeliveryDate1 == nil && m.DateOfContact1 != nil && m.TimeMilitary1 != nil { + verrs.Add("firstAvailableDeliveryDate1", "firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 must be provided together in body.") + } + if m.DateOfContact1 == nil && m.TimeMilitary1 != nil && m.FirstAvailableDeliveryDate1 != nil { + verrs.Add("DateOfContact1", "dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 must be provided together in body.") + } + if m.TimeMilitary1 == nil && m.DateOfContact1 != nil && m.FirstAvailableDeliveryDate1 != nil { + verrs.Add("timeMilitary1", "timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 must be provided together in body.") + } + if m.FirstAvailableDeliveryDate2 == nil && m.DateOfContact2 != nil && m.TimeMilitary2 != nil { + verrs.Add("firstAvailableDeliveryDate2", "firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 must be provided together in body.") + } + if m.DateOfContact2 == nil && m.TimeMilitary2 != nil && m.FirstAvailableDeliveryDate2 != nil { + verrs.Add("DateOfContact2", "dateOfContact2, firstAvailableDeliveryDate2, and timeMilitary2 must be provided together in body.") + } + if m.TimeMilitary2 == nil && m.DateOfContact2 != nil && m.FirstAvailableDeliveryDate2 != nil { + verrs.Add("timeMilitary2", "timeMilitary2, firstAvailableDeliveryDate2, and dateOfContact2 must be provided together in body.") + } + return verrs +} + // validateDestSITForUpdate validates DDDSIT service item has all required fields func validateDestSITForUpdate(m primev2messages.UpdateMTOServiceItemSIT) *validate.Errors { verrs := validate.NewErrors() @@ -967,6 +1087,16 @@ func validateReasonDestSIT(m primev2messages.MTOServiceItemDestSIT) *validate.Er return verrs } +// validateReasonInternationalDestSIT validates that International Destination SIT service items have required Reason field +func validateReasonInternationalDestSIT(m primev2messages.MTOServiceItemInternationalDestSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.Reason == nil || m.Reason == models.StringPointer("") { + verrs.Add("reason", "reason is required in body.") + } + return verrs +} + // validateReasonOriginSIT validates that Origin SIT service items have required Reason field func validateReasonOriginSIT(m primev2messages.MTOServiceItemOriginSIT) *validate.Errors { verrs := validate.NewErrors() @@ -977,6 +1107,16 @@ func validateReasonOriginSIT(m primev2messages.MTOServiceItemOriginSIT) *validat return verrs } +// validateReasonInternationalOriginSIT validates that International Origin SIT service items have required Reason field +func validateReasonInternationalOriginSIT(m primev2messages.MTOServiceItemInternationalOriginSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.Reason == nil || m.Reason == models.StringPointer("") { + verrs.Add("reason", "reason is required in body.") + } + return verrs +} + // validateBoatShipmentType validates that the shipment type is a valid boat type, and is not nil. func validateBoatShipmentType(s primev2messages.MTOShipmentType) *validate.Errors { verrs := validate.NewErrors() diff --git a/pkg/handlers/primeapiv2/payloads/payload_to_model_test.go b/pkg/handlers/primeapiv2/payloads/payload_to_model_test.go index 5a1e7844ab6..2f32f2f611a 100644 --- a/pkg/handlers/primeapiv2/payloads/payload_to_model_test.go +++ b/pkg/handlers/primeapiv2/payloads/payload_to_model_test.go @@ -378,6 +378,32 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) }) + suite.Run("Success - Returns SIT destination service item model - international", func() { + destSITServiceItem := &primev2messages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: &destServiceCode, + FirstAvailableDeliveryDate1: &destDate, + FirstAvailableDeliveryDate2: &destDate, + DateOfContact1: &destDate, + DateOfContact2: &destDate, + TimeMilitary1: &destTime, + TimeMilitary2: &destTime, + SitDestinationFinalAddress: &sitFinalDestAddress, + Reason: &destReason, + } + + destSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + destSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(destSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDDFSIT, returnedModel.ReService.Code) + suite.Equal(destPostalCode, returnedModel.SITDestinationFinalAddress.PostalCode) + suite.Equal(destStreet, returnedModel.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) + }) + suite.Run("Success - Returns SIT destination service item model without customer contact fields", func() { destSITServiceItem := &primev2messages.MTOServiceItemDestSIT{ ReServiceCode: &destServiceCode, @@ -398,6 +424,27 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) suite.Equal(destReason, *returnedModel.Reason) }) + + suite.Run("Success - Returns SIT destination service item model without customer contact fields - international", func() { + destSITServiceItem := &primev2messages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: &destServiceCode, + SitDestinationFinalAddress: &sitFinalDestAddress, + Reason: &destReason, + } + + destSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + destSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(destSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDDFSIT, returnedModel.ReService.Code) + suite.Equal(destPostalCode, returnedModel.SITDestinationFinalAddress.PostalCode) + suite.Equal(destStreet, returnedModel.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) + suite.Equal(destReason, *returnedModel.Reason) + }) } func (suite *PayloadsSuite) TestReweighModelFromUpdate() { @@ -641,6 +688,23 @@ func (suite *PayloadsSuite) TestValidateReasonOriginSIT() { verrs := validateReasonOriginSIT(mtoServiceItemOriginSIT) suite.True(verrs.HasAny()) }) + + suite.Run("Reason provided - international", func() { + reason := "reason" + mtoServiceItemOriginSIT := primev2messages.MTOServiceItemInternationalOriginSIT{ + Reason: &reason, + } + + verrs := validateReasonInternationalOriginSIT(mtoServiceItemOriginSIT) + suite.False(verrs.HasAny()) + }) + + suite.Run("No reason provided - international", func() { + mtoServiceItemOriginSIT := primev2messages.MTOServiceItemInternationalOriginSIT{} + + verrs := validateReasonInternationalOriginSIT(mtoServiceItemOriginSIT) + suite.True(verrs.HasAny()) + }) } func (suite *PayloadsSuite) TestShipmentAddressUpdateModel() { diff --git a/pkg/handlers/primeapiv3/mto_service_item_test.go b/pkg/handlers/primeapiv3/mto_service_item_test.go index b0b02a71aca..cd7bd7a3fc1 100644 --- a/pkg/handlers/primeapiv3/mto_service_item_test.go +++ b/pkg/handlers/primeapiv3/mto_service_item_test.go @@ -195,6 +195,11 @@ func (suite *HandlerSuite) TestCreateMTOServiceItemHandler() { Model: mto, LinkOnly: true, }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, }, nil) mtoShipment.PrimeEstimatedWeight = nil factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOSHUT) diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload.go b/pkg/handlers/primeapiv3/payloads/model_to_payload.go index aba7a9c1718..b7338ffc04a 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload.go @@ -93,12 +93,15 @@ func MoveTaskOrderWithShipmentRateAreas(appCtx appcontext.AppContext, moveTaskOr } // Origin/Destination RateArea will be present on root shipment level for all non-PPM shipment types for _, shipment := range payload.MtoShipments { - if shipment.PpmShipment != nil { - shipment.PpmShipment.OriginRateArea = PostalCodeToRateArea(shipment.PpmShipment.PickupAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) - shipment.PpmShipment.DestinationRateArea = PostalCodeToRateArea(shipment.PpmShipment.DestinationAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) - } else { - shipment.OriginRateArea = PostalCodeToRateArea(shipment.PickupAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) - shipment.DestinationRateArea = PostalCodeToRateArea(shipment.DestinationAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) + // B-22767: We want both domestic and international rate area info but only for international shipments + if shipment.MarketCode == string(models.MarketCodeInternational) { + if shipment.PpmShipment != nil { + shipment.PpmShipment.OriginRateArea = PostalCodeToRateArea(shipment.PpmShipment.PickupAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) + shipment.PpmShipment.DestinationRateArea = PostalCodeToRateArea(shipment.PpmShipment.DestinationAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) + } else { + shipment.OriginRateArea = PostalCodeToRateArea(shipment.PickupAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) + shipment.DestinationRateArea = PostalCodeToRateArea(shipment.DestinationAddress.PostalCode, shipmentPostalCodeRateAreaLookupMap) + } } } } @@ -760,6 +763,20 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primev3messages.MTOSe SitHHGActualOrigin: Address(mtoServiceItem.SITOriginHHGActualAddress), SitHHGOriginalOrigin: Address(mtoServiceItem.SITOriginHHGOriginalAddress), } + case models.ReServiceCodeIOFSIT, models.ReServiceCodeIOASIT, models.ReServiceCodeIOPSIT, models.ReServiceCodeIOSFSC: + var sitDepartureDate time.Time + if mtoServiceItem.SITDepartureDate != nil { + sitDepartureDate = *mtoServiceItem.SITDepartureDate + } + payload = &primev3messages.MTOServiceItemInternationalOriginSIT{ + ReServiceCode: handlers.FmtString(string(mtoServiceItem.ReService.Code)), + Reason: mtoServiceItem.Reason, + SitDepartureDate: handlers.FmtDate(sitDepartureDate), + SitEntryDate: handlers.FmtDatePtr(mtoServiceItem.SITEntryDate), + SitPostalCode: mtoServiceItem.SITPostalCode, + SitHHGActualOrigin: Address(mtoServiceItem.SITOriginHHGActualAddress), + SitHHGOriginalOrigin: Address(mtoServiceItem.SITOriginHHGOriginalAddress), + } case models.ReServiceCodeDDFSIT, models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDSFSC: var sitDepartureDate, firstAvailableDeliveryDate1, firstAvailableDeliveryDate2, dateOfContact1, dateOfContact2 time.Time var timeMilitary1, timeMilitary2 *string @@ -804,7 +821,50 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primev3messages.MTOSe SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), } + case models.ReServiceCodeIDFSIT, models.ReServiceCodeIDASIT, models.ReServiceCodeIDDSIT, models.ReServiceCodeIDSFSC: + var sitDepartureDate, firstAvailableDeliveryDate1, firstAvailableDeliveryDate2, dateOfContact1, dateOfContact2 time.Time + var timeMilitary1, timeMilitary2 *string + + if mtoServiceItem.SITDepartureDate != nil { + sitDepartureDate = *mtoServiceItem.SITDepartureDate + } + + firstContact := GetCustomerContact(mtoServiceItem.CustomerContacts, models.CustomerContactTypeFirst) + secondContact := GetCustomerContact(mtoServiceItem.CustomerContacts, models.CustomerContactTypeSecond) + timeMilitary1 = &firstContact.TimeMilitary + timeMilitary2 = &secondContact.TimeMilitary + + if !firstContact.DateOfContact.IsZero() { + dateOfContact1 = firstContact.DateOfContact + } + + if !secondContact.DateOfContact.IsZero() { + dateOfContact2 = secondContact.DateOfContact + } + + if !firstContact.FirstAvailableDeliveryDate.IsZero() { + firstAvailableDeliveryDate1 = firstContact.FirstAvailableDeliveryDate + } + if !secondContact.FirstAvailableDeliveryDate.IsZero() { + firstAvailableDeliveryDate2 = secondContact.FirstAvailableDeliveryDate + } + + payload = &primev3messages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: handlers.FmtString(string(mtoServiceItem.ReService.Code)), + Reason: mtoServiceItem.Reason, + DateOfContact1: handlers.FmtDate(dateOfContact1), + TimeMilitary1: handlers.FmtStringPtrNonEmpty(timeMilitary1), + FirstAvailableDeliveryDate1: handlers.FmtDate(firstAvailableDeliveryDate1), + DateOfContact2: handlers.FmtDate(dateOfContact2), + TimeMilitary2: handlers.FmtStringPtrNonEmpty(timeMilitary2), + FirstAvailableDeliveryDate2: handlers.FmtDate(firstAvailableDeliveryDate2), + SitDepartureDate: handlers.FmtDate(sitDepartureDate), + SitEntryDate: handlers.FmtDatePtr(mtoServiceItem.SITEntryDate), + SitDestinationFinalAddress: Address(mtoServiceItem.SITDestinationFinalAddress), + SitCustomerContacted: handlers.FmtDatePtr(mtoServiceItem.SITCustomerContacted), + SitRequestedDelivery: handlers.FmtDatePtr(mtoServiceItem.SITRequestedDelivery), + } case models.ReServiceCodeDCRT, models.ReServiceCodeDUCRT: item := GetDimension(mtoServiceItem.Dimensions, models.DimensionTypeItem) crate := GetDimension(mtoServiceItem.Dimensions, models.DimensionTypeCrate) diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go b/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go index f0f7036eac6..dec88a480cb 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go @@ -151,11 +151,13 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { const fairbanksAlaskaPostalCode = "99716" const anchorageAlaskaPostalCode = "99521" const wasillaAlaskaPostalCode = "99652" + const beverlyHillsCAPostalCode = "90210" //clear MTOShipment and rebuild with specifics for test newMove.MTOShipments = newMove.MTOShipments[:0] newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ + MarketCode: models.MarketCodeInternational, PickupAddress: &models.Address{ StreetAddress1: "123 Main St", StreetAddress2: &streetAddress2, @@ -175,6 +177,7 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { }, }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ + MarketCode: models.MarketCodeInternational, PickupAddress: &models.Address{ StreetAddress1: "123 Main St", StreetAddress2: &streetAddress2, @@ -195,6 +198,7 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ ShipmentType: models.MTOShipmentTypePPM, + MarketCode: models.MarketCodeInternational, PPMShipment: &models.PPMShipment{ ID: uuid.Must(uuid.NewV4()), ApprovedAt: models.TimePointer(time.Now()), @@ -224,6 +228,8 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { }, }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ + ShipmentType: models.MTOShipmentTypePPM, + MarketCode: models.MarketCodeDomestic, PPMShipment: &models.PPMShipment{ ID: uuid.Must(uuid.NewV4()), ApprovedAt: models.TimePointer(time.Now()), @@ -240,7 +246,7 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { StreetAddress3: &streetAddress3, City: "Beverly Hills", State: "CA", - PostalCode: "90210", + PostalCode: beverlyHillsCAPostalCode, }, DestinationAddress: &models.Address{ StreetAddress1: "123 Main St", @@ -248,18 +254,19 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { StreetAddress3: &streetAddress3, City: "Beverly Hills", State: "CA", - PostalCode: "90210", + PostalCode: beverlyHillsCAPostalCode, }, }, }) newMove.MTOShipments = append(newMove.MTOShipments, models.MTOShipment{ + MarketCode: models.MarketCodeDomestic, PickupAddress: &models.Address{ StreetAddress1: "123 Main St", StreetAddress2: &streetAddress2, StreetAddress3: &streetAddress3, City: "Beverly Hills", State: "CA", - PostalCode: "90210", + PostalCode: beverlyHillsCAPostalCode, DestinationGbloc: models.StringPointer("JEAT"), }, DestinationAddress: &models.Address{ @@ -268,7 +275,7 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { StreetAddress3: &streetAddress3, City: "Beverly Hills", State: "CA", - PostalCode: "90210", + PostalCode: beverlyHillsCAPostalCode, DestinationGbloc: models.StringPointer("JEAT"), }, }) @@ -335,6 +342,14 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { Name: wasillaAlaskaPostalCode, }, }, + { + PostalCode: beverlyHillsCAPostalCode, + RateArea: &models.ReRateArea{ + ID: uuid.Must(uuid.NewV4()), + Code: beverlyHillsCAPostalCode, + Name: beverlyHillsCAPostalCode, + }, + }, } returnedModel = MoveTaskOrderWithShipmentRateAreas(suite.AppContextForTest(), newMove, &shipmentPostalCodeRateArea) @@ -1002,6 +1017,72 @@ func (suite *PayloadsSuite) TestMTOServiceItemDestSIT() { suite.Equal(finalAddress.PostalCode, *destSIT.SitDestinationFinalAddress.PostalCode) suite.Equal(mtoShipmentID.String(), destSIT.MtoShipmentID().String()) } + +func (suite *PayloadsSuite) TestMTOServiceItemInternationalDestSIT() { + reServiceCode := models.ReServiceCodeIDFSIT + reason := "reason" + dateOfContact1 := time.Now() + timeMilitary1 := "1500Z" + firstAvailableDeliveryDate1 := dateOfContact1.AddDate(0, 0, 10) + dateOfContact2 := time.Now().AddDate(0, 0, 5) + timeMilitary2 := "1300Z" + firstAvailableDeliveryDate2 := dateOfContact2.AddDate(0, 0, 10) + sitDepartureDate := time.Now().AddDate(0, 1, 0) + sitEntryDate := time.Now().AddDate(0, 0, -30) + finalAddress := models.Address{ + StreetAddress1: "dummyStreet", + City: "dummyCity", + State: "FL", + PostalCode: "55555", + } + mtoShipmentID := uuid.Must(uuid.NewV4()) + + mtoServiceItemDestSIT := &models.MTOServiceItem{ + ID: uuid.Must(uuid.NewV4()), + ReService: models.ReService{Code: reServiceCode}, + Reason: &reason, + SITDepartureDate: &sitDepartureDate, + SITEntryDate: &sitEntryDate, + SITDestinationFinalAddress: &finalAddress, + MTOShipmentID: &mtoShipmentID, + CustomerContacts: models.MTOServiceItemCustomerContacts{ + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact1, + TimeMilitary: timeMilitary1, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate1, + Type: models.CustomerContactTypeFirst, + }, + models.MTOServiceItemCustomerContact{ + DateOfContact: dateOfContact2, + TimeMilitary: timeMilitary2, + FirstAvailableDeliveryDate: firstAvailableDeliveryDate2, + Type: models.CustomerContactTypeSecond, + }, + }, + } + + resultDestSIT := MTOServiceItem(mtoServiceItemDestSIT) + suite.NotNil(resultDestSIT) + destSIT, ok := resultDestSIT.(*primev3messages.MTOServiceItemInternationalDestSIT) + suite.True(ok) + + suite.Equal(string(reServiceCode), string(*destSIT.ReServiceCode)) + suite.Equal(reason, *destSIT.Reason) + suite.Equal(strfmt.Date(sitDepartureDate).String(), destSIT.SitDepartureDate.String()) + suite.Equal(strfmt.Date(sitEntryDate).String(), destSIT.SitEntryDate.String()) + suite.Equal(strfmt.Date(dateOfContact1).String(), destSIT.DateOfContact1.String()) + suite.Equal(timeMilitary1, *destSIT.TimeMilitary1) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate1).String(), destSIT.FirstAvailableDeliveryDate1.String()) + suite.Equal(strfmt.Date(dateOfContact2).String(), destSIT.DateOfContact2.String()) + suite.Equal(timeMilitary2, *destSIT.TimeMilitary2) + suite.Equal(strfmt.Date(firstAvailableDeliveryDate2).String(), destSIT.FirstAvailableDeliveryDate2.String()) + suite.Equal(finalAddress.StreetAddress1, *destSIT.SitDestinationFinalAddress.StreetAddress1) + suite.Equal(finalAddress.City, *destSIT.SitDestinationFinalAddress.City) + suite.Equal(finalAddress.State, *destSIT.SitDestinationFinalAddress.State) + suite.Equal(finalAddress.PostalCode, *destSIT.SitDestinationFinalAddress.PostalCode) + suite.Equal(mtoShipmentID.String(), destSIT.MtoShipmentID().String()) +} + func (suite *PayloadsSuite) TestMTOServiceItemDCRT() { reServiceCode := models.ReServiceCodeDCRT reason := "reason" diff --git a/pkg/handlers/primeapiv3/payloads/payload_to_model.go b/pkg/handlers/primeapiv3/payloads/payload_to_model.go index 2acc20eb04a..84b22616fdd 100644 --- a/pkg/handlers/primeapiv3/payloads/payload_to_model.go +++ b/pkg/handlers/primeapiv3/payloads/payload_to_model.go @@ -727,7 +727,44 @@ func MTOServiceItemModel(mtoServiceItem primev3messages.MTOServiceItem) (*models if model.SITOriginHHGActualAddress != nil { model.SITOriginHHGActualAddressID = &model.SITOriginHHGActualAddress.ID } + case primev3messages.MTOServiceItemModelTypeMTOServiceItemInternationalOriginSIT: + originsit := mtoServiceItem.(*primev3messages.MTOServiceItemInternationalOriginSIT) + + if originsit.ReServiceCode != nil { + model.ReService.Code = models.ReServiceCode(*originsit.ReServiceCode) + } + + model.Reason = originsit.Reason + // Check for reason required field on a DDFSIT + if model.ReService.Code == models.ReServiceCodeDOASIT { + reasonVerrs := validateReasonInternationalOriginSIT(*originsit) + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + if model.ReService.Code == models.ReServiceCodeDOFSIT { + reasonVerrs := validateReasonInternationalOriginSIT(*originsit) + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + sitEntryDate := handlers.FmtDatePtrToPopPtr(originsit.SitEntryDate) + + if sitEntryDate != nil { + model.SITEntryDate = sitEntryDate + } + + model.SITPostalCode = originsit.SitPostalCode + + model.SITOriginHHGActualAddress = AddressModel(originsit.SitHHGActualOrigin) + if model.SITOriginHHGActualAddress != nil { + model.SITOriginHHGActualAddressID = &model.SITOriginHHGActualAddress.ID + } case primev3messages.MTOServiceItemModelTypeMTOServiceItemDestSIT: destsit := mtoServiceItem.(*primev3messages.MTOServiceItemDestSIT) @@ -782,6 +819,64 @@ func MTOServiceItemModel(mtoServiceItem primev3messages.MTOServiceItem) (*models model.SITDepartureDate = handlers.FmtDatePtrToPopPtr(destsit.SitDepartureDate) } + model.SITDestinationFinalAddress = AddressModel(destsit.SitDestinationFinalAddress) + if model.SITDestinationFinalAddress != nil { + model.SITDestinationFinalAddressID = &model.SITDestinationFinalAddress.ID + } + case primev3messages.MTOServiceItemModelTypeMTOServiceItemInternationalDestSIT: + destsit := mtoServiceItem.(*primev3messages.MTOServiceItemInternationalDestSIT) + + if destsit.ReServiceCode != nil { + model.ReService.Code = models.ReServiceCode(*destsit.ReServiceCode) + + } + + model.Reason = destsit.Reason + sitEntryDate := handlers.FmtDatePtrToPopPtr(destsit.SitEntryDate) + + // Check for required fields on a IDFSIT + if model.ReService.Code == models.ReServiceCodeIDFSIT { + verrs := validateIDFSITForCreate(*destsit) + reasonVerrs := validateReasonInternationalDestSIT(*destsit) + + if verrs.HasAny() { + return nil, verrs + } + + if reasonVerrs.HasAny() { + return nil, reasonVerrs + } + } + + var customerContacts models.MTOServiceItemCustomerContacts + + if destsit.TimeMilitary1 != nil && destsit.FirstAvailableDeliveryDate1 != nil && destsit.DateOfContact1 != nil { + customerContacts = append(customerContacts, models.MTOServiceItemCustomerContact{ + Type: models.CustomerContactTypeFirst, + DateOfContact: time.Time(*destsit.DateOfContact1), + TimeMilitary: *destsit.TimeMilitary1, + FirstAvailableDeliveryDate: time.Time(*destsit.FirstAvailableDeliveryDate1), + }) + } + if destsit.TimeMilitary2 != nil && destsit.FirstAvailableDeliveryDate2 != nil && destsit.DateOfContact2 != nil { + customerContacts = append(customerContacts, models.MTOServiceItemCustomerContact{ + Type: models.CustomerContactTypeSecond, + DateOfContact: time.Time(*destsit.DateOfContact2), + TimeMilitary: *destsit.TimeMilitary2, + FirstAvailableDeliveryDate: time.Time(*destsit.FirstAvailableDeliveryDate2), + }) + } + + model.CustomerContacts = customerContacts + + if sitEntryDate != nil { + model.SITEntryDate = sitEntryDate + } + + if destsit.SitDepartureDate != nil { + model.SITDepartureDate = handlers.FmtDatePtrToPopPtr(destsit.SitDepartureDate) + } + model.SITDestinationFinalAddress = AddressModel(destsit.SitDestinationFinalAddress) if model.SITDestinationFinalAddress != nil { model.SITDestinationFinalAddressID = &model.SITDestinationFinalAddress.ID @@ -1096,6 +1191,31 @@ func validateDDFSITForCreate(m primev3messages.MTOServiceItemDestSIT) *validate. return verrs } +// validateIDFSITForCreate validates IDFSIT service item has all required fields +func validateIDFSITForCreate(m primev3messages.MTOServiceItemInternationalDestSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.FirstAvailableDeliveryDate1 == nil && m.DateOfContact1 != nil && m.TimeMilitary1 != nil { + verrs.Add("firstAvailableDeliveryDate1", "firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 must be provided together in body.") + } + if m.DateOfContact1 == nil && m.TimeMilitary1 != nil && m.FirstAvailableDeliveryDate1 != nil { + verrs.Add("DateOfContact1", "dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 must be provided together in body.") + } + if m.TimeMilitary1 == nil && m.DateOfContact1 != nil && m.FirstAvailableDeliveryDate1 != nil { + verrs.Add("timeMilitary1", "timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 must be provided together in body.") + } + if m.FirstAvailableDeliveryDate2 == nil && m.DateOfContact2 != nil && m.TimeMilitary2 != nil { + verrs.Add("firstAvailableDeliveryDate2", "firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 must be provided together in body.") + } + if m.DateOfContact2 == nil && m.TimeMilitary2 != nil && m.FirstAvailableDeliveryDate2 != nil { + verrs.Add("DateOfContact1", "dateOfContact2, firstAvailableDeliveryDate2, and timeMilitary2 must be provided together in body.") + } + if m.TimeMilitary2 == nil && m.DateOfContact2 != nil && m.FirstAvailableDeliveryDate2 != nil { + verrs.Add("timeMilitary2", "timeMilitary2, firstAvailableDeliveryDate2, and dateOfContact2 must be provided together in body.") + } + return verrs +} + // validateDestSITForUpdate validates DDDSIT service item has all required fields func validateDestSITForUpdate(m primev3messages.UpdateMTOServiceItemSIT) *validate.Errors { verrs := validate.NewErrors() @@ -1131,6 +1251,16 @@ func validateReasonDestSIT(m primev3messages.MTOServiceItemDestSIT) *validate.Er return verrs } +// validateReasonInternationalDestSIT validates that International Destination SIT service items have required Reason field +func validateReasonInternationalDestSIT(m primev3messages.MTOServiceItemInternationalDestSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.Reason == nil || m.Reason == models.StringPointer("") { + verrs.Add("reason", "reason is required in body.") + } + return verrs +} + // validateReasonOriginSIT validates that Origin SIT service items have required Reason field func validateReasonOriginSIT(m primev3messages.MTOServiceItemOriginSIT) *validate.Errors { verrs := validate.NewErrors() @@ -1141,6 +1271,16 @@ func validateReasonOriginSIT(m primev3messages.MTOServiceItemOriginSIT) *validat return verrs } +// validateReasonInternationalOriginSIT validates that International Origin SIT service items have required Reason field +func validateReasonInternationalOriginSIT(m primev3messages.MTOServiceItemInternationalOriginSIT) *validate.Errors { + verrs := validate.NewErrors() + + if m.Reason == nil || m.Reason == models.StringPointer("") { + verrs.Add("reason", "reason is required in body.") + } + return verrs +} + // validateBoatShipmentType validates that the shipment type is a valid boat type, and is not nil. func validateBoatShipmentType(s primev3messages.MTOShipmentType) *validate.Errors { verrs := validate.NewErrors() diff --git a/pkg/handlers/primeapiv3/payloads/payload_to_model_test.go b/pkg/handlers/primeapiv3/payloads/payload_to_model_test.go index 4f12b050b83..2d99bd58d77 100644 --- a/pkg/handlers/primeapiv3/payloads/payload_to_model_test.go +++ b/pkg/handlers/primeapiv3/payloads/payload_to_model_test.go @@ -378,6 +378,32 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) }) + suite.Run("Success - Returns international SIT destination service item model", func() { + destSITServiceItem := &primev3messages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: &destServiceCode, + FirstAvailableDeliveryDate1: &destDate, + FirstAvailableDeliveryDate2: &destDate, + DateOfContact1: &destDate, + DateOfContact2: &destDate, + TimeMilitary1: &destTime, + TimeMilitary2: &destTime, + SitDestinationFinalAddress: &sitFinalDestAddress, + Reason: &destReason, + } + + destSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + destSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(destSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDDFSIT, returnedModel.ReService.Code) + suite.Equal(destPostalCode, returnedModel.SITDestinationFinalAddress.PostalCode) + suite.Equal(destStreet, returnedModel.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) + }) + suite.Run("Success - Returns SIT destination service item model without customer contact fields", func() { destSITServiceItem := &primev3messages.MTOServiceItemDestSIT{ ReServiceCode: &destServiceCode, @@ -398,6 +424,27 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) suite.Equal(destReason, *returnedModel.Reason) }) + + suite.Run("Success - Returns international SIT destination service item model without customer contact fields", func() { + destSITServiceItem := &primev3messages.MTOServiceItemInternationalDestSIT{ + ReServiceCode: &destServiceCode, + SitDestinationFinalAddress: &sitFinalDestAddress, + Reason: &destReason, + } + + destSITServiceItem.SetMoveTaskOrderID(handlers.FmtUUID(moveTaskOrderIDField)) + destSITServiceItem.SetMtoShipmentID(*mtoShipmentIDString) + returnedModel, verrs := MTOServiceItemModel(destSITServiceItem) + + suite.NoVerrs(verrs) + suite.Equal(moveTaskOrderIDField.String(), returnedModel.MoveTaskOrderID.String()) + suite.Equal(mtoShipmentIDField.String(), returnedModel.MTOShipmentID.String()) + suite.Equal(models.ReServiceCodeDDFSIT, returnedModel.ReService.Code) + suite.Equal(destPostalCode, returnedModel.SITDestinationFinalAddress.PostalCode) + suite.Equal(destStreet, returnedModel.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(destUSPRCID.String(), returnedModel.SITDestinationFinalAddress.UsPostRegionCityID.String()) + suite.Equal(destReason, *returnedModel.Reason) + }) } func (suite *PayloadsSuite) TestReweighModelFromUpdate() { @@ -724,6 +771,23 @@ func (suite *PayloadsSuite) TestValidateReasonOriginSIT() { verrs := validateReasonOriginSIT(mtoServiceItemOriginSIT) suite.True(verrs.HasAny()) }) + + suite.Run("Reason provided - international", func() { + reason := "reason" + mtoServiceItemOriginSIT := primev3messages.MTOServiceItemInternationalOriginSIT{ + Reason: &reason, + } + + verrs := validateReasonInternationalOriginSIT(mtoServiceItemOriginSIT) + suite.False(verrs.HasAny()) + }) + + suite.Run("No reason provided - international", func() { + mtoServiceItemOriginSIT := primev3messages.MTOServiceItemInternationalOriginSIT{} + + verrs := validateReasonInternationalOriginSIT(mtoServiceItemOriginSIT) + suite.True(verrs.HasAny()) + }) } func (suite *PayloadsSuite) TestShipmentAddressUpdateModel() { diff --git a/pkg/models/moving_expense.go b/pkg/models/moving_expense.go index 97ea06f1a38..92b4d5ab77c 100644 --- a/pkg/models/moving_expense.go +++ b/pkg/models/moving_expense.go @@ -29,6 +29,8 @@ const ( MovingExpenseReceiptTypeTolls MovingExpenseReceiptType = "TOLLS" // MovingExpenseReceiptTypeWeighingFee captures enum value "WEIGHING_FEE" MovingExpenseReceiptTypeWeighingFee MovingExpenseReceiptType = "WEIGHING_FEE" + // MovingExpenseReceiptTypeSmallPackage captures enum value "SMALL_PACKAGE" + MovingExpenseReceiptTypeSmallPackage MovingExpenseReceiptType = "SMALL_PACKAGE" // MovingExpenseReceiptTypeOther captures enum value "OTHER" MovingExpenseReceiptTypeOther MovingExpenseReceiptType = "OTHER" ) diff --git a/pkg/models/mto_shipments.go b/pkg/models/mto_shipments.go index 148f1130e65..1d7f6a2dada 100644 --- a/pkg/models/mto_shipments.go +++ b/pkg/models/mto_shipments.go @@ -48,6 +48,8 @@ var internationalAccessorialServiceItems = []ReServiceCode{ ReServiceCodeIDDSIT, ReServiceCodeIDSHUT, ReServiceCodeIOSHUT, + ReServiceCodeIOSFSC, + ReServiceCodeIDSFSC, } const ( diff --git a/pkg/models/ppm_shipment.go b/pkg/models/ppm_shipment.go index d53bdb5b3ac..ecb04cc45ca 100644 --- a/pkg/models/ppm_shipment.go +++ b/pkg/models/ppm_shipment.go @@ -180,9 +180,29 @@ type PPMDocuments struct { ProgearWeightTickets } +// PPMType represents the type of a PPM shipment +type PPMType string + +const ( + // PPMTypeIncentiveBased captures enum value "INCENTIVE_BASED" + PPMTypeIncentiveBased PPMType = "INCENTIVE_BASED" + // PPMTypeActualExpense captures enum value "ACTUAL_EXPENSE" + PPMTypeActualExpense PPMType = "ACTUAL_EXPENSE" + // PPMTypeSmallPackage captures enum value "SMALL_PACKAGE" + PPMTypeSmallPackage PPMType = "SMALL_PACKAGE" +) + +// AllowedPPMTypes is a list of all the allowed values for PPM types +var AllowedPPMTypes = []string{ + string(PPMTypeIncentiveBased), + string(PPMTypeActualExpense), + string(PPMTypeSmallPackage), +} + // PPMShipment is the portion of a move that a service member performs themselves type PPMShipment struct { ID uuid.UUID `json:"id" db:"id"` + PPMType PPMType `json:"ppm_type" db:"ppm_type"` ShipmentID uuid.UUID `json:"shipment_id" db:"shipment_id"` Shipment MTOShipment `belongs_to:"mto_shipments" fk_id:"shipment_id"` CreatedAt time.Time `json:"created_at" db:"created_at"` @@ -264,6 +284,7 @@ type PPMShipments []PPMShipment func (p PPMShipment) Validate(_ *pop.Connection) (*validate.Errors, error) { return validate.Validate( &validators.UUIDIsPresent{Name: "ShipmentID", Field: p.ShipmentID}, + &validators.StringInclusion{Name: "PPMType", Field: string(p.PPMType), List: AllowedPPMTypes}, &OptionalTimeIsPresent{Name: "DeletedAt", Field: p.DeletedAt}, &validators.TimeIsPresent{Name: "ExpectedDepartureDate", Field: p.ExpectedDepartureDate}, &validators.StringInclusion{Name: "Status", Field: string(p.Status), List: AllowedPPMShipmentStatuses}, diff --git a/pkg/models/ppm_shipment_test.go b/pkg/models/ppm_shipment_test.go index 7dbeb27f545..f4b2662a98b 100644 --- a/pkg/models/ppm_shipment_test.go +++ b/pkg/models/ppm_shipment_test.go @@ -29,6 +29,7 @@ func (suite *ModelSuite) TestPPMShipmentValidation() { }{ "Successful Minimal Validation": { ppmShipment: models.PPMShipment{ + PPMType: models.PPMTypeIncentiveBased, ShipmentID: uuid.Must(uuid.NewV4()), ExpectedDepartureDate: testdatagen.PeakRateCycleStart, Status: models.PPMShipmentStatusDraft, @@ -39,6 +40,7 @@ func (suite *ModelSuite) TestPPMShipmentValidation() { }, "Missing Required Fields": { ppmShipment: models.PPMShipment{ + PPMType: models.PPMTypeIncentiveBased, PickupAddressID: models.UUIDPointer(uuid.Nil), DestinationAddressID: models.UUIDPointer(uuid.Nil), }, @@ -53,6 +55,7 @@ func (suite *ModelSuite) TestPPMShipmentValidation() { "Optional fields raise errors with invalid values": { ppmShipment: models.PPMShipment{ // Setting up min required fields here so that we don't get these in our errors. + PPMType: models.PPMTypeIncentiveBased, ShipmentID: uuid.Must(uuid.NewV4()), ExpectedDepartureDate: testdatagen.PeakRateCycleStart, Status: models.PPMShipmentStatusDraft, diff --git a/pkg/models/transportation_office.go b/pkg/models/transportation_office.go index fe5ba6261ea..5490da6c743 100644 --- a/pkg/models/transportation_office.go +++ b/pkg/models/transportation_office.go @@ -70,3 +70,17 @@ func FetchNearestTransportationOffice(tx *pop.Connection, long float32, lat floa return to, nil } + +// GetCounselingOffices calls a db function that returns all the transportation offices in the GBLOC +// of the given duty location where provides_services_counseling = true +func GetCounselingOffices(db *pop.Connection, dutyLocationID uuid.UUID, serviceMemberID uuid.UUID) (TransportationOffices, error) { + var officeList TransportationOffices + + err := db.RawQuery("SELECT * FROM get_counseling_offices($1, $2)", dutyLocationID, serviceMemberID). + All(&officeList) + if err != nil { + return officeList, err + } + + return officeList, nil +} diff --git a/pkg/models/transportation_office_test.go b/pkg/models/transportation_office_test.go index b553d410b3e..32fc2e09cdb 100644 --- a/pkg/models/transportation_office_test.go +++ b/pkg/models/transportation_office_test.go @@ -10,6 +10,7 @@ package models_test import ( + "github.com/transcom/mymove/pkg/factory" m "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services/address" ) @@ -78,3 +79,123 @@ func (suite *ModelSuite) Test_TransportationOffice() { suite.Equal(ppo.ID, loadedOffice.ID) suite.Equal(jppso.ID, loadedOffice.ShippingOffice.ID) } + +func (suite *ModelSuite) TestGetCounselingOffices() { + customAddress1 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: m.Address{ + PostalCode: "59801", + }, + }, + }, nil) + factory.BuildDutyLocation(suite.DB(), []factory.Customization{ + { + Model: m.DutyLocation{ + ProvidesServicesCounseling: false, + }, + }, + { + Model: m.TransportationOffice{ + Name: "PPPO Holloman AFB - USAF", + }, + }, + { + Model: customAddress1, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, + }, nil) + + // duty locations in KKFA with provides_services_counseling = true + customAddress2 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: m.Address{ + PostalCode: "59801", + }, + }, + }, nil) + factory.BuildDutyLocation(suite.DB(), []factory.Customization{ + { + Model: m.DutyLocation{ + ProvidesServicesCounseling: true, + }, + }, + { + Model: m.TransportationOffice{ + Name: "PPPO Hill AFB - USAF", + }, + }, + { + Model: customAddress2, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, + }, nil) + + customAddress3 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: m.Address{ + PostalCode: "59801", + }, + }, + }, nil) + origDutyLocation := factory.BuildDutyLocation(suite.DB(), []factory.Customization{ + { + Model: m.DutyLocation{ + ProvidesServicesCounseling: true, + }, + }, + { + Model: m.TransportationOffice{ + Name: "PPPO Travis AFB - USAF", + Gbloc: "KKFA", + ProvidesCloseout: true, + }, + }, + { + Model: customAddress3, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, + }, nil) + + // this one will not show in the return since it is not KKFA + customAddress4 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: m.Address{ + PostalCode: "20906", + }, + }, + }, nil) + factory.BuildDutyLocation(suite.DB(), []factory.Customization{ + { + Model: m.DutyLocation{ + ProvidesServicesCounseling: true, + }, + }, + { + Model: m.TransportationOffice{ + Name: "PPPO Fort Meade - USA", + Gbloc: "BGCA", + ProvidesCloseout: true, + }, + }, + { + Model: customAddress4, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, + }, nil) + + armyAffliation := m.AffiliationARMY + serviceMember := factory.BuildServiceMember(suite.DB(), []factory.Customization{ + { + Model: m.ServiceMember{ + Affiliation: &armyAffliation, + }, + }, + }, nil) + offices, err := m.GetCounselingOffices(suite.DB(), origDutyLocation.ID, serviceMember.ID) + suite.NoError(err) + suite.Len(offices, 2) +} diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 8944ad1b1bc..f10ccdd8bbc 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -57,7 +57,7 @@ type DomesticLinehaulPricer interface { // //go:generate mockery --name DomesticShorthaulPricer type DomesticShorthaulPricer interface { - Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string, isPPM bool) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/domestic_shorthaul_pricer.go b/pkg/services/ghcrateengine/domestic_shorthaul_pricer.go index 44aa7d161b6..08600956811 100644 --- a/pkg/services/ghcrateengine/domestic_shorthaul_pricer.go +++ b/pkg/services/ghcrateengine/domestic_shorthaul_pricer.go @@ -28,7 +28,8 @@ func (p domesticShorthaulPricer) Price(appCtx appcontext.AppContext, contractCod referenceDate time.Time, distance unit.Miles, weight unit.Pound, - serviceArea string) (totalCost unit.Cents, params services.PricingDisplayParams, err error) { + serviceArea string, + isPPM bool) (totalCost unit.Cents, params services.PricingDisplayParams, err error) { // Validate parameters if len(contractCode) == 0 { return 0, nil, errors.New("ContractCode is required") @@ -36,7 +37,7 @@ func (p domesticShorthaulPricer) Price(appCtx appcontext.AppContext, contractCod if referenceDate.IsZero() { return 0, nil, errors.New("ReferenceDate is required") } - if weight < minDomesticWeight { + if !isPPM && weight < minDomesticWeight { return 0, nil, fmt.Errorf("Weight must be a minimum of %d", minDomesticWeight) } if distance <= 0 { @@ -110,5 +111,13 @@ func (p domesticShorthaulPricer) PriceUsingParams(appCtx appcontext.AppContext, return unit.Cents(0), nil, err } - return p.Price(appCtx, contractCode, referenceDate, unit.Miles(distanceZip), unit.Pound(weightBilled), serviceAreaOrigin) + var isPPM = false + if params[0].PaymentServiceItem.MTOServiceItem.MTOShipment.ShipmentType == models.MTOShipmentTypePPM { + // PPMs do not require minimums for a shipment's weight or distance + // this flag is passed into the Price function to ensure the weight and distance mins + // are not enforced for PPMs + isPPM = true + } + + return p.Price(appCtx, contractCode, referenceDate, unit.Miles(distanceZip), unit.Pound(weightBilled), serviceAreaOrigin, isPPM) } diff --git a/pkg/services/ghcrateengine/domestic_shorthaul_pricer_test.go b/pkg/services/ghcrateengine/domestic_shorthaul_pricer_test.go index 7f43328515a..d8f157f2682 100644 --- a/pkg/services/ghcrateengine/domestic_shorthaul_pricer_test.go +++ b/pkg/services/ghcrateengine/domestic_shorthaul_pricer_test.go @@ -17,6 +17,8 @@ const ( dshTestMileage = 1200 ) +var dshRequestedPickupDate = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) + func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaulWithServiceItemParamsBadData() { requestedPickup := time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC).Format(DateParamFormat) pricer := NewDomesticShorthaulPricer() @@ -120,6 +122,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaulWithServiceIte } func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { + isPPM := false suite.Run("success shorthaul cost within peak period", func() { requestedPickup := time.Date(testdatagen.TestYear, peakStart.month, peakStart.day, 0, 0, 0, 0, time.UTC).Format(DateParamFormat) suite.setUpDomesticShorthaulData() @@ -135,6 +138,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { dshTestMileage, dshTestWeight, dshTestServiceArea, + isPPM, ) expectedCost := unit.Cents(6566400) suite.NoError(err) @@ -158,6 +162,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { dshTestMileage, dshTestWeight, dshTestServiceArea, + isPPM, ) expectedCost := unit.Cents(5702400) suite.NoError(err) @@ -176,6 +181,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { dshTestMileage, dshTestWeight, dshTestServiceArea, + isPPM, ) suite.Error(err) @@ -194,6 +200,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { dshTestMileage, dshTestWeight, dshTestServiceArea, + isPPM, ) suite.Error(err) @@ -212,6 +219,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { dshTestMileage, unit.Pound(499), dshTestServiceArea, + isPPM, ) suite.Equal(unit.Cents(0), cost) suite.Error(err) @@ -219,6 +227,24 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { suite.Nil(rateEngineParams) }) + suite.Run("successfully finds shorthaul price for ppm with weight < 500 lbs with Price method", func() { + suite.setUpDomesticShorthaulData() + pricer := NewDomesticShorthaulPricer() + isPPM = true + // the PPM price for weights < 500 should be prorated from a base of 500 + basePriceCents, _, err := pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, dshRequestedPickupDate, dshTestMileage, unit.Pound(500), dshTestServiceArea, isPPM) + suite.NoError(err) + + halfPriceCents, _, err := pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, dshRequestedPickupDate, dshTestMileage, unit.Pound(250), dshTestServiceArea, isPPM) + suite.NoError(err) + suite.Equal(basePriceCents/2, halfPriceCents) + + fifthPriceCents, _, err := pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, dshRequestedPickupDate, dshTestMileage, unit.Pound(100), dshTestServiceArea, isPPM) + suite.NoError(err) + suite.Equal(basePriceCents/5, fifthPriceCents) + isPPM = false + }) + suite.Run("validation errors", func() { suite.setUpDomesticShorthaulData() pricer := NewDomesticShorthaulPricer() @@ -226,31 +252,31 @@ func (suite *GHCRateEngineServiceSuite) TestPriceDomesticShorthaul() { requestedPickupDate := time.Date(testdatagen.TestYear, time.July, 4, 0, 0, 0, 0, time.UTC) // No contract code - _, rateEngineParams, err := pricer.Price(suite.AppContextForTest(), "", requestedPickupDate, dshTestMileage, dshTestWeight, dshTestServiceArea) + _, rateEngineParams, err := pricer.Price(suite.AppContextForTest(), "", requestedPickupDate, dshTestMileage, dshTestWeight, dshTestServiceArea, isPPM) suite.Error(err) suite.Equal("ContractCode is required", err.Error()) suite.Nil(rateEngineParams) // No reference date - _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, time.Time{}, dshTestMileage, dshTestWeight, dshTestServiceArea) + _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, time.Time{}, dshTestMileage, dshTestWeight, dshTestServiceArea, isPPM) suite.Error(err) suite.Equal("ReferenceDate is required", err.Error()) suite.Nil(rateEngineParams) // No distance - _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, requestedPickupDate, 0, dshTestWeight, dshTestServiceArea) + _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, requestedPickupDate, 0, dshTestWeight, dshTestServiceArea, isPPM) suite.Error(err) suite.Equal("Distance must be greater than 0", err.Error()) suite.Nil(rateEngineParams) // No weight - _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, requestedPickupDate, dshTestMileage, 0, dshTestServiceArea) + _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, requestedPickupDate, dshTestMileage, 0, dshTestServiceArea, isPPM) suite.Error(err) suite.Equal("Weight must be a minimum of 500", err.Error()) suite.Nil(rateEngineParams) // No service area - _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, requestedPickupDate, dshTestMileage, dshTestWeight, "") + _, rateEngineParams, err = pricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, requestedPickupDate, dshTestMileage, dshTestWeight, "", isPPM) suite.Error(err) suite.Equal("ServiceArea is required", err.Error()) suite.Nil(rateEngineParams) diff --git a/pkg/services/ghcrateengine/pricer_helpers.go b/pkg/services/ghcrateengine/pricer_helpers.go index cb804b0da49..9f88767d652 100644 --- a/pkg/services/ghcrateengine/pricer_helpers.go +++ b/pkg/services/ghcrateengine/pricer_helpers.go @@ -267,7 +267,8 @@ func priceDomesticPickupDeliverySIT(appCtx appcontext.AppContext, pickupDelivery if zip3Original == zip3Actual { // Do a normal shorthaul calculation shorthaulPricer := NewDomesticShorthaulPricer() - totalPriceCents, displayParams, err := shorthaulPricer.Price(appCtx, contractCode, referenceDate, distance, weight, serviceArea) + isPPM := false + totalPriceCents, displayParams, err := shorthaulPricer.Price(appCtx, contractCode, referenceDate, distance, weight, serviceArea, isPPM) if err != nil { return unit.Cents(0), nil, fmt.Errorf("could not price shorthaul: %w", err) } diff --git a/pkg/services/mocks/DomesticShorthaulPricer.go b/pkg/services/mocks/DomesticShorthaulPricer.go index 029872ef7e4..5ffc3ad9536 100644 --- a/pkg/services/mocks/DomesticShorthaulPricer.go +++ b/pkg/services/mocks/DomesticShorthaulPricer.go @@ -20,9 +20,9 @@ type DomesticShorthaulPricer struct { mock.Mock } -// Price provides a mock function with given fields: appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea -func (_m *DomesticShorthaulPricer) Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string) (unit.Cents, services.PricingDisplayParams, error) { - ret := _m.Called(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea) +// Price provides a mock function with given fields: appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea, isPPM +func (_m *DomesticShorthaulPricer) Price(appCtx appcontext.AppContext, contractCode string, requestedPickupDate time.Time, distance unit.Miles, weight unit.Pound, serviceArea string, isPPM bool) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea, isPPM) if len(ret) == 0 { panic("no return value specified for Price") @@ -31,25 +31,25 @@ func (_m *DomesticShorthaulPricer) Price(appCtx appcontext.AppContext, contractC var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string) (unit.Cents, services.PricingDisplayParams, error)); ok { - return rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string, bool) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea, isPPM) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string) unit.Cents); ok { - r0 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string, bool) unit.Cents); ok { + r0 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea, isPPM) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string) services.PricingDisplayParams); ok { - r1 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string, bool) services.PricingDisplayParams); ok { + r1 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea, isPPM) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(services.PricingDisplayParams) } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string) error); ok { - r2 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea) + if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time, unit.Miles, unit.Pound, string, bool) error); ok { + r2 = rf(appCtx, contractCode, requestedPickupDate, distance, weight, serviceArea, isPPM) } else { r2 = ret.Error(2) } diff --git a/pkg/services/mto_service_item/mto_service_item_creator.go b/pkg/services/mto_service_item/mto_service_item_creator.go index 6e5415a5916..d4966974691 100644 --- a/pkg/services/mto_service_item/mto_service_item_creator.go +++ b/pkg/services/mto_service_item/mto_service_item_creator.go @@ -3,6 +3,7 @@ package mtoserviceitem import ( "database/sql" "fmt" + "slices" "strconv" "time" @@ -151,7 +152,7 @@ func (o *mtoServiceItemCreator) FindEstimatedPrice(appCtx appcontext.AppContext, return 0, err } } - price, _, err = o.shorthaulPricer.Price(appCtx, contractCode, requestedPickupDate, unit.Miles(distance), *adjustedWeight, domesticServiceArea.ServiceArea) + price, _, err = o.shorthaulPricer.Price(appCtx, contractCode, requestedPickupDate, unit.Miles(distance), *adjustedWeight, domesticServiceArea.ServiceArea, isPPM) if err != nil { return 0, err } @@ -450,22 +451,35 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex // checking to see if the service item being created is a destination SIT // if so, we want the destination address to be the same as the shipment's // which will later populate the additional dest SIT service items as well - if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT && mtoShipment.DestinationAddressID != nil { + if (serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || serviceItem.ReService.Code == models.ReServiceCodeIDFSIT) && + mtoShipment.DestinationAddressID != nil { serviceItem.SITDestinationFinalAddress = mtoShipment.DestinationAddress serviceItem.SITDestinationFinalAddressID = mtoShipment.DestinationAddressID } - if serviceItem.ReService.Code == models.ReServiceCodeDOASIT { + if serviceItem.ReService.Code == models.ReServiceCodeDOASIT || serviceItem.ReService.Code == models.ReServiceCodeIOASIT { + // validation mappings // DOASIT must be associated with shipment that has DOFSIT - serviceItem, err = o.validateSITStandaloneServiceItem(appCtx, serviceItem, models.ReServiceCodeDOFSIT) + // IOASIT must be associated with shipment that has IOFSIT + m := make(map[models.ReServiceCode]models.ReServiceCode) + m[models.ReServiceCodeDOASIT] = models.ReServiceCodeDOFSIT + m[models.ReServiceCodeIOASIT] = models.ReServiceCodeIOFSIT + + serviceItem, err = o.validateSITStandaloneServiceItem(appCtx, serviceItem, m[serviceItem.ReService.Code]) if err != nil { return nil, nil, err } } - if serviceItem.ReService.Code == models.ReServiceCodeDDASIT { + if serviceItem.ReService.Code == models.ReServiceCodeDDASIT || serviceItem.ReService.Code == models.ReServiceCodeIDASIT { + // validation mappings // DDASIT must be associated with shipment that has DDFSIT - serviceItem, err = o.validateSITStandaloneServiceItem(appCtx, serviceItem, models.ReServiceCodeDDFSIT) + // IDASIT must be associated with shipment that has IDFSIT + m := make(map[models.ReServiceCode]models.ReServiceCode) + m[models.ReServiceCodeDDASIT] = models.ReServiceCodeDDFSIT + m[models.ReServiceCodeIDASIT] = models.ReServiceCodeIDFSIT + + serviceItem, err = o.validateSITStandaloneServiceItem(appCtx, serviceItem, m[serviceItem.ReService.Code]) if err != nil { return nil, nil, err } @@ -480,7 +494,9 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex } if serviceItem.ReService.Code == models.ReServiceCodeDDDSIT || serviceItem.ReService.Code == models.ReServiceCodeDOPSIT || - serviceItem.ReService.Code == models.ReServiceCodeDDSFSC || serviceItem.ReService.Code == models.ReServiceCodeDOSFSC { + serviceItem.ReService.Code == models.ReServiceCodeDDSFSC || serviceItem.ReService.Code == models.ReServiceCodeDOSFSC || + serviceItem.ReService.Code == models.ReServiceCodeIDDSIT || serviceItem.ReService.Code == models.ReServiceCodeIOPSIT || + serviceItem.ReService.Code == models.ReServiceCodeIDSFSC || serviceItem.ReService.Code == models.ReServiceCodeIOSFSC { verrs = validate.NewErrors() verrs.Add("reServiceCode", fmt.Sprintf("%s cannot be created", serviceItem.ReService.Code)) return nil, nil, apperror.NewInvalidInputError(serviceItem.ID, nil, verrs, @@ -488,15 +504,19 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex } updateShipmentPickupAddress := false - if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || serviceItem.ReService.Code == models.ReServiceCodeDOFSIT { + if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || + serviceItem.ReService.Code == models.ReServiceCodeDOFSIT || + serviceItem.ReService.Code == models.ReServiceCodeIDFSIT || + serviceItem.ReService.Code == models.ReServiceCodeIOFSIT { extraServiceItems, errSIT := o.validateFirstDaySITServiceItem(appCtx, serviceItem) if errSIT != nil { return nil, nil, errSIT } - // update HHG origin address for ReServiceCodeDOFSIT service item - if serviceItem.ReService.Code == models.ReServiceCodeDOFSIT { - // When creating a DOFSIT, the prime must provide an HHG actual address for the move/shift in origin (pickup address) + // update HHG origin address for ReServiceCodeDOFSIT/ReServiceCodeIOFSIT service item + if serviceItem.ReService.Code == models.ReServiceCodeDOFSIT || + serviceItem.ReService.Code == models.ReServiceCodeIOFSIT { + // When creating a DOFSIT/IOFSIT, the prime must provide an HHG actual address for the move/shift in origin (pickup address) if serviceItem.SITOriginHHGActualAddress == nil { verrs = validate.NewErrors() verrs.Add("reServiceCode", fmt.Sprintf("%s cannot be created", serviceItem.ReService.Code)) @@ -545,13 +565,16 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex // changes were made to the shipment, needs to be saved to the database updateShipmentPickupAddress = true - // Find the DOPSIT service item and update the SIT related address fields. These fields - // will be used for pricing when a payment request is created for DOPSIT + // Find the DOPSIT/IOPSIT service item and update the SIT related address fields. These fields + // will be used for pricing when a payment request is created for DOPSIT/IOPSIT for itemIndex := range *extraServiceItems { extraServiceItem := &(*extraServiceItems)[itemIndex] if extraServiceItem.ReService.Code == models.ReServiceCodeDOPSIT || extraServiceItem.ReService.Code == models.ReServiceCodeDOASIT || - extraServiceItem.ReService.Code == models.ReServiceCodeDOSFSC { + extraServiceItem.ReService.Code == models.ReServiceCodeDOSFSC || + extraServiceItem.ReService.Code == models.ReServiceCodeIOPSIT || + extraServiceItem.ReService.Code == models.ReServiceCodeIOASIT || + extraServiceItem.ReService.Code == models.ReServiceCodeIOSFSC { extraServiceItem.SITOriginHHGActualAddress = serviceItem.SITOriginHHGActualAddress extraServiceItem.SITOriginHHGActualAddressID = serviceItem.SITOriginHHGActualAddressID extraServiceItem.SITOriginHHGOriginalAddress = serviceItem.SITOriginHHGOriginalAddress @@ -561,12 +584,17 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex } // make sure SITDestinationFinalAddress is the same for all destination SIT related service item - if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT && serviceItem.SITDestinationFinalAddress != nil { + if (serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || serviceItem.ReService.Code == models.ReServiceCodeIDFSIT) && + serviceItem.SITDestinationFinalAddress != nil { for itemIndex := range *extraServiceItems { extraServiceItem := &(*extraServiceItems)[itemIndex] + // handle both domestic and internationl(OCONUS) if extraServiceItem.ReService.Code == models.ReServiceCodeDDDSIT || extraServiceItem.ReService.Code == models.ReServiceCodeDDASIT || - extraServiceItem.ReService.Code == models.ReServiceCodeDDSFSC { + extraServiceItem.ReService.Code == models.ReServiceCodeDDSFSC || + extraServiceItem.ReService.Code == models.ReServiceCodeIDDSIT || + extraServiceItem.ReService.Code == models.ReServiceCodeIDASIT || + extraServiceItem.ReService.Code == models.ReServiceCodeIDSFSC { extraServiceItem.SITDestinationFinalAddress = serviceItem.SITDestinationFinalAddress extraServiceItem.SITDestinationFinalAddressID = serviceItem.SITDestinationFinalAddressID } @@ -576,11 +604,13 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex milesCalculated, errCalcSITDelivery := o.calculateSITDeliveryMiles(appCtx, serviceItem, mtoShipment) // only calculate SITDeliveryMiles for DOPSIT and DOSFSC origin service items - if serviceItem.ReService.Code == models.ReServiceCodeDOFSIT && milesCalculated != 0 { + if (serviceItem.ReService.Code == models.ReServiceCodeDOFSIT || serviceItem.ReService.Code == models.ReServiceCodeIOFSIT) && + milesCalculated != 0 { for itemIndex := range *extraServiceItems { extraServiceItem := &(*extraServiceItems)[itemIndex] - if extraServiceItem.ReService.Code == models.ReServiceCodeDOPSIT || - extraServiceItem.ReService.Code == models.ReServiceCodeDOSFSC { + if extraServiceItem.ReService.Code == models.ReServiceCodeDOPSIT || extraServiceItem.ReService.Code == models.ReServiceCodeIOPSIT || + extraServiceItem.ReService.Code == models.ReServiceCodeDOSFSC || + extraServiceItem.ReService.Code == models.ReServiceCodeIOSFSC { if milesCalculated > 0 && errCalcSITDelivery == nil { extraServiceItem.SITDeliveryMiles = &milesCalculated } @@ -589,11 +619,12 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex } // only calculate SITDeliveryMiles for DDDSIT and DDSFSC destination service items - if serviceItem.ReService.Code == models.ReServiceCodeDDFSIT && milesCalculated != 0 { + if (serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || serviceItem.ReService.Code == models.ReServiceCodeIDFSIT) && milesCalculated != 0 { for itemIndex := range *extraServiceItems { extraServiceItem := &(*extraServiceItems)[itemIndex] - if extraServiceItem.ReService.Code == models.ReServiceCodeDDDSIT || - extraServiceItem.ReService.Code == models.ReServiceCodeDDSFSC { + if extraServiceItem.ReService.Code == models.ReServiceCodeDDDSIT || extraServiceItem.ReService.Code == models.ReServiceCodeIDDSIT || + extraServiceItem.ReService.Code == models.ReServiceCodeDDSFSC || + extraServiceItem.ReService.Code == models.ReServiceCodeIDSFSC { if milesCalculated > 0 && errCalcSITDelivery == nil { extraServiceItem.SITDeliveryMiles = &milesCalculated } @@ -675,11 +706,15 @@ func (o *mtoServiceItemCreator) CreateMTOServiceItem(appCtx appcontext.AppContex } if mtoShipment.MarketCode == models.MarketCodeInternational { - createdInternationalServiceItemIds, err = models.CreateInternationalAccessorialServiceItemsForShipment(appCtx.DB(), *serviceItem.MTOShipmentID, models.MTOServiceItems{*serviceItem}) + createdInternationalServiceItemIds, err = models.CreateInternationalAccessorialServiceItemsForShipment(appCtx.DB(), *requestedServiceItem.MTOShipmentID, models.MTOServiceItems{*requestedServiceItem}) if err != nil { return err } } else { + if isInternationalServiceItem(requestedServiceItem) { + err := fmt.Errorf("cannot create international service items for domestic shipment: %s", mtoShipment.ID) + return apperror.NewInvalidInputError(mtoShipment.ID, err, nil, err.Error()) + } verrs, err = o.builder.CreateOne(txnAppCtx, requestedServiceItem) if verrs != nil || err != nil { return fmt.Errorf("%#v %e", verrs, err) @@ -940,6 +975,10 @@ func (o *mtoServiceItemCreator) validateFirstDaySITServiceItem(appCtx appcontext reServiceCodes = append(reServiceCodes, models.ReServiceCodeDDASIT, models.ReServiceCodeDDDSIT, models.ReServiceCodeDDSFSC) case models.ReServiceCodeDOFSIT: reServiceCodes = append(reServiceCodes, models.ReServiceCodeDOASIT, models.ReServiceCodeDOPSIT, models.ReServiceCodeDOSFSC) + case models.ReServiceCodeIDFSIT: + reServiceCodes = append(reServiceCodes, models.ReServiceCodeIDASIT, models.ReServiceCodeIDDSIT, models.ReServiceCodeIDSFSC) + case models.ReServiceCodeIOFSIT: + reServiceCodes = append(reServiceCodes, models.ReServiceCodeIOASIT, models.ReServiceCodeIOPSIT, models.ReServiceCodeIOSFSC) default: verrs := validate.NewErrors() verrs.Add("reServiceCode", fmt.Sprintf("%s invalid code", serviceItem.ReService.Code)) @@ -979,3 +1018,21 @@ func GetAdjustedWeight(incomingWeight unit.Pound, isUB bool) *unit.Pound { } return adjustedWeight } + +func isInternationalServiceItem(serviceItem *models.MTOServiceItem) bool { + var internationalAccessorialServiceItems = []models.ReServiceCode{ + models.ReServiceCodeICRT, + models.ReServiceCodeIUCRT, + models.ReServiceCodeIOASIT, + models.ReServiceCodeIDASIT, + models.ReServiceCodeIOFSIT, + models.ReServiceCodeIDFSIT, + models.ReServiceCodeIOPSIT, + models.ReServiceCodeIDDSIT, + models.ReServiceCodeIDSHUT, + models.ReServiceCodeIOSHUT, + models.ReServiceCodeIOSFSC, + models.ReServiceCodeIDSFSC, + } + return slices.Contains(internationalAccessorialServiceItems, serviceItem.ReService.Code) +} diff --git a/pkg/services/mto_service_item/mto_service_item_creator_test.go b/pkg/services/mto_service_item/mto_service_item_creator_test.go index c785f78ec1b..463e06e9090 100644 --- a/pkg/services/mto_service_item/mto_service_item_creator_test.go +++ b/pkg/services/mto_service_item/mto_service_item_creator_test.go @@ -112,6 +112,45 @@ func (suite *MTOServiceItemServiceSuite) buildValidDDFSITServiceItemWithValidMov return serviceItem } +func (suite *MTOServiceItemServiceSuite) buildValidIDFSITServiceItemWithValidMove() models.MTOServiceItem { + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + dimension := models.MTOServiceItemDimension{ + Type: models.DimensionTypeItem, + Length: 12000, + Height: 12000, + Width: 12000, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + reServiceIDFSIT := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeIDFSIT) + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + }, nil) + destAddress := factory.BuildDefaultAddress(suite.DB()) + + serviceItem := models.MTOServiceItem{ + MoveTaskOrderID: move.ID, + MoveTaskOrder: move, + ReService: reServiceIDFSIT, + MTOShipmentID: &shipment.ID, + MTOShipment: shipment, + Dimensions: models.MTOServiceItemDimensions{dimension}, + Status: models.MTOServiceItemStatusSubmitted, + SITDestinationFinalAddressID: &destAddress.ID, + SITDestinationFinalAddress: &destAddress, + } + + return serviceItem +} + func (suite *MTOServiceItemServiceSuite) buildValidDOSHUTServiceItemWithValidMove() models.MTOServiceItem { move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) reServiceDOSHUT := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDOSHUT) @@ -281,6 +320,60 @@ func (suite *MTOServiceItemServiceSuite) TestCreateMTOServiceItem() { suite.Equal(numDDSFSCFound, 1) }) + suite.Run("200 Success - International Destination SIT Service Item Creation", func() { + + // TESTCASE SCENARIO + // Under test: CreateMTOServiceItem function + // Set up: We create an approved move and attempt to create IDFSIT service item on it. Includes Dimensions + // and a SITDestinationFinalAddress + // Expected outcome: + // 4 SIT items are created, status of move is APPROVALS_REQUESTED + + sitServiceItem := suite.buildValidIDFSITServiceItemWithValidMove() + sitMove := sitServiceItem.MoveTaskOrder + sitShipment := sitServiceItem.MTOShipment + + createdServiceItems, verrs, err := creator.CreateMTOServiceItem(suite.AppContextForTest(), &sitServiceItem) + suite.NoError(err) + suite.Nil(verrs) + suite.NotNil(createdServiceItems) + + var foundMove models.Move + err = suite.DB().Find(&foundMove, sitMove.ID) + suite.NoError(err) + + createdServiceItemList := *createdServiceItems + suite.Equal(len(createdServiceItemList), 4) + suite.Equal(models.MoveStatusAPPROVALSREQUESTED, foundMove.Status) + + numIDFSITFound := 0 + numIDASITFound := 0 + numIDDSITFound := 0 + numIDSFSCFound := 0 + + for _, createdServiceItem := range createdServiceItemList { + // checking that the service item final destination address equals the shipment's final destination address + suite.Equal(sitShipment.DestinationAddress.StreetAddress1, createdServiceItem.SITDestinationFinalAddress.StreetAddress1) + suite.Equal(sitShipment.DestinationAddressID, createdServiceItem.SITDestinationFinalAddressID) + + switch createdServiceItem.ReService.Code { + case models.ReServiceCodeIDFSIT: + suite.NotEmpty(createdServiceItem.Dimensions) + numIDFSITFound++ + case models.ReServiceCodeIDASIT: + numIDASITFound++ + case models.ReServiceCodeIDDSIT: + numIDDSITFound++ + case models.ReServiceCodeIDSFSC: + numIDSFSCFound++ + } + } + suite.Equal(numIDASITFound, 1) + suite.Equal(numIDDSITFound, 1) + suite.Equal(numIDFSITFound, 1) + suite.Equal(numIDSFSCFound, 1) + }) + // Happy path: If the service item is created successfully it should be returned suite.Run("200 Success - SHUT Service Item Creation", func() { @@ -1975,6 +2068,122 @@ func (suite *MTOServiceItemServiceSuite) TestCreateDestSITServiceItem() { suite.NotEmpty(invalidInputError.ValidationErrors) suite.Contains(invalidInputError.ValidationErrors.Keys(), "reServiceCode") }) + + suite.Run("Failure - cannot create domestic service item international domestic shipment", func() { + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + dimension := models.MTOServiceItemDimension{ + Type: models.DimensionTypeItem, + Length: 12000, + Height: 12000, + Width: 12000, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + + // setup domestic shipment + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + }, nil) + destAddress := factory.BuildDefaultAddress(suite.DB()) + + // setup international service item. must fail validation for a domestic shipment + reServiceDDFSIT := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeDDFSIT) + internationalServiceItem := models.MTOServiceItem{ + MoveTaskOrderID: move.ID, + MoveTaskOrder: move, + ReService: reServiceDDFSIT, + MTOShipmentID: &shipment.ID, + MTOShipment: shipment, + Dimensions: models.MTOServiceItemDimensions{dimension}, + Status: models.MTOServiceItemStatusSubmitted, + SITDestinationFinalAddressID: &destAddress.ID, + SITDestinationFinalAddress: &destAddress, + } + + builder := query.NewQueryBuilder() + moveRouter := moverouter.NewMoveRouter() + planner := &mocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + ).Return(400, nil) + creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + + createdServiceItems, _, err := creator.CreateMTOServiceItem(suite.AppContextForTest(), &internationalServiceItem) + suite.Nil(createdServiceItems) + suite.Error(err) + suite.IsType(apperror.InvalidInputError{}, err) + + suite.Contains(err.Error(), "cannot create domestic service items for international shipment") + }) + + suite.Run("Failure - cannot create international service item for domestic shipment", func() { + move := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + dimension := models.MTOServiceItemDimension{ + Type: models.DimensionTypeItem, + Length: 12000, + Height: 12000, + Width: 12000, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + + // setup domestic shipment + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeDomestic, + }, + }, + }, nil) + destAddress := factory.BuildDefaultAddress(suite.DB()) + + // setup international service item. must fail validation for a domestic shipment + reServiceIDFSIT := factory.FetchReServiceByCode(suite.DB(), models.ReServiceCodeIDFSIT) + internationalServiceItem := models.MTOServiceItem{ + MoveTaskOrderID: move.ID, + MoveTaskOrder: move, + ReService: reServiceIDFSIT, + MTOShipmentID: &shipment.ID, + MTOShipment: shipment, + Dimensions: models.MTOServiceItemDimensions{dimension}, + Status: models.MTOServiceItemStatusSubmitted, + SITDestinationFinalAddressID: &destAddress.ID, + SITDestinationFinalAddress: &destAddress, + } + + builder := query.NewQueryBuilder() + moveRouter := moverouter.NewMoveRouter() + planner := &mocks.Planner{} + planner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + mock.Anything, + mock.Anything, + false, + ).Return(400, nil) + creator := NewMTOServiceItemCreator(planner, builder, moveRouter, ghcrateengine.NewDomesticUnpackPricer(), ghcrateengine.NewDomesticPackPricer(), ghcrateengine.NewDomesticLinehaulPricer(), ghcrateengine.NewDomesticShorthaulPricer(), ghcrateengine.NewDomesticOriginPricer(), ghcrateengine.NewDomesticDestinationPricer(), ghcrateengine.NewFuelSurchargePricer()) + + createdServiceItems, _, err := creator.CreateMTOServiceItem(suite.AppContextForTest(), &internationalServiceItem) + suite.Nil(createdServiceItems) + suite.Error(err) + suite.IsType(apperror.InvalidInputError{}, err) + + suite.Contains(err.Error(), "cannot create international service items for domestic shipment") + }) } func (suite *MTOServiceItemServiceSuite) TestPriceEstimator() { diff --git a/pkg/services/mto_service_item/mto_service_item_updater.go b/pkg/services/mto_service_item/mto_service_item_updater.go index b5eaeae3caa..0a81d7ede20 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater.go +++ b/pkg/services/mto_service_item/mto_service_item_updater.go @@ -373,7 +373,11 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, if (serviceItem.ReService.Code == models.ReServiceCodeDDDSIT || serviceItem.ReService.Code == models.ReServiceCodeDDSFSC || serviceItem.ReService.Code == models.ReServiceCodeDDASIT || - serviceItem.ReService.Code == models.ReServiceCodeDDFSIT) && + serviceItem.ReService.Code == models.ReServiceCodeDDFSIT || + serviceItem.ReService.Code == models.ReServiceCodeIDDSIT || + serviceItem.ReService.Code == models.ReServiceCodeIDSFSC || + serviceItem.ReService.Code == models.ReServiceCodeIDASIT || + serviceItem.ReService.Code == models.ReServiceCodeIDFSIT) && serviceItem.SITDestinationOriginalAddressID == nil { // Set the original address on a service item to the shipment's @@ -401,9 +405,11 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, serviceItem.SITDestinationFinalAddress = shipmentDestinationAddress } - // Calculate SITDeliveryMiles for DDDSIT and DDSFSC origin SIT service items + // Calculate SITDeliveryMiles for DDDSIT/DDSFSC, IDDSIT/IDSFSC origin SIT service items if serviceItem.ReService.Code == models.ReServiceCodeDDDSIT || - serviceItem.ReService.Code == models.ReServiceCodeDDSFSC { + serviceItem.ReService.Code == models.ReServiceCodeDDSFSC || + serviceItem.ReService.Code == models.ReServiceCodeIDDSIT || + serviceItem.ReService.Code == models.ReServiceCodeIDSFSC { // Destination SIT: distance between shipment destination address & service item ORIGINAL destination address milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.DestinationAddress.PostalCode, serviceItem.SITDestinationOriginalAddress.PostalCode, false) if err != nil { @@ -413,9 +419,11 @@ func (p *mtoServiceItemUpdater) updateServiceItem(appCtx appcontext.AppContext, } } - // Calculate SITDeliveryMiles for DOPSIT and DOSFSC origin SIT service items + // Calculate SITDeliveryMiles for DOPSIT/DOSFSC, IOPSIT/IOSFSC origin SIT service items if serviceItem.ReService.Code == models.ReServiceCodeDOPSIT || - serviceItem.ReService.Code == models.ReServiceCodeDOSFSC { + serviceItem.ReService.Code == models.ReServiceCodeDOSFSC || + serviceItem.ReService.Code == models.ReServiceCodeIOPSIT || + serviceItem.ReService.Code == models.ReServiceCodeIOSFSC { // Origin SIT: distance between shipment pickup address & service item ORIGINAL pickup address milesCalculated, err := p.planner.ZipTransitDistance(appCtx, mtoShipment.PickupAddress.PostalCode, serviceItem.SITOriginHHGOriginalAddress.PostalCode, false) if err != nil { diff --git a/pkg/services/mto_service_item/mto_service_item_updater_test.go b/pkg/services/mto_service_item/mto_service_item_updater_test.go index a1192cc39fe..27abd914a79 100644 --- a/pkg/services/mto_service_item/mto_service_item_updater_test.go +++ b/pkg/services/mto_service_item/mto_service_item_updater_test.go @@ -766,6 +766,14 @@ func (suite *MTOServiceItemServiceSuite) TestMTOServiceItemUpdater() { models.ReServiceCodeDOPSIT, models.ReServiceCodeDOFSIT, models.ReServiceCodeDOSFSC, + models.ReServiceCodeIDFSIT, + models.ReServiceCodeIDASIT, + models.ReServiceCodeIDDSIT, + models.ReServiceCodeIDSFSC, + models.ReServiceCodeIOASIT, + models.ReServiceCodeIOPSIT, + models.ReServiceCodeIOFSIT, + models.ReServiceCodeIOSFSC, } shipmentSITAllowance := 90 @@ -2390,6 +2398,68 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.Equal(destinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) }) + suite.Run("When TOO approves a IDSFSC service item with an existing SITDestinationFinalAddress", func() { + move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) + destUSPRC, _ := models.FindByZipCode(suite.AppContextForTest().DB(), "99505") + sitDestinationFinalAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + StreetAddress1: "JBER", + City: "Anchorage", + State: "AK", + PostalCode: "99505", + IsOconus: models.BoolPointer(true), + UsPostRegionCityID: &destUSPRC.ID, + }, + }, + }, nil) + + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDSFSC, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusSubmitted, + }, + }, + { + Model: sitDestinationFinalAddress, + LinkOnly: true, + Type: &factory.Addresses.SITDestinationFinalAddress, + }, + }, nil) + + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + + // ApproveOrRejectServiceItem doesn't return the service item with the updated move + // get move from the db to check the updated status + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + suite.Equal(models.MoveStatusAPPROVED, move.Status) + + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + suite.NotNil(updatedServiceItem.ApprovedAt) + suite.Nil(updatedServiceItem.RejectionReason) + suite.Nil(updatedServiceItem.RejectedAt) + suite.NotNil(updatedServiceItem) + destinationAddress := serviceItem.MTOShipment.DestinationAddress + suite.Equal(destinationAddress.StreetAddress1, updatedServiceItem.SITDestinationOriginalAddress.StreetAddress1) + suite.Equal(destinationAddress.City, updatedServiceItem.SITDestinationOriginalAddress.City) + suite.Equal(destinationAddress.State, updatedServiceItem.SITDestinationOriginalAddress.State) + suite.Equal(destinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) + }) + suite.Run("When TOO approves a DDSFSC service item without a SITDestinationFinalAddress", func() { move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ @@ -2489,6 +2559,55 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.Equal(destinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) }) + suite.Run("When TOO approves a IDASIT service item with an existing SITDestinationFinalAddress", func() { + move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) + sitDestinationFinalAddress := factory.BuildAddress(suite.DB(), nil, nil) + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDASIT, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusSubmitted, + }, + }, + { + Model: sitDestinationFinalAddress, + LinkOnly: true, + Type: &factory.Addresses.SITDestinationFinalAddress, + }, + }, nil) + + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + + // ApproveOrRejectServiceItem doesn't return the service item with the updated move + // get move from the db to check the updated status + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + suite.Equal(models.MoveStatusAPPROVED, move.Status) + + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + suite.NotNil(updatedServiceItem.ApprovedAt) + suite.Nil(updatedServiceItem.RejectionReason) + suite.Nil(updatedServiceItem.RejectedAt) + suite.NotNil(updatedServiceItem) + destinationAddress := serviceItem.MTOShipment.DestinationAddress + suite.Equal(destinationAddress.StreetAddress1, updatedServiceItem.SITDestinationOriginalAddress.StreetAddress1) + suite.Equal(destinationAddress.City, updatedServiceItem.SITDestinationOriginalAddress.City) + suite.Equal(destinationAddress.State, updatedServiceItem.SITDestinationOriginalAddress.State) + suite.Equal(destinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) + }) + suite.Run("When TOO approves a DDASIT service item without a SITDestinationFinalAddress", func() { move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ @@ -2539,6 +2658,56 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.Equal(shipment.DestinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) }) + suite.Run("When TOO approves a IDASIT service item without a SITDestinationFinalAddress", func() { + move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDASIT, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusSubmitted, + }, + }, + }, nil) + + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + + // ApproveOrRejectServiceItem doesn't return the service item with the updated move + // get move from the db to check the updated status + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + suite.Equal(models.MoveStatusAPPROVED, move.Status) + + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + suite.NotNil(updatedServiceItem.ApprovedAt) + suite.Nil(updatedServiceItem.RejectionReason) + suite.Nil(updatedServiceItem.RejectedAt) + suite.NotNil(updatedServiceItem) + suite.NotEqual(shipment.DestinationAddressID, *updatedServiceItem.SITDestinationOriginalAddressID) + suite.NotEqual(shipment.DestinationAddress.ID, *updatedServiceItem.SITDestinationOriginalAddressID) + suite.Equal(shipment.DestinationAddress.StreetAddress1, updatedServiceItem.SITDestinationOriginalAddress.StreetAddress1) + suite.Equal(shipment.DestinationAddress.City, updatedServiceItem.SITDestinationOriginalAddress.City) + suite.Equal(shipment.DestinationAddress.State, updatedServiceItem.SITDestinationOriginalAddress.State) + suite.Equal(shipment.DestinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) + }) + suite.Run("When TOO approves a DDFSIT service item with an existing SITDestinationFinalAddress", func() { move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) sitDestinationFinalAddress := factory.BuildAddress(suite.DB(), nil, nil) @@ -2588,6 +2757,55 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.Equal(destinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) }) + suite.Run("When TOO approves a IDFSIT service item with an existing SITDestinationFinalAddress", func() { + move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) + sitDestinationFinalAddress := factory.BuildAddress(suite.DB(), nil, nil) + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDFSIT, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusSubmitted, + }, + }, + { + Model: sitDestinationFinalAddress, + LinkOnly: true, + Type: &factory.Addresses.SITDestinationFinalAddress, + }, + }, nil) + + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + + // ApproveOrRejectServiceItem doesn't return the service item with the updated move + // get move from the db to check the updated status + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + suite.Equal(models.MoveStatusAPPROVED, move.Status) + + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + suite.NotNil(updatedServiceItem.ApprovedAt) + suite.Nil(updatedServiceItem.RejectionReason) + suite.Nil(updatedServiceItem.RejectedAt) + suite.NotNil(updatedServiceItem) + destinationAddress := serviceItem.MTOShipment.DestinationAddress + suite.Equal(destinationAddress.StreetAddress1, updatedServiceItem.SITDestinationOriginalAddress.StreetAddress1) + suite.Equal(destinationAddress.City, updatedServiceItem.SITDestinationOriginalAddress.City) + suite.Equal(destinationAddress.State, updatedServiceItem.SITDestinationOriginalAddress.State) + suite.Equal(destinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) + }) + suite.Run("When TOO approves a DDFSIT service item without a SITDestinationFinalAddress", func() { move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ @@ -2638,6 +2856,56 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.Equal(shipment.DestinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) }) + suite.Run("When TOO approves a IDFSIT service item without a SITDestinationFinalAddress", func() { + move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + }, nil) + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDFSIT, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusSubmitted, + }, + }, + }, nil) + + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + + // ApproveOrRejectServiceItem doesn't return the service item with the updated move + // get move from the db to check the updated status + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + suite.Equal(models.MoveStatusAPPROVED, move.Status) + + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + suite.NotNil(updatedServiceItem.ApprovedAt) + suite.Nil(updatedServiceItem.RejectionReason) + suite.Nil(updatedServiceItem.RejectedAt) + suite.NotNil(updatedServiceItem) + suite.NotEqual(shipment.DestinationAddressID, *updatedServiceItem.SITDestinationOriginalAddressID) + suite.NotEqual(shipment.DestinationAddress.ID, *updatedServiceItem.SITDestinationOriginalAddressID) + suite.Equal(shipment.DestinationAddress.StreetAddress1, updatedServiceItem.SITDestinationOriginalAddress.StreetAddress1) + suite.Equal(shipment.DestinationAddress.City, updatedServiceItem.SITDestinationOriginalAddress.City) + suite.Equal(shipment.DestinationAddress.State, updatedServiceItem.SITDestinationOriginalAddress.State) + suite.Equal(shipment.DestinationAddress.PostalCode, updatedServiceItem.SITDestinationOriginalAddress.PostalCode) + }) + // Test that the move's status changes to Approvals Requested if any of its service // items' status is SUBMITTED suite.Run("When move is approved and service item is submitted", func() { @@ -2785,6 +3053,52 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemStatus() { suite.NotNil(updatedServiceItem) }) + suite.Run("When TOO rejects a IOFSIT service item and converts it to the customer expense", func() { + move := factory.BuildApprovalsRequestedMove(suite.DB(), nil, nil) + serviceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIOFSIT, + }, + }, + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + }, + }, + { + Model: models.Address{}, + Type: &factory.Addresses.SITOriginHHGActualAddress, + }, + { + Model: models.Address{}, + Type: &factory.Addresses.SITOriginHHGOriginalAddress, + }, + }, nil) + + eTag := etag.GenerateEtag(serviceItem.UpdatedAt) + + updatedServiceItem, err := updater.ApproveOrRejectServiceItem( + suite.AppContextForTest(), serviceItem.ID, models.MTOServiceItemStatusApproved, rejectionReason, eTag) + suite.NoError(err) + + // ApproveOrRejectServiceItem doesn't return the service item with the updated move + // get move from the db to check the updated status + err = suite.DB().Find(&move, move.ID) + suite.NoError(err) + suite.Equal(models.MoveStatusAPPROVED, move.Status) + + suite.Equal(models.MTOServiceItemStatusApproved, updatedServiceItem.Status) + suite.NotNil(updatedServiceItem.ApprovedAt) + suite.Nil(updatedServiceItem.RejectionReason) + suite.Nil(updatedServiceItem.RejectedAt) + suite.NotNil(updatedServiceItem) + }) + suite.Run("Returns a not found error if the updater can't find the ReService code for DOFSIT in the DB.", func() { _, err := updater.ConvertItemToCustomerExpense( suite.AppContextForTest(), &models.MTOShipment{}, models.StringPointer("test"), true) diff --git a/pkg/services/mto_service_item/mto_service_item_validators.go b/pkg/services/mto_service_item/mto_service_item_validators.go index a16ee07fc10..786f18d9944 100644 --- a/pkg/services/mto_service_item/mto_service_item_validators.go +++ b/pkg/services/mto_service_item/mto_service_item_validators.go @@ -43,6 +43,14 @@ var allSITServiceItemsToCheck = []models.ReServiceCode{ models.ReServiceCodeDOFSIT, models.ReServiceCodeDOASIT, models.ReServiceCodeDOSFSC, + models.ReServiceCodeIDDSIT, + models.ReServiceCodeIDASIT, + models.ReServiceCodeIDFSIT, + models.ReServiceCodeIDSFSC, + models.ReServiceCodeIOPSIT, + models.ReServiceCodeIOFSIT, + models.ReServiceCodeIOASIT, + models.ReServiceCodeIOSFSC, } var allAccessorialServiceItemsToCheck = []models.ReServiceCode{ diff --git a/pkg/services/mto_service_item/mto_service_item_validators_test.go b/pkg/services/mto_service_item/mto_service_item_validators_test.go index 947758dec43..e53dc6738a4 100644 --- a/pkg/services/mto_service_item/mto_service_item_validators_test.go +++ b/pkg/services/mto_service_item/mto_service_item_validators_test.go @@ -181,6 +181,29 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { suite.NoError(err) }) + suite.Run("checkForSITItemChanges - should not throw error when SIT Item is changed - international", func() { + + // Update the non-updateable fields: + oldServiceItem, newServiceItem := setupTestData() // Create old and new service item + + // Make both sthe newServiceItem of type DOFSIT because this type of service item will be checked by checkForSITItemChanges + newServiceItem.ReService.Code = models.ReServiceCodeIOFSIT + + // Sit Entry Date change. Need to make the newServiceItem different than the old. + newSitEntryDate := time.Date(2023, time.October, 10, 10, 10, 0, 0, time.UTC) + newServiceItem.SITEntryDate = &newSitEntryDate + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newServiceItem, + oldServiceItem: oldServiceItem, + verrs: validate.NewErrors(), + } + + err := serviceItemData.checkForSITItemChanges(&serviceItemData) + + suite.NoError(err) + }) + suite.Run("checkForSITItemChanges - should throw error when SIT Item is not changed", func() { oldServiceItem, newServiceItem := setupTestData() // Create old and new service item @@ -204,6 +227,29 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { }) + suite.Run("checkForSITItemChanges - should throw error when SIT Item is not changed - international", func() { + + oldServiceItem, newServiceItem := setupTestData() // Create old and new service item + + // Make both service items of type IOFSIT because this type of service item will be checked by checkForSITItemChanges + oldServiceItem.ReService.Code = models.ReServiceCodeIOFSIT + newServiceItem.ReService.Code = models.ReServiceCodeIOFSIT + oldServiceItem.SITDepartureDate, newServiceItem.SITDepartureDate = &now, &now + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newServiceItem, + oldServiceItem: oldServiceItem, + verrs: validate.NewErrors(), + } + + err := serviceItemData.checkForSITItemChanges(&serviceItemData) + + // Should error with message if nothing has changed between the new service item and the old one + suite.Error(err) + suite.Contains(err.Error(), "To re-submit a SIT sevice item the new SIT service item must be different than the previous one.") + + }) + // Test successful check for SIT departure service item - not updating SITDepartureDate suite.Run("checkSITDeparture w/ no SITDepartureDate update - success", func() { oldServiceItem, newServiceItem := setupTestData() // These @@ -247,6 +293,62 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { suite.NoVerrs(serviceItemData.verrs) }) + // Test successful check for SIT departure service item - IDDSIT + suite.Run("checkSITDeparture w/ IDDSIT - success", func() { + // Under test: checkSITDeparture checks that the service item is a + // IDDSIT or IOPSIT if the user is trying to update the + // SITDepartureDate + // Set up: Create an old and new IDDSIT, with a new date and try to update. + // Expected outcome: Success if both are IDDSIT + oldIDDSIT := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodeIDDSIT, + }, + }, + }, nil) + newIDDSIT := oldIDDSIT + newIDDSIT.SITDepartureDate = &now + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newIDDSIT, + oldServiceItem: oldIDDSIT, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDeparture(suite.AppContextForTest()) + + suite.NoError(err) + suite.NoVerrs(serviceItemData.verrs) + }) + + // Test successful check for SIT departure service item - IDDSIT + suite.Run("checkSITDeparture w/ IDDSIT - success", func() { + // Under test: checkSITDeparture checks that the service item is a + // IDDSIT or IOPSIT if the user is trying to update the + // SITDepartureDate + // Set up: Create an old and new IDDSIT, with a new date and try to update. + // Expected outcome: Success if both are IDDSIT + oldIDDSIT := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodeIDDSIT, + }, + }, + }, nil) + newIDDSIT := oldIDDSIT + newIDDSIT.SITDepartureDate = &now + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newIDDSIT, + oldServiceItem: oldIDDSIT, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDeparture(suite.AppContextForTest()) + + suite.NoError(err) + suite.NoVerrs(serviceItemData.verrs) + }) + // Test unsuccessful check for SIT departure service item - not a departure SIT item suite.Run("checkSITDeparture w/ non-departure SIT - failure", func() { // Under test: checkSITDeparture checks that the service item is a @@ -397,6 +499,37 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { suite.Contains(err.Error(), "- reason cannot be empty when resubmitting a previously rejected SIT service item") }) + // Test unsuccessful check service item when the reason isn't being updated + suite.Run("checkReasonWasUpdatedOnRejectedSIT - failure when empty string - international", func() { + // Under test: checkReasonWasUpdatedOnRejectedSIT ensures that the reason value is being updated + // Set up: Create any SIT service item + // Expected outcome: ConflictError + oldServiceItem, newServiceItem := setupTestData() + + // only checks rejected SIT service items + newServiceItem.Status = models.MTOServiceItemStatusSubmitted + oldServiceItem.Status = models.MTOServiceItemStatusRejected + + // This only checks SIT service items + newServiceItem.ReService.Code = models.ReServiceCodeIDFSIT + oldServiceItem.ReService.Code = models.ReServiceCodeIDFSIT + + newServiceItem.Reason = models.StringPointer("") + oldServiceItem.Reason = models.StringPointer("a reason") + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newServiceItem, + oldServiceItem: oldServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkReasonWasUpdatedOnRejectedSIT(suite.AppContextForTest()) + + suite.Error(err) + suite.IsType(apperror.ConflictError{}, err) + suite.NoVerrs(serviceItemData.verrs) + suite.Contains(err.Error(), "- reason cannot be empty when resubmitting a previously rejected SIT service item") + }) + // Test unsuccessful check service item when the reason isn't being updated suite.Run("checkReasonWasUpdatedOnRejectedSIT - failure when no reason is provided", func() { // Under test: checkReasonWasUpdatedOnRejectedSIT ensures that the reason value is being updated @@ -428,6 +561,37 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { suite.Contains(err.Error(), "- you must provide a new reason when resubmitting a previously rejected SIT service item") }) + // Test unsuccessful check service item when the reason isn't being updated + suite.Run("checkReasonWasUpdatedOnRejectedSIT - failure when no reason is provided - international", func() { + // Under test: checkReasonWasUpdatedOnRejectedSIT ensures that the reason value is being updated + // Set up: Create any SIT service item + // Expected outcome: ConflictError + oldServiceItem, newServiceItem := setupTestData() + + // only checks rejected SIT service items + newServiceItem.Status = models.MTOServiceItemStatusSubmitted + oldServiceItem.Status = models.MTOServiceItemStatusRejected + + // This only checks SIT service items + newServiceItem.ReService.Code = models.ReServiceCodeIDFSIT + oldServiceItem.ReService.Code = models.ReServiceCodeIDFSIT + + newServiceItem.Reason = nil + oldServiceItem.Reason = models.StringPointer("a reason") + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newServiceItem, + oldServiceItem: oldServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkReasonWasUpdatedOnRejectedSIT(suite.AppContextForTest()) + + suite.Error(err) + suite.IsType(apperror.ConflictError{}, err) + suite.NoVerrs(serviceItemData.verrs) + suite.Contains(err.Error(), "- you must provide a new reason when resubmitting a previously rejected SIT service item") + }) + suite.Run("checkReasonWasUpdatedOnRejectedSIT - success", func() { // Under test: checkReasonWasUpdatedOnRejectedSIT ensures that the reason value is being updated // Set up: Create any SIT service item @@ -456,6 +620,34 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { suite.NoVerrs(serviceItemData.verrs) }) + suite.Run("checkReasonWasUpdatedOnRejectedSIT - international - success", func() { + // Under test: checkReasonWasUpdatedOnRejectedSIT ensures that the reason value is being updated + // Set up: Create any SIT service item + // Expected outcome: No errors + oldServiceItem, newServiceItem := setupTestData() + + // only checks rejected SIT service items + newServiceItem.Status = models.MTOServiceItemStatusSubmitted + oldServiceItem.Status = models.MTOServiceItemStatusRejected + + // This only checks SIT service items + newServiceItem.ReService.Code = models.ReServiceCodeIDFSIT + oldServiceItem.ReService.Code = models.ReServiceCodeIDFSIT + + newServiceItem.Reason = models.StringPointer("one reason") + oldServiceItem.Reason = models.StringPointer("another reason") + + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newServiceItem, + oldServiceItem: oldServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkReasonWasUpdatedOnRejectedSIT(suite.AppContextForTest()) + + suite.NoError(err) + suite.NoVerrs(serviceItemData.verrs) + }) + // Test getVerrs for successful example suite.Run("getVerrs - success", func() { // Under test: getVerrs returns a list of validation errors @@ -860,6 +1052,138 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { }) + suite.Run("SITDepartureDate - Does not error or update shipment auth end date when set after the authorized end date - international", func() { + // Under test: checkSITDepartureDate checks that + // the SITDepartureDate is not later than the authorized end date + // Set up: Create an old and new IOPSIT and IDDSIT, with a date later than the + // shipment and try to update. + // Expected outcome: No ERROR if departure date comes after the end date. + // Shipment auth end date does not change + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{OriginSITAuthEndDate: &now, + DestinationSITAuthEndDate: &now}, + }, + }, nil) + testCases := []struct { + reServiceCode models.ReServiceCode + }{ + { + reServiceCode: models.ReServiceCodeIOPSIT, + }, + { + reServiceCode: models.ReServiceCodeIDDSIT, + }, + } + for _, tc := range testCases { + oldSITServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: tc.reServiceCode, + }, + }, + { + Model: mtoShipment, + LinkOnly: true, + }, + { + Model: models.MTOServiceItem{ + SITEntryDate: &before, + }, + }, + }, nil) + newSITServiceItem := oldSITServiceItem + newSITServiceItem.SITDepartureDate = &later + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newSITServiceItem, + oldServiceItem: oldSITServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDepartureDate(suite.AppContextForTest()) + suite.NoError(err) + suite.False(serviceItemData.verrs.HasAny()) + + // Double check the shipment and ensure that the SITDepartureDate is after the authorized end date and does not alter the authorized end date + var postUpdateShipment models.MTOShipment + err = suite.DB().Find(&postUpdateShipment, mtoShipment.ID) + suite.NoError(err) + if tc.reServiceCode == models.ReServiceCodeIOPSIT { + suite.True(mtoShipment.OriginSITAuthEndDate.Truncate(24 * time.Hour).Equal(postUpdateShipment.OriginSITAuthEndDate.Truncate(24 * time.Hour))) + suite.True(newSITServiceItem.SITDepartureDate.Truncate(24 * time.Hour).After(postUpdateShipment.OriginSITAuthEndDate.Truncate(24 * time.Hour))) + } + if tc.reServiceCode == models.ReServiceCodeIDDSIT { + suite.True(mtoShipment.DestinationSITAuthEndDate.Truncate(24 * time.Hour).Equal(postUpdateShipment.DestinationSITAuthEndDate.Truncate(24 * time.Hour))) + suite.True(newSITServiceItem.SITDepartureDate.Truncate(24 * time.Hour).After(postUpdateShipment.DestinationSITAuthEndDate.Truncate(24 * time.Hour))) + } + } + }) + + suite.Run("SITDepartureDate - Does not error or update shipment auth end date when set after the authorized end date - international", func() { + // Under test: checkSITDepartureDate checks that + // the SITDepartureDate is not later than the authorized end date + // Set up: Create an old and new IOPSIT and IDDSIT, with a date later than the + // shipment and try to update. + // Expected outcome: No ERROR if departure date comes after the end date. + // Shipment auth end date does not change + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{OriginSITAuthEndDate: &now, + DestinationSITAuthEndDate: &now}, + }, + }, nil) + testCases := []struct { + reServiceCode models.ReServiceCode + }{ + { + reServiceCode: models.ReServiceCodeIOPSIT, + }, + { + reServiceCode: models.ReServiceCodeIDDSIT, + }, + } + for _, tc := range testCases { + oldSITServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: tc.reServiceCode, + }, + }, + { + Model: mtoShipment, + LinkOnly: true, + }, + { + Model: models.MTOServiceItem{ + SITEntryDate: &later, + }, + }, + }, nil) + newSITServiceItem := oldSITServiceItem + newSITServiceItem.SITDepartureDate = &later + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newSITServiceItem, + oldServiceItem: oldSITServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDepartureDate(suite.AppContextForTest()) + suite.NoError(err) + suite.False(serviceItemData.verrs.HasAny()) + + // Double check the shipment and ensure that the SITDepartureDate is in fact after the authorized end date + var postUpdateShipment models.MTOShipment + err = suite.DB().Find(&postUpdateShipment, mtoShipment.ID) + suite.NoError(err) + if tc.reServiceCode == models.ReServiceCodeIOPSIT { + suite.True(mtoShipment.OriginSITAuthEndDate.Truncate(24 * time.Hour).Equal(postUpdateShipment.OriginSITAuthEndDate.Truncate(24 * time.Hour))) + suite.True(newSITServiceItem.SITEntryDate.Truncate(24 * time.Hour).After(postUpdateShipment.OriginSITAuthEndDate.Truncate(24 * time.Hour))) + } + if tc.reServiceCode == models.ReServiceCodeIDDSIT { + suite.True(mtoShipment.DestinationSITAuthEndDate.Truncate(24 * time.Hour).Equal(postUpdateShipment.DestinationSITAuthEndDate.Truncate(24 * time.Hour))) + suite.True(newSITServiceItem.SITEntryDate.Truncate(24 * time.Hour).After(postUpdateShipment.DestinationSITAuthEndDate.Truncate(24 * time.Hour))) + } + } + }) + suite.Run("SITDepartureDate - errors when set before or equal the SIT entry date", func() { mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ { @@ -960,6 +1284,154 @@ func (suite *MTOServiceItemServiceSuite) TestUpdateMTOServiceItemData() { }) + suite.Run("SITDepartureDate - errors when set before the SIT entry date - international", func() { + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{OriginSITAuthEndDate: &now, + DestinationSITAuthEndDate: &now}, + }, + }, nil) + testCases := []struct { + reServiceCode models.ReServiceCode + }{ + { + reServiceCode: models.ReServiceCodeIOPSIT, + }, + { + reServiceCode: models.ReServiceCodeIDDSIT, + }, + } + for _, tc := range testCases { + oldSITServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: tc.reServiceCode, + }, + }, + { + Model: mtoShipment, + LinkOnly: true, + }, + { + Model: models.MTOServiceItem{ + SITEntryDate: &later, + }, + }, + }, nil) + newSITServiceItem := oldSITServiceItem + newSITServiceItem.SITDepartureDate = &before + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newSITServiceItem, + oldServiceItem: oldSITServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDepartureDate(suite.AppContextForTest()) + suite.NoError(err) // Just verrs + suite.True(serviceItemData.verrs.HasAny()) + suite.Contains(serviceItemData.verrs.Keys(), "SITDepartureDate") + suite.Contains(serviceItemData.verrs.Get("SITDepartureDate"), "SIT departure date cannot be set before or equal to the SIT entry date.") + } + + }) + + suite.Run("SITDepartureDate - errors when set equal to the SIT entry date", func() { + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{OriginSITAuthEndDate: &now, + DestinationSITAuthEndDate: &now}, + }, + }, nil) + testCases := []struct { + reServiceCode models.ReServiceCode + }{ + { + reServiceCode: models.ReServiceCodeDOPSIT, + }, + { + reServiceCode: models.ReServiceCodeDDDSIT, + }, + } + for _, tc := range testCases { + oldSITServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: tc.reServiceCode, + }, + }, + { + Model: mtoShipment, + LinkOnly: true, + }, + { + Model: models.MTOServiceItem{ + SITEntryDate: &now, + }, + }, + }, nil) + newSITServiceItem := oldSITServiceItem + newSITServiceItem.SITDepartureDate = &now + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newSITServiceItem, + oldServiceItem: oldSITServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDepartureDate(suite.AppContextForTest()) + suite.NoError(err) // Just verrs + suite.True(serviceItemData.verrs.HasAny()) + suite.Contains(serviceItemData.verrs.Keys(), "SITDepartureDate") + suite.Contains(serviceItemData.verrs.Get("SITDepartureDate"), "SIT departure date cannot be set before or equal to the SIT entry date.") + } + }) + + suite.Run("SITDepartureDate - errors when set before the SIT entry date - international", func() { + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{OriginSITAuthEndDate: &now, + DestinationSITAuthEndDate: &now}, + }, + }, nil) + testCases := []struct { + reServiceCode models.ReServiceCode + }{ + { + reServiceCode: models.ReServiceCodeIOPSIT, + }, + { + reServiceCode: models.ReServiceCodeIDDSIT, + }, + } + for _, tc := range testCases { + oldSITServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: tc.reServiceCode, + }, + }, + { + Model: mtoShipment, + LinkOnly: true, + }, + { + Model: models.MTOServiceItem{ + SITEntryDate: &later, + }, + }, + }, nil) + newSITServiceItem := oldSITServiceItem + newSITServiceItem.SITDepartureDate = &before + serviceItemData := updateMTOServiceItemData{ + updatedServiceItem: newSITServiceItem, + oldServiceItem: oldSITServiceItem, + verrs: validate.NewErrors(), + } + err := serviceItemData.checkSITDepartureDate(suite.AppContextForTest()) + suite.NoError(err) // Just verrs + suite.True(serviceItemData.verrs.HasAny()) + suite.Contains(serviceItemData.verrs.Keys(), "SITDepartureDate") + suite.Contains(serviceItemData.verrs.Get("SITDepartureDate"), "SIT departure date cannot be set before the SIT entry date.") + } + }) + suite.Run("SITDepartureDate - errors when service item is missing a shipment ID", func() { oldSITServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ diff --git a/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher.go b/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher.go index ed7381c60a9..de42e34918f 100644 --- a/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher.go +++ b/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher.go @@ -36,37 +36,40 @@ func (f mtoShipmentRateAreaFetcher) GetPrimeMoveShipmentRateAreas(appCtx appcont var oconusPostalCodes = make([]string, 0) var conusPostalCodes = make([]string, 0) for _, shipment := range moveTaskOrder.MTOShipments { - if shipment.PickupAddress != nil { - if !slices.Contains(oconusPostalCodes, shipment.PickupAddress.PostalCode) && - shipment.PickupAddress.IsOconus != nil && *shipment.PickupAddress.IsOconus { - oconusPostalCodes = append(oconusPostalCodes, shipment.PickupAddress.PostalCode) - } else if !slices.Contains(conusPostalCodes, shipment.PickupAddress.PostalCode) { - conusPostalCodes = append(conusPostalCodes, shipment.PickupAddress.PostalCode) - } - } - if shipment.DestinationAddress != nil { - if !slices.Contains(oconusPostalCodes, shipment.DestinationAddress.PostalCode) && - shipment.DestinationAddress.IsOconus != nil && *shipment.DestinationAddress.IsOconus { - oconusPostalCodes = append(oconusPostalCodes, shipment.DestinationAddress.PostalCode) - } else if !slices.Contains(conusPostalCodes, shipment.DestinationAddress.PostalCode) { - conusPostalCodes = append(conusPostalCodes, shipment.DestinationAddress.PostalCode) + // B-22767: We want both domestic and international rate area info but only for international shipments + if shipment.MarketCode == models.MarketCodeInternational { + if shipment.PickupAddress != nil { + if !slices.Contains(oconusPostalCodes, shipment.PickupAddress.PostalCode) && + shipment.PickupAddress.IsOconus != nil && *shipment.PickupAddress.IsOconus { + oconusPostalCodes = append(oconusPostalCodes, shipment.PickupAddress.PostalCode) + } else if !slices.Contains(conusPostalCodes, shipment.PickupAddress.PostalCode) { + conusPostalCodes = append(conusPostalCodes, shipment.PickupAddress.PostalCode) + } } - } - if shipment.PPMShipment != nil { - if shipment.PPMShipment.PickupAddress != nil { - if !slices.Contains(oconusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) && - shipment.PPMShipment.PickupAddress.IsOconus != nil && *shipment.PPMShipment.PickupAddress.IsOconus { - oconusPostalCodes = append(oconusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) - } else if !slices.Contains(conusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) { - conusPostalCodes = append(conusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) + if shipment.DestinationAddress != nil { + if !slices.Contains(oconusPostalCodes, shipment.DestinationAddress.PostalCode) && + shipment.DestinationAddress.IsOconus != nil && *shipment.DestinationAddress.IsOconus { + oconusPostalCodes = append(oconusPostalCodes, shipment.DestinationAddress.PostalCode) + } else if !slices.Contains(conusPostalCodes, shipment.DestinationAddress.PostalCode) { + conusPostalCodes = append(conusPostalCodes, shipment.DestinationAddress.PostalCode) } } - if shipment.PPMShipment.DestinationAddress != nil { - if !slices.Contains(oconusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) && - shipment.PPMShipment.DestinationAddress.IsOconus != nil && *shipment.PPMShipment.DestinationAddress.IsOconus { - oconusPostalCodes = append(oconusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) - } else if !slices.Contains(conusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) { - conusPostalCodes = append(conusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) + if shipment.PPMShipment != nil { + if shipment.PPMShipment.PickupAddress != nil { + if !slices.Contains(oconusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) && + shipment.PPMShipment.PickupAddress.IsOconus != nil && *shipment.PPMShipment.PickupAddress.IsOconus { + oconusPostalCodes = append(oconusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) + } else if !slices.Contains(conusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) { + conusPostalCodes = append(conusPostalCodes, shipment.PPMShipment.PickupAddress.PostalCode) + } + } + if shipment.PPMShipment.DestinationAddress != nil { + if !slices.Contains(oconusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) && + shipment.PPMShipment.DestinationAddress.IsOconus != nil && *shipment.PPMShipment.DestinationAddress.IsOconus { + oconusPostalCodes = append(oconusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) + } else if !slices.Contains(conusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) { + conusPostalCodes = append(conusPostalCodes, shipment.PPMShipment.DestinationAddress.PostalCode) + } } } } diff --git a/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher_test.go b/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher_test.go index e94fea2c4a1..b594c3f3a6c 100644 --- a/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher_test.go +++ b/pkg/services/mto_shipment/mto_shipment_rate_area_fetcher_test.go @@ -3,6 +3,7 @@ package mtoshipment import ( "database/sql" "fmt" + "slices" "time" "github.com/gofrs/uuid" @@ -46,6 +47,7 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { PostalCode: anchorageAlaskaPostalCode, IsOconus: models.BoolPointer(true), }, + MarketCode: models.MarketCodeInternational, }, models.MTOShipment{ PickupAddress: &models.Address{ @@ -62,15 +64,16 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { PostalCode: sanDiegoCAPostalCode, IsOconus: models.BoolPointer(false), }, + MarketCode: models.MarketCodeDomestic, }, models.MTOShipment{ PPMShipment: &models.PPMShipment{ PickupAddress: &models.Address{ StreetAddress1: "123 Main St", - City: "Wasilla", - State: "AK", - PostalCode: wasillaAlaskaPostalCode, - IsOconus: models.BoolPointer(true), + City: "Beverly Hills", + State: "CA", + PostalCode: beverlyHillsCAPostalCode, + IsOconus: models.BoolPointer(false), }, DestinationAddress: &models.Address{ StreetAddress1: "123 Main St", @@ -80,6 +83,7 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { IsOconus: models.BoolPointer(true), }, }, + MarketCode: models.MarketCodeInternational, }, }, } @@ -214,9 +218,9 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { }) // setup Fairbanks and Anchorage to have same RateArea - rateArea1 := setupRateAreaToManyPostalCodesData(*contract, []string{fairbanksAlaskaPostalCode, anchorageAlaskaPostalCode}) + rateAreaAK1 := setupRateAreaToManyPostalCodesData(*contract, []string{fairbanksAlaskaPostalCode, anchorageAlaskaPostalCode}) // setup Wasilla to have it's own RateArea - rateArea2 := setupRateAreaToPostalCodeData(setupRateArea(*contract), wasillaAlaskaPostalCode) + rateAreaAK2 := setupRateAreaToPostalCodeData(setupRateArea(*contract), wasillaAlaskaPostalCode) rateAreaCA, err := setupDomesticRateAreaAndZip3s("US88", "California-South", map[string]string{beverlyHillsCAPostalCode: "Beverly Hills", sanDiegoCAPostalCode: "San Diego"}, domServiceArea) if err != nil { @@ -226,27 +230,30 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { shipmentPostalCodeRateAreas, err := shipmentRateAreaFetcher.GetPrimeMoveShipmentRateAreas(suite.AppContextForTest(), testMove) suite.NotNil(shipmentPostalCodeRateAreas) suite.FatalNoError(err) - suite.Equal(5, len(*shipmentPostalCodeRateAreas)) + suite.Equal(4, len(*shipmentPostalCodeRateAreas)) - suite.Equal(true, isRateAreaEquals(rateArea1, fairbanksAlaskaPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(true, isRateAreaEquals(rateArea1, anchorageAlaskaPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(true, isRateAreaEquals(rateArea2, wasillaAlaskaPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(true, isRateAreaEquals(rateAreaAK1, fairbanksAlaskaPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(true, isRateAreaEquals(rateAreaAK1, anchorageAlaskaPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(true, isRateAreaEquals(rateAreaAK2, wasillaAlaskaPostalCode, shipmentPostalCodeRateAreas)) suite.Equal(true, isRateAreaEquals(rateAreaCA, beverlyHillsCAPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(true, isRateAreaEquals(rateAreaCA, sanDiegoCAPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea2, fairbanksAlaskaPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea2, anchorageAlaskaPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea1, wasillaAlaskaPostalCode, shipmentPostalCodeRateAreas)) + // Postal code used only in a CONUS shipment should not have been fetched + i := slices.IndexFunc(*shipmentPostalCodeRateAreas, func(pcra services.ShipmentPostalCodeRateArea) bool { + return pcra.PostalCode == sanDiegoCAPostalCode + }) + suite.Equal(-1, i) + + suite.Equal(false, isRateAreaEquals(rateAreaAK1, beverlyHillsCAPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(false, isRateAreaEquals(rateAreaAK1, wasillaAlaskaPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(false, isRateAreaEquals(rateAreaAK2, fairbanksAlaskaPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(false, isRateAreaEquals(rateAreaAK2, anchorageAlaskaPostalCode, shipmentPostalCodeRateAreas)) + suite.Equal(false, isRateAreaEquals(rateAreaAK2, beverlyHillsCAPostalCode, shipmentPostalCodeRateAreas)) suite.Equal(false, isRateAreaEquals(rateAreaCA, fairbanksAlaskaPostalCode, shipmentPostalCodeRateAreas)) suite.Equal(false, isRateAreaEquals(rateAreaCA, anchorageAlaskaPostalCode, shipmentPostalCodeRateAreas)) suite.Equal(false, isRateAreaEquals(rateAreaCA, wasillaAlaskaPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea1, beverlyHillsCAPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea1, sanDiegoCAPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea2, beverlyHillsCAPostalCode, shipmentPostalCodeRateAreas)) - suite.Equal(false, isRateAreaEquals(rateArea2, sanDiegoCAPostalCode, shipmentPostalCodeRateAreas)) }) - suite.Run("Returns matching CONUS rate areas", func() { + suite.Run("Does not return rate areas for CONUS only shipments", func() { availableToPrimeAtTime := time.Now().Add(-500 * time.Hour) testMove := models.Move{ AvailableToPrimeAt: &availableToPrimeAtTime, @@ -266,6 +273,7 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { PostalCode: sanDiegoCAPostalCode, IsOconus: models.BoolPointer(false), }, + MarketCode: models.MarketCodeDomestic, }, models.MTOShipment{ PPMShipment: &models.PPMShipment{ @@ -284,6 +292,7 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { IsOconus: models.BoolPointer(false), }, }, + MarketCode: models.MarketCodeDomestic, }, }, } @@ -334,29 +343,20 @@ func (suite *MTOShipmentServiceSuite) TestGetMoveShipmentRateArea() { return rateArea, nil } - rateAreaCA, err := setupDomesticRateAreaAndZip3s("US88", "California-South", map[string]string{beverlyHillsCAPostalCode: "Beverly Hills", sanDiegoCAPostalCode: "San Diego"}, domServiceArea) + _, err := setupDomesticRateAreaAndZip3s("US88", "California-South", map[string]string{beverlyHillsCAPostalCode: "Beverly Hills", sanDiegoCAPostalCode: "San Diego"}, domServiceArea) if err != nil { suite.Fail(err.Error()) } - rateAreaNY, err := setupDomesticRateAreaAndZip3s("US17", "New York", map[string]string{brooklynNYPostalCode: "Brooklyn"}, domServiceArea) + _, err = setupDomesticRateAreaAndZip3s("US17", "New York", map[string]string{brooklynNYPostalCode: "Brooklyn"}, domServiceArea) if err != nil { suite.Fail(err.Error()) } shipmentPostalCodeRateAreas, err := shipmentRateAreaFetcher.GetPrimeMoveShipmentRateAreas(suite.AppContextForTest(), testMove) suite.NotNil(shipmentPostalCodeRateAreas) - suite.Equal(3, len(*shipmentPostalCodeRateAreas)) + suite.Equal(0, len(*shipmentPostalCodeRateAreas)) suite.Nil(err) - - var shipmentPostalCodeRateAreaLookupMap = make(map[string]services.ShipmentPostalCodeRateArea) - for _, pcra := range *shipmentPostalCodeRateAreas { - shipmentPostalCodeRateAreaLookupMap[pcra.PostalCode] = pcra - } - - suite.Equal(rateAreaCA.Name, shipmentPostalCodeRateAreaLookupMap[beverlyHillsCAPostalCode].RateArea.Name) - suite.Equal(rateAreaCA.Name, shipmentPostalCodeRateAreaLookupMap[sanDiegoCAPostalCode].RateArea.Name) - suite.Equal(rateAreaNY.Name, shipmentPostalCodeRateAreaLookupMap[brooklynNYPostalCode].RateArea.Name) }) suite.Run("not available to prime error", func() { diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 63e61cdddac..cb36634cec8 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -1344,7 +1344,8 @@ func UpdateDestinationSITServiceItemsAddress(appCtx appcontext.AppContext, shipm mtoServiceItems := mtoShipment.MTOServiceItems // Only update these serviceItems address ID - serviceItemsToUpdate := []models.ReServiceCode{models.ReServiceCodeDDDSIT, models.ReServiceCodeDDFSIT, models.ReServiceCodeDDASIT, models.ReServiceCodeDDSFSC} + serviceItemsToUpdate := []models.ReServiceCode{models.ReServiceCodeDDDSIT, models.ReServiceCodeDDFSIT, models.ReServiceCodeDDASIT, models.ReServiceCodeDDSFSC, + models.ReServiceCodeIDDSIT, models.ReServiceCodeIDFSIT, models.ReServiceCodeIDASIT, models.ReServiceCodeIDSFSC} for _, serviceItem := range mtoServiceItems { @@ -1387,7 +1388,9 @@ func UpdateDestinationSITServiceItemsSITDeliveryMiles(planner route.Planner, app serviceItem := s reServiceCode := serviceItem.ReService.Code if reServiceCode == models.ReServiceCodeDDDSIT || - reServiceCode == models.ReServiceCodeDDSFSC { + reServiceCode == models.ReServiceCodeDDSFSC || + reServiceCode == models.ReServiceCodeIDDSIT || + reServiceCode == models.ReServiceCodeIDSFSC { var milesCalculated int diff --git a/pkg/services/ppmshipment/ppm_estimator.go b/pkg/services/ppmshipment/ppm_estimator.go index cf77b16fb04..d162aa3a722 100644 --- a/pkg/services/ppmshipment/ppm_estimator.go +++ b/pkg/services/ppmshipment/ppm_estimator.go @@ -489,8 +489,16 @@ func (f estimatePPM) calculatePrice(appCtx appcontext.AppContext, ppmShipment *m } } - if pickupPostal[0:3] == destPostal[0:3] { - serviceItemsToPrice[0] = models.MTOServiceItem{ReService: models.ReService{Code: models.ReServiceCodeDSH}, MTOShipmentID: &ppmShipment.ShipmentID} + // if the ZIPs are the same, we need to replace the DLH service item with DSH + if len(pickupPostal) >= 3 && len(destPostal) >= 3 && pickupPostal[:3] == destPostal[:3] { + if pickupPostal[0:3] == destPostal[0:3] { + for i, serviceItem := range serviceItemsToPrice { + if serviceItem.ReService.Code == models.ReServiceCodeDLH { + serviceItemsToPrice[i] = models.MTOServiceItem{ReService: models.ReService{Code: models.ReServiceCodeDSH}, MTOShipmentID: &ppmShipment.ShipmentID} + break + } + } + } } // Get a list of all the pricing params needed to calculate the price for each service item @@ -630,9 +638,15 @@ func (f estimatePPM) priceBreakdown(appCtx appcontext.AppContext, ppmShipment *m destPostal = ppmShipment.DestinationAddress.PostalCode } + // if the ZIPs are the same, we need to replace the DLH service item with DSH if len(pickupPostal) >= 3 && len(destPostal) >= 3 && pickupPostal[:3] == destPostal[:3] { if pickupPostal[0:3] == destPostal[0:3] { - serviceItemsToPrice[0] = models.MTOServiceItem{ReService: models.ReService{Code: models.ReServiceCodeDSH}, MTOShipmentID: &ppmShipment.ShipmentID} + for i, serviceItem := range serviceItemsToPrice { + if serviceItem.ReService.Code == models.ReServiceCodeDLH { + serviceItemsToPrice[i] = models.MTOServiceItem{ReService: models.ReService{Code: models.ReServiceCodeDSH}, MTOShipmentID: &ppmShipment.ShipmentID} + break + } + } } } diff --git a/pkg/services/ppmshipment/ppm_shipment_creator.go b/pkg/services/ppmshipment/ppm_shipment_creator.go index 75f8e50f7ae..b76cfbe778d 100644 --- a/pkg/services/ppmshipment/ppm_shipment_creator.go +++ b/pkg/services/ppmshipment/ppm_shipment_creator.go @@ -56,6 +56,11 @@ func (f *ppmShipmentCreator) createPPMShipment(appCtx appcontext.AppContext, ppm return apperror.NewInvalidInputError(uuid.Nil, nil, nil, "Must have a DRAFT or SUBMITTED status associated with PPM shipment") } + // default PPM type is incentive based + if ppmShipment.PPMType == "" { + ppmShipment.PPMType = models.PPMType(models.PPMTypeIncentiveBased) + } + // create pickup and destination addresses if ppmShipment.PickupAddress != nil { address, err = f.addressCreator.CreateAddress(txnAppCtx, ppmShipment.PickupAddress) diff --git a/pkg/services/ppmshipment/ppm_shipment_creator_test.go b/pkg/services/ppmshipment/ppm_shipment_creator_test.go index 22fc576d525..73c545ca608 100644 --- a/pkg/services/ppmshipment/ppm_shipment_creator_test.go +++ b/pkg/services/ppmshipment/ppm_shipment_creator_test.go @@ -108,6 +108,7 @@ func (suite *PPMShipmentSuite) TestPPMShipmentCreator() { suite.Nil(err) suite.NotNil(createdPPMShipment) + suite.Equal(createdPPMShipment.PPMType, models.PPMTypeIncentiveBased) suite.Equal(createdPPMShipment.Shipment.MarketCode, models.MarketCodeDomestic) }) diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester.go b/pkg/services/shipment_address_update/shipment_address_update_requester.go index 8f4b75973e6..3acd31b33fb 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester.go @@ -178,7 +178,14 @@ func (f *shipmentAddressUpdateRequester) doesShipmentContainApprovedDestinationS for _, serviceItem := range serviceItems { serviceCode := serviceItem.ReService.Code status := serviceItem.Status - if (serviceCode == models.ReServiceCodeDDASIT || serviceCode == models.ReServiceCodeDDDSIT || serviceCode == models.ReServiceCodeDDFSIT || serviceCode == models.ReServiceCodeDDSFSC) && + if (serviceCode == models.ReServiceCodeDDASIT || + serviceCode == models.ReServiceCodeDDDSIT || + serviceCode == models.ReServiceCodeDDFSIT || + serviceCode == models.ReServiceCodeDDSFSC || + serviceCode == models.ReServiceCodeIDASIT || + serviceCode == models.ReServiceCodeIDDSIT || + serviceCode == models.ReServiceCodeIDFSIT || + serviceCode == models.ReServiceCodeIDSFSC) && status == models.MTOServiceItemStatusApproved { return true } @@ -317,7 +324,14 @@ func (f *shipmentAddressUpdateRequester) RequestShipmentDeliveryAddressUpdate(ap serviceItems := shipment.MTOServiceItems for _, serviceItem := range serviceItems { serviceCode := serviceItem.ReService.Code - if serviceCode == models.ReServiceCodeDDASIT || serviceCode == models.ReServiceCodeDDDSIT || serviceCode == models.ReServiceCodeDDFSIT || serviceCode == models.ReServiceCodeDDSFSC { + if serviceCode == models.ReServiceCodeDDASIT || + serviceCode == models.ReServiceCodeDDDSIT || + serviceCode == models.ReServiceCodeDDFSIT || + serviceCode == models.ReServiceCodeDDSFSC || + serviceCode == models.ReServiceCodeIDASIT || + serviceCode == models.ReServiceCodeIDDSIT || + serviceCode == models.ReServiceCodeIDFSIT || + serviceCode == models.ReServiceCodeIDSFSC { if serviceItem.SITDestinationOriginalAddressID != nil { addressUpdate.SitOriginalAddressID = serviceItem.SITDestinationOriginalAddressID } diff --git a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go index ad1c2cd1ad9..93090688a25 100644 --- a/pkg/services/shipment_address_update/shipment_address_update_requester_test.go +++ b/pkg/services/shipment_address_update/shipment_address_update_requester_test.go @@ -780,6 +780,90 @@ func (suite *ShipmentAddressUpdateServiceSuite) TestCreateApprovedShipmentAddres suite.Equal(*addressUpdate.OldSitDistanceBetween, 0) suite.Equal(*addressUpdate.SitOriginalAddressID, *serviceItemDDASIT.SITDestinationOriginalAddressID) }) + + suite.Run("destination address request succeeds when containing international destination SIT", func() { + move := setupTestData() + newAddress := models.Address{ + StreetAddress1: "123 Any St", + City: "Anchorage", + State: "AK", + PostalCode: "99695", + } + + setupInternationalSITCodes := []models.ReServiceCode{ + models.ReServiceCodeIDASIT, + models.ReServiceCodeIDDSIT, + models.ReServiceCodeIDFSIT, + models.ReServiceCodeIDSFSC, + } + + // loop through test codes to verify updates are applied for expected international SITs + for _, reServiceCode := range setupInternationalSITCodes { + shipment := factory.BuildMTOShipmentWithMove(&move, suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + }, nil) + + // building service item to get dest SIT checks + serviceItemDDASIT := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: models.MTOServiceItem{ + Status: models.MTOServiceItemStatusApproved, + SITDestinationOriginalAddressID: shipment.DestinationAddressID, + }, + }, + { + Model: move, + LinkOnly: true, + }, + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: reServiceCode, + }, + }, + }, nil) + + // mock ZipTransitDistance function + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "94535", + "94535", + false, + ).Return(0, nil).Once() + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "94523", + "99695", + false, + ).Return(500, nil).Once() + mockPlanner.On("ZipTransitDistance", + mock.AnythingOfType("*appcontext.appContext"), + "94535", + "99695", + false, + ).Return(1000, nil).Once() + + // request the update + update, err := addressUpdateRequester.RequestShipmentDeliveryAddressUpdate(suite.AppContextForTest(), shipment.ID, newAddress, "we really need to change the address", etag.GenerateEtag(shipment.UpdatedAt)) + suite.NoError(err) + suite.NotNil(update) + + // querying the address update to make sure that SIT data was populated + var addressUpdate models.ShipmentAddressUpdate + err = suite.DB().Find(&addressUpdate, update.ID) + suite.NoError(err) + suite.Equal(*addressUpdate.NewSitDistanceBetween, 1000) + suite.Equal(*addressUpdate.OldSitDistanceBetween, 0) + suite.Equal(*addressUpdate.SitOriginalAddressID, *serviceItemDDASIT.SITDestinationOriginalAddressID) + } + }) } func (suite *ShipmentAddressUpdateServiceSuite) TestTOOApprovedShipmentAddressUpdateRequest() { diff --git a/pkg/services/sit_entry_date_update/sit_entry_date_updater.go b/pkg/services/sit_entry_date_update/sit_entry_date_updater.go index 2e32dc8172c..54012f13bb0 100644 --- a/pkg/services/sit_entry_date_update/sit_entry_date_updater.go +++ b/pkg/services/sit_entry_date_update/sit_entry_date_updater.go @@ -53,9 +53,10 @@ func (p sitEntryDateUpdater) UpdateSitEntryDate(appCtx appcontext.AppContext, s return nil, apperror.NewQueryError("Shipment", err, "") } - // the service code can either be DOFSIT or DDFSIT + // the service code can either be DOFSIT/DDFSIT or IOFSIT/IDFSIT serviceItemCode := serviceItem.ReService.Code - if serviceItemCode != models.ReServiceCodeDOFSIT && serviceItemCode != models.ReServiceCodeDDFSIT { + if serviceItemCode != models.ReServiceCodeDOFSIT && serviceItemCode != models.ReServiceCodeDDFSIT && + serviceItemCode != models.ReServiceCodeIOFSIT && serviceItemCode != models.ReServiceCodeIDFSIT { return nil, apperror.NewUnprocessableEntityError(string(serviceItemCode) + "You cannot change the SIT entry date of this service item.") } @@ -63,16 +64,16 @@ func (p sitEntryDateUpdater) UpdateSitEntryDate(appCtx appcontext.AppContext, s // then looking for the sister service item of add'l days // once found, we'll set the value of variable to that service item // so now we have the 1st day of SIT service item & the add'l days SIT service item - if serviceItemCode == models.ReServiceCodeDOFSIT { + if serviceItemCode == models.ReServiceCodeDOFSIT || serviceItemCode == models.ReServiceCodeIOFSIT { for _, si := range shipment.MTOServiceItems { - if si.ReService.Code == models.ReServiceCodeDOASIT { + if si.ReService.Code == models.ReServiceCodeDOASIT || si.ReService.Code == models.ReServiceCodeIOASIT { serviceItemAdditionalDays = si break } } - } else if serviceItemCode == models.ReServiceCodeDDFSIT { + } else if serviceItemCode == models.ReServiceCodeDDFSIT || serviceItemCode == models.ReServiceCodeIDFSIT { for _, si := range shipment.MTOServiceItems { - if si.ReService.Code == models.ReServiceCodeDDASIT { + if si.ReService.Code == models.ReServiceCodeDDASIT || si.ReService.Code == models.ReServiceCodeIDASIT { serviceItemAdditionalDays = si break } diff --git a/pkg/services/sit_entry_date_update/sit_entry_date_updater_test.go b/pkg/services/sit_entry_date_update/sit_entry_date_updater_test.go index d3546d7a5f7..7144a84f784 100644 --- a/pkg/services/sit_entry_date_update/sit_entry_date_updater_test.go +++ b/pkg/services/sit_entry_date_update/sit_entry_date_updater_test.go @@ -49,6 +49,44 @@ func (suite *UpdateSitEntryDateServiceSuite) TestUpdateSitEntryDate() { return ddfServiceItem, ddaServiceItem } + setupInternationalModels := func() (models.MTOServiceItem, models.MTOServiceItem) { + move := factory.BuildMove(suite.DB(), nil, nil) + shipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: move, + LinkOnly: true, + }, + { + Model: models.MTOShipment{ + MarketCode: models.MarketCodeInternational, + }, + }, + }, nil) + idfServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDFSIT, + }, + }, + }, nil) + idaServiceItem := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ + { + Model: shipment, + LinkOnly: true, + }, + { + Model: models.ReService{ + Code: models.ReServiceCodeIDASIT, + }, + }, + }, nil) + return idfServiceItem, idaServiceItem + } + // Test not found error suite.Run("Not Found Error", func() { ddfServiceItem, _ := setupModels() @@ -67,6 +105,23 @@ func (suite *UpdateSitEntryDateServiceSuite) TestUpdateSitEntryDate() { suite.IsType(apperror.NotFoundError{}, err) }) + suite.Run("Not Found Error - international", func() { + idfServiceItem, _ := setupInternationalModels() + notFoundServiceItem := models.SITEntryDateUpdate{ + ID: idfServiceItem.ID, + SITEntryDate: idfServiceItem.SITEntryDate, + } + notFoundUUID, err := uuid.NewV4() + suite.NoError(err) + notFoundServiceItem.ID = notFoundUUID + + updatedServiceItem, err := updater.UpdateSitEntryDate(suite.AppContextForTest(), ¬FoundServiceItem) + + suite.Nil(updatedServiceItem) + suite.Error(err) + suite.IsType(apperror.NotFoundError{}, err) + }) + // Test successful update of both service items suite.Run("Successful update of service items", func() { ddfServiceItem, ddaServiceItem := setupModels() @@ -252,4 +307,25 @@ func (suite *UpdateSitEntryDateServiceSuite) TestUpdateSitEntryDate() { ) suite.Contains(err.Error(), expectedError) }) + suite.Run("Successful update of service items - international", func() { + idfServiceItem, idaServiceItem := setupInternationalModels() + updatedServiceItem := models.SITEntryDateUpdate{ + ID: idfServiceItem.ID, + SITEntryDate: idfServiceItem.SITEntryDate, + } + newSitEntryDate := time.Date(2020, time.December, 02, 0, 0, 0, 0, time.UTC) + newSitEntryDateNextDay := newSitEntryDate.Add(24 * time.Hour) + + updatedServiceItem.SITEntryDate = &newSitEntryDate + idaServiceItem.SITEntryDate = &newSitEntryDateNextDay + + changedServiceItem, err := updater.UpdateSitEntryDate(suite.AppContextForTest(), &updatedServiceItem) + + suite.NoError(err) + suite.NotNil(updatedServiceItem) + suite.Equal(idfServiceItem.ID, updatedServiceItem.ID) + suite.Equal(updatedServiceItem.SITEntryDate.Local(), changedServiceItem.SITEntryDate.Local()) + suite.Equal(idaServiceItem.SITEntryDate.Local(), newSitEntryDateNextDay.Local()) + }) + } diff --git a/pkg/services/transportation_office/transportation_office_fetcher.go b/pkg/services/transportation_office/transportation_office_fetcher.go index 8fde2e98093..2ad7681ea29 100644 --- a/pkg/services/transportation_office/transportation_office_fetcher.go +++ b/pkg/services/transportation_office/transportation_office_fetcher.go @@ -133,8 +133,10 @@ func ListDistinctGBLOCs(appCtx appcontext.AppContext) (models.GBLOCs, error) { return gblocList, err } +// return all the transportation offices in the GBLOC of the given duty location where provides_services_counseling = true +// serviceMemberID is only provided when this function is called by the office handler func (o transportationOfficesFetcher) GetCounselingOffices(appCtx appcontext.AppContext, dutyLocationID uuid.UUID, serviceMemberID uuid.UUID) (*models.TransportationOffices, error) { - officeList, err := findCounselingOffice(appCtx, dutyLocationID, serviceMemberID) + officeList, err := models.GetCounselingOffices(appCtx.DB(), dutyLocationID, serviceMemberID) if err != nil { switch err { diff --git a/pkg/services/transportation_office/transportation_office_fetcher_test.go b/pkg/services/transportation_office/transportation_office_fetcher_test.go index 64c377deb30..6d5134b2c8f 100644 --- a/pkg/services/transportation_office/transportation_office_fetcher_test.go +++ b/pkg/services/transportation_office/transportation_office_fetcher_test.go @@ -100,13 +100,15 @@ func (suite *TransportationOfficeServiceSuite) Test_SortedTransportationOffices( } func (suite *TransportationOfficeServiceSuite) Test_FindCounselingOffices() { - // duty location in KKFA with provies services counseling false - customAddress1 := models.Address{ - ID: uuid.Must(uuid.NewV4()), - PostalCode: "59801", - } + suite.toFetcher = NewTransportationOfficesFetcher() + customAddress1 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: "59801", + }, + }, + }, nil) factory.BuildDutyLocation(suite.DB(), []factory.Customization{ - {Model: customAddress1, Type: &factory.Addresses.DutyLocationAddress}, { Model: models.DutyLocation{ ProvidesServicesCounseling: false, @@ -117,15 +119,22 @@ func (suite *TransportationOfficeServiceSuite) Test_FindCounselingOffices() { Name: "PPPO Holloman AFB - USAF", }, }, + { + Model: customAddress1, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, }, nil) - // duty location in KKFA with provides services counseling true - customAddress2 := models.Address{ - ID: uuid.Must(uuid.NewV4()), - PostalCode: "59801", - } + // duty locations in KKFA with provides_services_counseling = true + customAddress2 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: "59801", + }, + }, + }, nil) factory.BuildDutyLocation(suite.DB(), []factory.Customization{ - {Model: customAddress2, Type: &factory.Addresses.DutyLocationAddress}, { Model: models.DutyLocation{ ProvidesServicesCounseling: true, @@ -136,15 +145,21 @@ func (suite *TransportationOfficeServiceSuite) Test_FindCounselingOffices() { Name: "PPPO Hill AFB - USAF", }, }, + { + Model: customAddress2, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, }, nil) - // duty location in KKFA with provides services counseling true - customAddress3 := models.Address{ - ID: uuid.Must(uuid.NewV4()), - PostalCode: "59801", - } + customAddress3 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: "59801", + }, + }, + }, nil) origDutyLocation := factory.BuildDutyLocation(suite.DB(), []factory.Customization{ - {Model: customAddress3, Type: &factory.Addresses.DutyLocationAddress}, { Model: models.DutyLocation{ ProvidesServicesCounseling: true, @@ -157,15 +172,22 @@ func (suite *TransportationOfficeServiceSuite) Test_FindCounselingOffices() { ProvidesCloseout: true, }, }, + { + Model: customAddress3, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, }, nil) - // duty location NOT in KKFA with provides services counseling true - customAddress4 := models.Address{ - ID: uuid.Must(uuid.NewV4()), - PostalCode: "20906", - } + // this one will not show in the return since it is not KKFA + customAddress4 := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + PostalCode: "20906", + }, + }, + }, nil) factory.BuildDutyLocation(suite.DB(), []factory.Customization{ - {Model: customAddress4, Type: &factory.Addresses.DutyLocationAddress}, { Model: models.DutyLocation{ ProvidesServicesCounseling: true, @@ -178,6 +200,11 @@ func (suite *TransportationOfficeServiceSuite) Test_FindCounselingOffices() { ProvidesCloseout: true, }, }, + { + Model: customAddress4, + LinkOnly: true, + Type: &factory.Addresses.DutyLocationAddress, + }, }, nil) armyAffliation := models.AffiliationARMY @@ -189,12 +216,9 @@ func (suite *TransportationOfficeServiceSuite) Test_FindCounselingOffices() { }, }, nil) - offices, err := findCounselingOffice(suite.AppContextForTest(), origDutyLocation.ID, serviceMember.ID) - + offices, err := suite.toFetcher.GetCounselingOffices(suite.AppContextForTest(), origDutyLocation.ID, serviceMember.ID) suite.NoError(err) - suite.Len(offices, 2) - suite.Equal(offices[0].Name, "PPPO Hill AFB - USAF") - suite.Equal(offices[1].Name, "PPPO Travis AFB - USAF") + suite.Len(*offices, 2) } func (suite *TransportationOfficeServiceSuite) Test_Oconus_AK_FindCounselingOffices() { @@ -399,7 +423,6 @@ func (suite *TransportationOfficeServiceSuite) Test_Oconus_AK_FindCounselingOffi suite.Nil(err) suite.Equal(2, len(offices)) }) - } func (suite *TransportationOfficeServiceSuite) Test_GetTransportationOffice() { diff --git a/playwright/tests/admin/offices.spec.js b/playwright/tests/admin/offices.spec.js index bf9d2745a8e..ceee23ed984 100644 --- a/playwright/tests/admin/offices.spec.js +++ b/playwright/tests/admin/offices.spec.js @@ -16,7 +16,7 @@ test.describe('Offices Page', () => { await expect(page.locator('header')).toContainText('Offices'); await expect(page.getByLabel('Search by Office Name')).toBeEditable(); - const columnLabels = ['Id', 'Name', 'Latitude', 'Longitude', 'Gbloc']; + const columnLabels = ['Id', 'Name', 'Gbloc']; await adminPage.expectRoleLabelsByText('columnheader', columnLabels); }); }); diff --git a/src/components/Customer/EditOrdersForm/EditOrdersForm.jsx b/src/components/Customer/EditOrdersForm/EditOrdersForm.jsx index ab0b538ba7a..017a2f68973 100644 --- a/src/components/Customer/EditOrdersForm/EditOrdersForm.jsx +++ b/src/components/Customer/EditOrdersForm/EditOrdersForm.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { Formik, Field } from 'formik'; import * as Yup from 'yup'; import { Radio, FormGroup, Label, Link as USWDSLink } from '@trussworks/react-uswds'; +import { connect } from 'react-redux'; import { isBooleanFlagEnabled } from '../../../utils/featureFlags'; @@ -16,7 +17,7 @@ import FileUpload from 'components/FileUpload/FileUpload'; import UploadsTable from 'components/UploadsTable/UploadsTable'; import LoadingPlaceholder from 'shared/LoadingPlaceholder'; import SectionWrapper from 'components/Customer/SectionWrapper'; -import { FEATURE_FLAG_KEYS, documentSizeLimitMsg } from 'shared/constants'; +import { FEATURE_FLAG_KEYS, MOVE_STATUSES, documentSizeLimitMsg } from 'shared/constants'; import profileImage from 'scenes/Review/images/profile.png'; import { DropdownArrayOf } from 'types'; import { ExistingUploadsShape } from 'types/uploads'; @@ -26,6 +27,10 @@ import Callout from 'components/Callout'; import { formatLabelReportByDate, dropdownInputOptions, formatYesNoAPIValue } from 'utils/formatters'; import formStyles from 'styles/form.module.scss'; import { showCounselingOffices } from 'services/internalApi'; +import { setShowLoadingSpinner as setShowLoadingSpinnerAction } from 'store/general/actions'; +import { milmoveLogger } from 'utils/milmoveLog'; +import retryPageLoading from 'utils/retryPageLoading'; +import Hint from 'components/Hint'; const EditOrdersForm = ({ createUpload, @@ -36,6 +41,7 @@ const EditOrdersForm = ({ onSubmit, ordersTypeOptions, onCancel, + setShowLoadingSpinner, }) => { const [officeOptions, setOfficeOptions] = useState(null); const [currentDutyLocation, setDutyLocation] = useState(initialValues.origin_duty_location); @@ -93,7 +99,7 @@ const EditOrdersForm = ({ }); const enableDelete = () => { - const isValuePresent = initialValues.move_status === 'DRAFT'; + const isValuePresent = initialValues.move_status === MOVE_STATUSES.DRAFT; return isValuePresent; }; @@ -113,25 +119,40 @@ const EditOrdersForm = ({ }; checkUBFeatureFlag(); }, []); + useEffect(() => { - showCounselingOffices(currentDutyLocation?.id).then((fetchedData) => { - if (fetchedData.body) { - const counselingOffices = fetchedData.body.map((item) => ({ - key: item.id, - value: item.name, - })); - setOfficeOptions(counselingOffices); + const fetchCounselingOffices = async () => { + if (currentDutyLocation?.id && !officeOptions) { + setShowLoadingSpinner(true, null); + try { + const fetchedData = await showCounselingOffices(currentDutyLocation.id); + if (fetchedData.body) { + const counselingOffices = fetchedData.body.map((item) => ({ + key: item.id, + value: item.name, + })); + setOfficeOptions(counselingOffices); + } + } catch (error) { + const { message } = error; + milmoveLogger.error({ message, info: null }); + retryPageLoading(error); + } + setShowLoadingSpinner(false, null); } - }); + }; + fetchCounselingOffices(); + }, [currentDutyLocation.id, officeOptions, setShowLoadingSpinner]); + + useEffect(() => { // Check if either currentDutyLocation or newDutyLocation is OCONUS if (currentDutyLocation?.address?.isOconus || newDutyLocation?.address?.isOconus) { setIsOconusMove(true); } else { setIsOconusMove(false); } + if (currentDutyLocation?.address && newDutyLocation?.address && enableUB) { - // Only if one of the duty locations is OCONUS should accompanied tour and dependent - // age fields display if (isOconusMove && hasDependents) { setShowAccompaniedTourField(true); setShowDependentAgeFields(true); @@ -140,12 +161,13 @@ const EditOrdersForm = ({ setShowDependentAgeFields(false); } } + if (isLoading && finishedFetchingFF) { // If the form is still loading and the FF has finished fetching, // then the form is done loading setIsLoading(false); } - }, [currentDutyLocation, newDutyLocation, isOconusMove, hasDependents, enableUB, finishedFetchingFF, isLoading]); + }, [currentDutyLocation, newDutyLocation, isOconusMove, hasDependents, enableUB, isLoading, finishedFetchingFF]); if (isLoading) { return ; @@ -272,11 +294,6 @@ const EditOrdersForm = ({ /> {currentDutyLocation?.provides_services_counseling && (
- + + Select an origin duty location that most closely represents your current physical location, not + where your shipment will originate, if different. This will allow a nearby transportation office to + assist. +
)} {isRetirementOrSeparation ? ( @@ -521,4 +543,8 @@ EditOrdersForm.defaultProps = { filePondEl: null, }; -export default EditOrdersForm; +const mapDispatchToProps = { + setShowLoadingSpinner: setShowLoadingSpinnerAction, +}; + +export default connect(() => ({}), mapDispatchToProps)(EditOrdersForm); diff --git a/src/components/Customer/EditOrdersForm/EditOrdersForm.stories.jsx b/src/components/Customer/EditOrdersForm/EditOrdersForm.stories.jsx index d36e367b505..0da5575ec99 100644 --- a/src/components/Customer/EditOrdersForm/EditOrdersForm.stories.jsx +++ b/src/components/Customer/EditOrdersForm/EditOrdersForm.stories.jsx @@ -3,6 +3,7 @@ import React from 'react'; import EditOrdersForm from './EditOrdersForm'; import { ORDERS_TYPE } from 'constants/orders'; +import { MockProviders } from 'testUtils'; const testInitialValues = { orders_type: ORDERS_TYPE.PERMANENT_CHANGE_OF_STATION, @@ -101,49 +102,57 @@ const testProps = { }; export const EmptyValues = (argTypes) => ( - + + + ); export const PrefillNoDependents = (argTypes) => ( - + + + ); export const PrefillYesDependents = (argTypes) => ( - + + + ); export const PCSOnly = (argTypes) => ( - + + + ); diff --git a/src/components/Customer/EditOrdersForm/EditOrdersForm.test.jsx b/src/components/Customer/EditOrdersForm/EditOrdersForm.test.jsx index e073ddcc883..c3e2f420cea 100644 --- a/src/components/Customer/EditOrdersForm/EditOrdersForm.test.jsx +++ b/src/components/Customer/EditOrdersForm/EditOrdersForm.test.jsx @@ -9,6 +9,7 @@ import EditOrdersForm from './EditOrdersForm'; import { documentSizeLimitMsg } from 'shared/constants'; import { showCounselingOffices } from 'services/internalApi'; import { ORDERS_TYPE, ORDERS_TYPE_OPTIONS } from 'constants/orders'; +import { MockProviders } from 'testUtils'; jest.setTimeout(60000); @@ -265,7 +266,11 @@ describe('EditOrdersForm component', () => { [/Pay grade/, true, HTMLSelectElement], [/Current duty location/, false, HTMLInputElement], ])('rendering %s and is required is %s', async (formInput, required, inputType) => { - render(); + render( + + + , + ); expect(await screen.findByLabelText(formInput)).toBeInstanceOf(inputType); if (required) { @@ -276,7 +281,11 @@ describe('EditOrdersForm component', () => { it('rendering the upload area', async () => { showCounselingOffices.mockImplementation(() => Promise.resolve({})); - render(); + render( + + + , + ); expect(await screen.findByText(documentSizeLimitMsg)).toBeInTheDocument(); }); @@ -294,7 +303,11 @@ describe('EditOrdersForm component', () => { ])('rendering the %s option', async (selectionOption, expectedValue) => { isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true)); - render(); + render( + + + , + ); const ordersTypeDropdown = await screen.findByLabelText(/Orders type/); expect(ordersTypeDropdown).toBeInstanceOf(HTMLSelectElement); @@ -309,33 +322,35 @@ describe('EditOrdersForm component', () => { it('allows new and current duty location to be the same', async () => { // Render the component render( - + , + new_duty_location: { + name: 'Luke AFB', + provides_services_counseling: false, + address: { isOconus: false }, + }, + counseling_office_id: '3e937c1f-5539-4919-954d-017989130584', + uploaded_orders: [ + { + id: '123', + createdAt: '2020-11-08', + bytes: 1, + url: 'url', + filename: 'Test Upload', + contentType: 'application/pdf', + }, + ], + }} + /> + , ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); @@ -361,7 +376,11 @@ describe('EditOrdersForm component', () => { }); it('shows an error message if the form is invalid', async () => { - render(); + render( + + + , + ); const submitButton = await screen.findByRole('button', { name: 'Save' }); const ordersTypeDropdown = screen.getByLabelText(/Orders type/); @@ -379,27 +398,29 @@ describe('EditOrdersForm component', () => { it('submits the form when its valid', async () => { // Not testing the upload interaction, so give uploaded orders to the props. render( - + , + counseling_office_id: '3e937c1f-5539-4919-954d-017989130584', + uploaded_orders: [ + { + id: '123', + createdAt: '2020-11-08', + bytes: 1, + url: 'url', + filename: 'Test Upload', + contentType: 'application/pdf', + }, + ], + }} + /> + , ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); @@ -470,7 +491,11 @@ describe('EditOrdersForm component', () => { }); it('implements the onCancel handler when the Cancel button is clicked', async () => { - render(); + render( + + + , + ); const cancelButton = await screen.findByRole('button', { name: 'Cancel' }); @@ -534,7 +559,11 @@ describe('EditOrdersForm component', () => { }; it('pre-fills the inputs', async () => { - render(); + render( + + + , + ); expect(await screen.findByRole('form')).toHaveFormValues({ new_duty_location: 'Yuma AFB', @@ -552,7 +581,11 @@ describe('EditOrdersForm component', () => { }); it('renders the uploads table with an existing upload', async () => { - render(); + render( + + + , + ); await waitFor(() => { expect(screen.queryByText('Test Upload')).toBeInTheDocument(); @@ -628,7 +661,11 @@ describe('EditOrdersForm component', () => { modifiedProps.initialValues[attributeName] = valueToReplaceIt; - render(); + render( + + + , + ); const save = await screen.findByRole('button', { name: 'Save' }); await waitFor(() => { @@ -642,27 +679,29 @@ describe('EditOrdersForm component', () => { it('submits the form when temporary duty orders type is selected', async () => { // Not testing the upload interaction, so give uploaded orders to the props. render( - + , + counseling_office_id: '3e937c1f-5539-4919-954d-017989130584', + uploaded_orders: [ + { + id: '123', + createdAt: '2020-11-08', + bytes: 1, + url: 'url', + filename: 'Test Upload', + contentType: 'application/pdf', + }, + ], + }} + /> + , ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); @@ -702,8 +741,11 @@ describe('EditOrdersForm component', () => { it('has dependents is yes and disabled when order type is student travel', async () => { isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true)); - render(); - + render( + + + , + ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); await userEvent.selectOptions(screen.getByLabelText(/Orders type/), ORDERS_TYPE.STUDENT_TRAVEL); @@ -719,8 +761,11 @@ describe('EditOrdersForm component', () => { }); it('has dependents is yes and disabled when order type is early return', async () => { - render(); - + render( + + + , + ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); await userEvent.selectOptions(screen.getByLabelText(/Orders type/), ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS); @@ -736,8 +781,11 @@ describe('EditOrdersForm component', () => { }); it('has dependents becomes disabled and then re-enabled for order type student travel', async () => { - render(); - + render( + + + , + ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); // set order type to perm change and verify the "has dependents" state @@ -771,8 +819,11 @@ describe('EditOrdersForm component', () => { }); it('has dependents becomes disabled and then re-enabled for order type early return', async () => { - render(); - + render( + + + , + ); await waitFor(() => expect(screen.queryByText('Loading, please wait...')).not.toBeInTheDocument()); // set order type to perm change and verify the "has dependents" state diff --git a/src/components/Customer/OrdersInfoForm/OrdersInfoForm.jsx b/src/components/Customer/OrdersInfoForm/OrdersInfoForm.jsx index 704d3db9953..ca2adac05bd 100644 --- a/src/components/Customer/OrdersInfoForm/OrdersInfoForm.jsx +++ b/src/components/Customer/OrdersInfoForm/OrdersInfoForm.jsx @@ -105,34 +105,28 @@ const OrdersInfoForm = ({ ordersTypeOptions, initialValues, onSubmit, onBack, se } setShowLoadingSpinner(false, null); } + }; + fetchCounselingOffices(); + }, [counselingOfficeOptions, currentDutyLocation.id, setShowLoadingSpinner]); + + useEffect(() => { + // Check if either currentDutyLocation or newDutyLocation is OCONUS + if (currentDutyLocation?.address?.isOconus || newDutyLocation?.address?.isOconus) { + setIsOconusMove(true); + } else { + setIsOconusMove(false); + } - // Check if either currentDutyLocation or newDutyLocation is OCONUS - if (currentDutyLocation?.address?.isOconus || newDutyLocation?.address?.isOconus) { - setIsOconusMove(true); + if (currentDutyLocation?.address && newDutyLocation?.address && enableUB) { + if (isOconusMove && hasDependents) { + setShowAccompaniedTourField(true); + setShowDependentAgeFields(true); } else { - setIsOconusMove(false); + setShowAccompaniedTourField(false); + setShowDependentAgeFields(false); } - - if (currentDutyLocation?.address && newDutyLocation?.address && enableUB) { - if (isOconusMove && hasDependents) { - setShowAccompaniedTourField(true); - setShowDependentAgeFields(true); - } else { - setShowAccompaniedTourField(false); - setShowDependentAgeFields(false); - } - } - }; - fetchCounselingOffices(); - }, [ - currentDutyLocation, - newDutyLocation, - isOconusMove, - hasDependents, - enableUB, - setShowLoadingSpinner, - counselingOfficeOptions, - ]); + } + }, [currentDutyLocation, newDutyLocation, isOconusMove, hasDependents, enableUB]); useEffect(() => { const fetchData = async () => { @@ -260,11 +254,6 @@ const OrdersInfoForm = ({ ordersTypeOptions, initialValues, onSubmit, onBack, se /> {currentDutyLocation.provides_services_counseling && (
- + + Select an origin duty location that most closely represents your current physical location, not + where your shipment will originate, if different. This will allow a nearby transportation office to + assist you. +
)} {isRetirementOrSeparation ? ( diff --git a/src/components/Office/AddOrdersForm/AddOrdersForm.jsx b/src/components/Office/AddOrdersForm/AddOrdersForm.jsx index a2c6be4ff4d..4df4e5774a4 100644 --- a/src/components/Office/AddOrdersForm/AddOrdersForm.jsx +++ b/src/components/Office/AddOrdersForm/AddOrdersForm.jsx @@ -22,6 +22,7 @@ import MaskedTextField from 'components/form/fields/MaskedTextField/MaskedTextFi import formStyles from 'styles/form.module.scss'; import ConnectedFlashMessage from 'containers/FlashMessage/FlashMessage'; import { showCounselingOffices } from 'services/ghcApi'; +import Hint from 'components/Hint'; let originMeta; let newDutyMeta = ''; @@ -217,11 +218,6 @@ const AddOrdersForm = ({ /> {currentDutyLocation.provides_services_counseling && (
- + + Select an origin duty location that most closely represents the customers current physical location, + not where their shipment will originate, if different. This will allow a nearby transportation + office to assist them. +
)} diff --git a/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx b/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx index 416134e0672..cbad67cc0b5 100644 --- a/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx +++ b/src/components/Office/ServiceItemDetails/ServiceItemDetails.jsx @@ -13,6 +13,7 @@ import { SitStatusShape } from 'types/sitStatusShape'; import { formatDateWithUTC } from 'shared/dates'; import { formatCityStateAndPostalCode } from 'utils/shipmentDisplay'; import { formatWeight, convertFromThousandthInchToInch, formatCents, toDollarString } from 'utils/formatters'; +import { SERVICE_ITEM_CODES } from 'constants/serviceItems'; function generateDetailText(details, id, className) { const detailList = Object.keys(details).map((detail) => ( @@ -38,7 +39,7 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai 'First available delivery date 1': '-', 'Customer contact 1': '-', }); - const numberOfDaysApprovedForDOASIT = shipment.sitDaysAllowance ? shipment.sitDaysAllowance - 1 : 0; + const numberOfDaysApprovedForSIT = shipment.sitDaysAllowance ? shipment.sitDaysAllowance - 1 : 0; const sitEndDate = sitStatus && sitStatus.currentSIT?.sitAuthorizedEndDate && @@ -50,7 +51,7 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai return (
- {code === 'DDFSIT' + {code === SERVICE_ITEM_CODES.DDFSIT || code === SERVICE_ITEM_CODES.IDFSIT ? generateDetailText({ 'Original Delivery Address': originalDeliveryAddress ? formatCityStateAndPostalCode(originalDeliveryAddress) @@ -58,7 +59,7 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai 'SIT entry date': details.sitEntryDate ? formatDateWithUTC(details.sitEntryDate, 'DD MMM YYYY') : '-', }) : null} - {code === 'DDASIT' && ( + {code === SERVICE_ITEM_CODES.DDASIT && ( <> {generateDetailText( { @@ -68,7 +69,7 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai "Add'l SIT Start Date": details.sitEntryDate ? moment.utc(details.sitEntryDate).add(1, 'days').format('DD MMM YYYY') : '-', - '# of days approved for': shipment.sitDaysAllowance ? `${numberOfDaysApprovedForDOASIT} days` : '-', + '# of days approved for': shipment.sitDaysAllowance ? `${numberOfDaysApprovedForSIT} days` : '-', 'SIT expiration date': sitEndDate || '-', }, id, @@ -87,7 +88,36 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai ) : null} )} - {code === 'DDSFSC' + {code === SERVICE_ITEM_CODES.IDASIT && ( + <> + {generateDetailText( + { + 'Original Delivery Address': originalDeliveryAddress + ? formatCityStateAndPostalCode(originalDeliveryAddress) + : '-', + "Add'l SIT Start Date": details.sitEntryDate + ? moment.utc(details.sitEntryDate).add(1, 'days').format('DD MMM YYYY') + : '-', + '# of days approved for': shipment.sitDaysAllowance ? `${numberOfDaysApprovedForSIT} days` : '-', + 'SIT expiration date': sitEndDate || '-', + }, + id, + )} + {!isEmpty(serviceRequestDocUploads) ? ( +
+

Download service item documentation:

+ {serviceRequestDocUploads.map((file) => ( + + ))} +
+ ) : null} + + )} + {code === SERVICE_ITEM_CODES.DDSFSC || code === SERVICE_ITEM_CODES.IDSFSC ? generateDetailText( { 'Original Delivery Address': originalDeliveryAddress @@ -102,7 +132,45 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai id, ) : null} - {code === 'DDDSIT' && ( + {code === SERVICE_ITEM_CODES.DDDSIT && ( + <> + {generateDetailText( + { + 'Original Delivery Address': originalDeliveryAddress + ? formatCityStateAndPostalCode(originalDeliveryAddress) + : '-', + 'Final Delivery Address': + details.sitDestinationFinalAddress && details.status !== 'SUBMITTED' + ? formatCityStateAndPostalCode(details.sitDestinationFinalAddress) + : '-', + 'Delivery miles out of SIT': details.sitDeliveryMiles ? details.sitDeliveryMiles : '-', + 'Customer contacted homesafe': details.sitCustomerContacted + ? formatDateWithUTC(details.sitCustomerContacted, 'DD MMM YYYY') + : '-', + 'Customer requested delivery date': details.sitRequestedDelivery + ? formatDateWithUTC(details.sitRequestedDelivery, 'DD MMM YYYY') + : '-', + 'SIT departure date': details.sitDepartureDate + ? formatDateWithUTC(details.sitDepartureDate, 'DD MMM YYYY') + : '-', + }, + id, + )} + {!isEmpty(serviceRequestDocUploads) ? ( +
+

Download service item documentation:

+ {serviceRequestDocUploads.map((file) => ( + + ))} +
+ ) : null} + + )} + {code === SERVICE_ITEM_CODES.IDDSIT && ( <> {generateDetailText( { @@ -140,7 +208,7 @@ const generateDestinationSITDetailSection = (id, serviceRequestDocUploads, detai ) : null} )} - {code === 'DDFSIT' && ( + {(code === SERVICE_ITEM_CODES.DDFSIT || code === SERVICE_ITEM_CODES.IDFSIT) && ( <> {!isEmpty(sortedCustomerContacts) ? sortedCustomerContacts.map((contact, index) => ( @@ -188,7 +256,8 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s let detailSection; switch (code) { - case 'DOFSIT': { + case SERVICE_ITEM_CODES.DOFSIT: + case SERVICE_ITEM_CODES.IOFSIT: { detailSection = (
@@ -221,12 +290,13 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DOASIT': { - const numberOfDaysApprovedForDOASIT = shipment.sitDaysAllowance ? shipment.sitDaysAllowance - 1 : 0; + case SERVICE_ITEM_CODES.DOASIT: + case SERVICE_ITEM_CODES.IOASIT: { const sitEndDate = sitStatus && sitStatus.currentSIT?.sitAuthorizedEndDate && formatDateWithUTC(sitStatus.currentSIT.sitAuthorizedEndDate, 'DD MMM YYYY'); + const numberOfDaysApprovedForSIT = shipment.sitDaysAllowance ? shipment.sitDaysAllowance - 1 : 0; detailSection = (
@@ -239,7 +309,7 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s "Add'l SIT Start Date": details.sitEntryDate ? moment.utc(details.sitEntryDate).add(1, 'days').format('DD MMM YYYY') : '-', - '# of days approved for': shipment.sitDaysAllowance ? `${numberOfDaysApprovedForDOASIT} days` : '-', + '# of days approved for': shipment.sitDaysAllowance ? `${numberOfDaysApprovedForSIT} days` : '-', 'SIT expiration date': sitEndDate || '-', 'Customer contacted homesafe': details.sitCustomerContacted ? formatDateWithUTC(details.sitCustomerContacted, 'DD MMM YYYY') @@ -272,7 +342,10 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DOPSIT': { + case SERVICE_ITEM_CODES.DOPSIT: + case SERVICE_ITEM_CODES.IOPSIT: + case SERVICE_ITEM_CODES.DOSFSC: + case SERVICE_ITEM_CODES.IOSFSC: { detailSection = (
@@ -307,65 +380,14 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DOSFSC': { - detailSection = ( -
-
- {generateDetailText( - { - 'Original Pickup Address': details.sitOriginHHGOriginalAddress - ? formatCityStateAndPostalCode(details.sitOriginHHGOriginalAddress) - : '-', - 'Actual Pickup Address': details.sitOriginHHGActualAddress - ? formatCityStateAndPostalCode(details.sitOriginHHGActualAddress) - : '-', - 'Delivery miles into SIT': details.sitDeliveryMiles ? details.sitDeliveryMiles : '-', - }, - id, - )} - {details.rejectionReason && - generateDetailText({ 'Rejection reason': details.rejectionReason }, id, 'margin-top-2')} - {!isEmpty(serviceRequestDocUploads) ? ( -
-

Download service item documentation:

- {serviceRequestDocUploads.map((file) => ( - - ))} -
- ) : null} -
-
- ); - break; - } - case 'DDFSIT': - case 'DDASIT': { - detailSection = generateDestinationSITDetailSection( - id, - serviceRequestDocUploads, - details, - code, - shipment, - sitStatus, - ); - break; - } - case 'DDDSIT': { - detailSection = generateDestinationSITDetailSection( - id, - serviceRequestDocUploads, - details, - code, - shipment, - sitStatus, - ); - break; - } - case 'DDSFSC': { + case SERVICE_ITEM_CODES.DDFSIT: + case SERVICE_ITEM_CODES.DDASIT: + case SERVICE_ITEM_CODES.IDFSIT: + case SERVICE_ITEM_CODES.IDASIT: + case SERVICE_ITEM_CODES.DDDSIT: + case SERVICE_ITEM_CODES.IDDSIT: + case SERVICE_ITEM_CODES.DDSFSC: + case SERVICE_ITEM_CODES.IDSFSC: { detailSection = generateDestinationSITDetailSection( id, serviceRequestDocUploads, @@ -376,8 +398,8 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DCRT': - case 'DCRTSA': { + case SERVICE_ITEM_CODES.DCRT: + case SERVICE_ITEM_CODES.DCRTSA: { const { description, itemDimensions, crateDimensions } = details; const itemDimensionFormat = `${convertFromThousandthInchToInch( itemDimensions?.length, @@ -415,7 +437,7 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DUCRT': { + case SERVICE_ITEM_CODES.DUCRT: { const { description, itemDimensions, crateDimensions } = details; const itemDimensionFormat = `${convertFromThousandthInchToInch( itemDimensions?.length, @@ -452,8 +474,8 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DOSHUT': - case 'DDSHUT': { + case SERVICE_ITEM_CODES.DOSHUT: + case SERVICE_ITEM_CODES.DDSHUT: { const estimatedWeight = details.estimatedWeight != null ? formatWeight(details.estimatedWeight) : `— lbs`; detailSection = (
@@ -481,8 +503,8 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'IOSHUT': - case 'IDSHUT': { + case SERVICE_ITEM_CODES.IOSHUT: + case SERVICE_ITEM_CODES.IDSHUT: { const estimatedWeight = details.estimatedWeight != null ? formatWeight(details.estimatedWeight) : `— lbs`; detailSection = (
@@ -514,21 +536,21 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'DLH': - case 'DSH': - case 'FSC': - case 'DOP': - case 'DDP': - case 'DPK': - case 'DUPK': - case 'ISLH': - case 'IHPK': - case 'IHUPK': - case 'IUBPK': - case 'IUBUPK': - case 'POEFSC': - case 'PODFSC': - case 'UBP': { + case SERVICE_ITEM_CODES.DLH: + case SERVICE_ITEM_CODES.DSH: + case SERVICE_ITEM_CODES.FSC: + case SERVICE_ITEM_CODES.DOP: + case SERVICE_ITEM_CODES.DDP: + case SERVICE_ITEM_CODES.DPK: + case SERVICE_ITEM_CODES.DUPK: + case SERVICE_ITEM_CODES.ISLH: + case SERVICE_ITEM_CODES.IHPK: + case SERVICE_ITEM_CODES.IHUPK: + case SERVICE_ITEM_CODES.IUBPK: + case SERVICE_ITEM_CODES.IUBUPK: + case SERVICE_ITEM_CODES.POEFSC: + case SERVICE_ITEM_CODES.PODFSC: + case SERVICE_ITEM_CODES.UBP: { detailSection = (
@@ -540,8 +562,8 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'MS': - case 'CS': { + case SERVICE_ITEM_CODES.MS: + case SERVICE_ITEM_CODES.CS: { const { estimatedPrice } = details; detailSection = (
@@ -550,7 +572,7 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'ICRT': { + case SERVICE_ITEM_CODES.ICRT: { const { description, itemDimensions, crateDimensions, market, externalCrate } = details; const itemDimensionFormat = `${convertFromThousandthInchToInch( itemDimensions?.length, @@ -590,7 +612,7 @@ const ServiceItemDetails = ({ id, code, details, serviceRequestDocs, shipment, s ); break; } - case 'IUCRT': { + case SERVICE_ITEM_CODES.IUCRT: { const { description, itemDimensions, crateDimensions, market } = details; const itemDimensionFormat = `${convertFromThousandthInchToInch( itemDimensions?.length, diff --git a/src/components/Office/ServiceItemDetails/ServiceItemDetails.test.jsx b/src/components/Office/ServiceItemDetails/ServiceItemDetails.test.jsx index 53aa270d13f..0aa382213fe 100644 --- a/src/components/Office/ServiceItemDetails/ServiceItemDetails.test.jsx +++ b/src/components/Office/ServiceItemDetails/ServiceItemDetails.test.jsx @@ -170,6 +170,42 @@ describe('ServiceItemDetails Domestic Destination SIT', () => { expect(downloadLink).toBeInstanceOf(HTMLAnchorElement); }); + it('renders IDASIT details', () => { + render( + , + ); + expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('Destination Original Tampa, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText("Add'l SIT Start Date:")).toBeInTheDocument(); + expect(screen.getByText('12 Mar 2024')).toBeInTheDocument(); + + expect(screen.queryByText('Customer contacted homesafe:')).not.toBeInTheDocument(); + expect(screen.queryByText('14 Mar 2024')).not.toBeInTheDocument(); + + expect(screen.getByText('# of days approved for:')).toBeInTheDocument(); + expect(screen.getByText('89 days')).toBeInTheDocument(); + + expect(screen.getByText('SIT expiration date:')).toBeInTheDocument(); + expect(screen.getByText('17 Mar 2024')).toBeInTheDocument(); + + expect(screen.queryByText('Customer requested delivery date:')).not.toBeInTheDocument(); + expect(screen.queryByText('15 Mar 2024')).not.toBeInTheDocument(); + + expect(screen.queryByText('SIT departure date:')).not.toBeInTheDocument(); + expect(screen.queryByText('16 Mar 2024')).not.toBeInTheDocument(); + expect(screen.getByText('Download service item documentation:')).toBeInTheDocument(); + const downloadLink = screen.getByText('receipt.pdf'); + expect(downloadLink).toBeInstanceOf(HTMLAnchorElement); + }); + it('renders DDDSIT details', () => { render(); expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); @@ -193,6 +229,31 @@ describe('ServiceItemDetails Domestic Destination SIT', () => { const downloadLink = screen.getByText('receipt.pdf'); expect(downloadLink).toBeInstanceOf(HTMLAnchorElement); }); + + it('renders IDDSIT details', () => { + render(); + expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('Destination Original Tampa, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Final Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('Destination Final MacDill, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Delivery miles out of SIT:')).toBeInTheDocument(); + expect(screen.getByText('50')).toBeInTheDocument(); + + expect(screen.getByText('Customer contacted homesafe:')).toBeInTheDocument(); + expect(screen.getByText('14 Mar 2024')).toBeInTheDocument(); + + expect(screen.getByText('Customer requested delivery date:')).toBeInTheDocument(); + expect(screen.getByText('15 Mar 2024')).toBeInTheDocument(); + + expect(screen.getByText('SIT departure date:')).toBeInTheDocument(); + expect(screen.getByText('16 Mar 2024')).toBeInTheDocument(); + expect(screen.getByText('Download service item documentation:')).toBeInTheDocument(); + const downloadLink = screen.getByText('receipt.pdf'); + expect(downloadLink).toBeInstanceOf(HTMLAnchorElement); + }); + it('renders DDDSIT details with - for the final delivery address is service item is in submitted state', () => { render( { expect(screen.getByText('Final Delivery Address:')).toBeInTheDocument(); expect(screen.getByText('-')).toBeInTheDocument(); }); + + it('renders IDDSIT details with - for the final delivery address is service item is in submitted state', () => { + render( + , + ); + + expect(screen.getByText('Final Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('-')).toBeInTheDocument(); + }); + it('renders DDFSIT details', () => { render(); expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); expect(screen.getByText('Destination Original Tampa, FL 33621')).toBeInTheDocument(); }); + + it('renders IDFSIT details', () => { + render(); + expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('Destination Original Tampa, FL 33621')).toBeInTheDocument(); + }); + it('renders DDSFSC details', () => { render(); expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); @@ -222,6 +305,19 @@ describe('ServiceItemDetails Domestic Destination SIT', () => { expect(screen.getByText('Delivery miles out of SIT:')).toBeInTheDocument(); expect(screen.getByText('50')).toBeInTheDocument(); }); + + it('renders IDSFSC details', () => { + render(); + expect(screen.getByText('Original Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('Destination Original Tampa, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Final Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('Destination Final MacDill, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Delivery miles out of SIT:')).toBeInTheDocument(); + expect(screen.getByText('50')).toBeInTheDocument(); + }); + it('renders DDSFSC details with - for the final delivery address is service item is in submitted state', () => { render( { expect(screen.getByText('Final Delivery Address:')).toBeInTheDocument(); expect(screen.getByText('-')).toBeInTheDocument(); }); + + it('renders IDSFSC details with - for the final delivery address is service item is in submitted state', () => { + render( + , + ); + + expect(screen.getByText('Final Delivery Address:')).toBeInTheDocument(); + expect(screen.getByText('-')).toBeInTheDocument(); + }); }); describe('ServiceItemDetails Domestic Origin SIT', () => { @@ -272,6 +382,40 @@ describe('ServiceItemDetails Domestic Origin SIT', () => { expect(screen.getByText('16 Mar 2024')).toBeInTheDocument(); }); + it(`renders IOASIT details`, () => { + render( + , + ); + + expect(screen.getByText('Original Pickup Address:')).toBeInTheDocument(); + expect(screen.getByText('Origin Original Tampa, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText("Add'l SIT Start Date:")).toBeInTheDocument(); + expect(screen.getByText('12 Mar 2024')).toBeInTheDocument(); + + expect(screen.getByText('# of days approved for:')).toBeInTheDocument(); + expect(screen.getByText('89 days')).toBeInTheDocument(); + + expect(screen.getByText('SIT expiration date:')).toBeInTheDocument(); + expect(screen.getByText('17 Mar 2024')).toBeInTheDocument(); + + expect(screen.getByText('Customer contacted homesafe:')).toBeInTheDocument(); + expect(screen.getByText('14 Mar 2024')).toBeInTheDocument(); + + expect(screen.getByText('Customer requested delivery date:')).toBeInTheDocument(); + expect(screen.getByText('15 Mar 2024')).toBeInTheDocument(); + + expect(screen.getByText('SIT departure date:')).toBeInTheDocument(); + expect(screen.getByText('16 Mar 2024')).toBeInTheDocument(); + }); + it(`renders DOPSIT details`, () => { render(); @@ -285,6 +429,19 @@ describe('ServiceItemDetails Domestic Origin SIT', () => { expect(screen.getByText('50')).toBeInTheDocument(); }); + it(`renders IOPSIT details`, () => { + render(); + + expect(screen.getByText('Original Pickup Address:')).toBeInTheDocument(); + expect(screen.getByText('Origin Original Tampa, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Actual Pickup Address:')).toBeInTheDocument(); + expect(screen.getByText('Origin Actual MacDill, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Delivery miles into SIT:')).toBeInTheDocument(); + expect(screen.getByText('50')).toBeInTheDocument(); + }); + it(`renders DOSFSC details`, () => { render(); @@ -297,11 +454,24 @@ describe('ServiceItemDetails Domestic Origin SIT', () => { expect(screen.getByText('Delivery miles into SIT:')).toBeInTheDocument(); expect(screen.getByText('50')).toBeInTheDocument(); }); + + it(`renders IOSFSC details`, () => { + render(); + + expect(screen.getByText('Original Pickup Address:')).toBeInTheDocument(); + expect(screen.getByText('Origin Original Tampa, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Actual Pickup Address:')).toBeInTheDocument(); + expect(screen.getByText('Origin Actual MacDill, FL 33621')).toBeInTheDocument(); + + expect(screen.getByText('Delivery miles into SIT:')).toBeInTheDocument(); + expect(screen.getByText('50')).toBeInTheDocument(); + }); }); -describe('ServiceItemDetails for DOFSIT', () => { - it('renders SIT entry date, ZIP, original pickup address, and reason', () => { - render(); +describe('ServiceItemDetails for DOFSIT/IOFSIT - origin 1st day SIT', () => { + it.each([['DOFSIT'], ['IOFSIT']])('renders SIT entry date, ZIP, original pickup address, and reason', (code) => { + render(); expect(screen.getByText('Original Pickup Address:')).toBeInTheDocument(); expect(screen.getByText('Origin Original Tampa, FL 33621')).toBeInTheDocument(); diff --git a/src/components/Office/ServiceItemsTable/ServiceItemsTable.jsx b/src/components/Office/ServiceItemsTable/ServiceItemsTable.jsx index 60f48a93f84..5495ad0fc48 100644 --- a/src/components/Office/ServiceItemsTable/ServiceItemsTable.jsx +++ b/src/components/Office/ServiceItemsTable/ServiceItemsTable.jsx @@ -10,6 +10,7 @@ import { ServiceItemDetailsShape } from '../../../types/serviceItems'; import styles from './ServiceItemsTable.module.scss'; import { SERVICE_ITEM_STATUS } from 'shared/constants'; +import { SERVICE_ITEM_CODES } from 'constants/serviceItems'; import { ALLOWED_RESUBMISSION_SI_CODES, ALLOWED_SIT_UPDATE_SI_CODES } from 'constants/sitUpdates'; import { formatDateFromIso } from 'utils/formatters'; import ServiceItemDetails from 'components/Office/ServiceItemDetails/ServiceItemDetails'; @@ -30,19 +31,37 @@ import { nullSafeStringCompare } from 'utils/string'; // destination SIT function sortServiceItems(items) { // Prioritize service items with codes 'DSH' (shorthaul) and 'DLH' (linehaul) to be at the top of the list - const haulTypeServiceItemCodes = ['DSH', 'DLH']; + const haulTypeServiceItemCodes = [SERVICE_ITEM_CODES.DSH, SERVICE_ITEM_CODES.DLH]; const haulTypeServiceItems = items.filter((item) => haulTypeServiceItemCodes.includes(item.code)); const sortedHaulTypeServiceItems = haulTypeServiceItems.sort( (a, b) => haulTypeServiceItemCodes.indexOf(a.code) - haulTypeServiceItemCodes.indexOf(b.code), ); // Filter and sort destination SIT. Code index is also the sort order - const destinationServiceItemCodes = ['DDFSIT', 'DDASIT', 'DDDSIT', 'DDSFSC']; + const destinationServiceItemCodes = [ + SERVICE_ITEM_CODES.DDFSIT, + SERVICE_ITEM_CODES.DDASIT, + SERVICE_ITEM_CODES.DDDSIT, + SERVICE_ITEM_CODES.DDSFSC, + SERVICE_ITEM_CODES.IDFSIT, + SERVICE_ITEM_CODES.IDASIT, + SERVICE_ITEM_CODES.IDDSIT, + SERVICE_ITEM_CODES.IDSFSC, + ]; const destinationServiceItems = items.filter((item) => destinationServiceItemCodes.includes(item.code)); const sortedDestinationServiceItems = destinationServiceItems.sort( (a, b) => destinationServiceItemCodes.indexOf(a.code) - destinationServiceItemCodes.indexOf(b.code), ); // Filter origin SIT. Code index is also the sort order - const originServiceItemCodes = ['DOFSIT', 'DOASIT', 'DOPSIT', 'DOSFSC']; + const originServiceItemCodes = [ + SERVICE_ITEM_CODES.DOFSIT, + SERVICE_ITEM_CODES.DOASIT, + SERVICE_ITEM_CODES.DOPSIT, + SERVICE_ITEM_CODES.DOSFSC, + SERVICE_ITEM_CODES.IOFSIT, + SERVICE_ITEM_CODES.IOASIT, + SERVICE_ITEM_CODES.IOPSIT, + SERVICE_ITEM_CODES.IOSFSC, + ]; const originServiceItems = items.filter((item) => originServiceItemCodes.includes(item.code)); const sortedOriginServiceItems = originServiceItems.sort( (a, b) => originServiceItemCodes.indexOf(a.code) - originServiceItemCodes.indexOf(b.code), @@ -202,7 +221,7 @@ const ServiceItemsTable = ({ // we don't want to display the "Accept" button for a DLH or DSH service item that was rejected by a shorthaul to linehaul change or vice versa let rejectedDSHorDLHServiceItem = false; if ( - (serviceItem.code === 'DLH' || serviceItem.code === 'DSH') && + (serviceItem.code === SERVICE_ITEM_CODES.DLH || serviceItem.code === SERVICE_ITEM_CODES.DSH) && serviceItem.details.rejectionReason === 'Automatically rejected due to change in delivery address affecting the ZIP code qualification for short haul / line haul.' ) { @@ -215,7 +234,9 @@ const ServiceItemsTable = ({
{serviceItem.serviceItem} - {(code === 'DCRT' || code === 'ICRT') && serviceItem.details.standaloneCrate && ' - Standalone'} + {(code === SERVICE_ITEM_CODES.DCRT || code === SERVICE_ITEM_CODES.ICRT) && + serviceItem.details.standaloneCrate && + ' - Standalone'} {ALLOWED_RESUBMISSION_SI_CODES.includes(code) && resubmittedToolTip.isResubmitted ? ( { - if (code === 'DDFSIT' || code === 'DOFSIT') { + if ( + code === SERVICE_ITEM_CODES.DDFSIT || + code === SERVICE_ITEM_CODES.DOFSIT || + code === SERVICE_ITEM_CODES.IDFSIT || + code === SERVICE_ITEM_CODES.IOFSIT + ) { handleShowEditSitEntryDateModal(id, mtoShipmentID); } else { handleShowEditSitAddressModal(id, mtoShipmentID); diff --git a/src/components/Office/ServiceItemsTable/ServiceItemsTable.test.jsx b/src/components/Office/ServiceItemsTable/ServiceItemsTable.test.jsx index 6b3e4a6ee87..cc159e86625 100644 --- a/src/components/Office/ServiceItemsTable/ServiceItemsTable.test.jsx +++ b/src/components/Office/ServiceItemsTable/ServiceItemsTable.test.jsx @@ -298,6 +298,63 @@ describe('ServiceItemsTable', () => { expect(wrapper.find('dd').at(5).text()).toBe('01 Jan 2021, 0800Z'); }); + it('renders the customer contacts for IDFSIT service item', () => { + const serviceItems = [ + { + id: 'abc123', + createdAt: '2020-11-20', + serviceItem: 'Domestic Crating', + code: 'IDFSIT', + details: { + sitEntryDate: '2020-12-31', + customerContacts: [ + { + timeMilitary: '0400Z', + firstAvailableDeliveryDate: '2020-12-31', + dateOfContact: '2020-12-31', + }, + { timeMilitary: '0800Z', firstAvailableDeliveryDate: '2021-01-01', dateOfContact: '2021-01-01' }, + ], + sitDestinationOriginalAddress: { + city: 'Destination Original Tampa', + eTag: 'MjAyNC0wMy0xMlQxOTo1OTowOC41NjkxMzla', + id: '7fd6cb90-54cd-44d8-8735-102e28734d84', + postalCode: '33621', + state: 'FL', + streetAddress1: 'MacDill', + }, + }, + }, + ]; + + const wrapper = mount( + + + , + ); + + expect(wrapper.find('table').exists()).toBe(true); + expect(wrapper.find('dt').at(0).text()).toBe('Original Delivery Address:'); + expect(wrapper.find('dd').at(0).text()).toBe('Destination Original Tampa, FL 33621'); + + expect(wrapper.find('dt').at(1).text()).toBe('SIT entry date:'); + expect(wrapper.find('dd').at(1).text()).toBe('31 Dec 2020'); + + expect(wrapper.find('dt').at(2).text()).toBe('First available delivery date 1:'); + expect(wrapper.find('dd').at(2).text()).toBe('31 Dec 2020'); + expect(wrapper.find('dt').at(3).text()).toBe('Customer contact attempt 1:'); + expect(wrapper.find('dd').at(3).text()).toBe('31 Dec 2020, 0400Z'); + + expect(wrapper.find('dt').at(4).text()).toBe('First available delivery date 2:'); + expect(wrapper.find('dd').at(4).text()).toBe('01 Jan 2021'); + expect(wrapper.find('dt').at(5).text()).toBe('Customer contact attempt 2:'); + expect(wrapper.find('dd').at(5).text()).toBe('01 Jan 2021, 0800Z'); + }); + it('should render the SITPostalCode ZIP, and reason for DOFSIT service item', () => { const serviceItems = [ { @@ -340,6 +397,48 @@ describe('ServiceItemsTable', () => { expect(wrapper.find('dd').at(2).contains('This is the reason')).toBe(true); }); + it('should render the SITPostalCode ZIP, and reason for IOFSIT service item', () => { + const serviceItems = [ + { + id: 'abc123', + submittedAt: '2020-11-20', + serviceItem: 'Domestic Origin 1st Day SIT', + code: 'IOFSIT', + details: { + pickupPostalCode: '11111', + SITPostalCode: '12345', + reason: 'This is the reason', + sitEntryDate: '2023-12-25T00:00:00.000Z', + sitOriginHHGOriginalAddress: { + city: 'Origin Original Tampa', + eTag: 'MjAyNC0wMy0xMlQxOTo1OTowOC41NjkxMzla', + id: '7fd6cb90-54cd-44d8-8735-102e28734d84', + postalCode: '33621', + state: 'FL', + streetAddress1: 'MacDill', + }, + }, + }, + ]; + + const wrapper = mount( + + + , + ); + expect(wrapper.find('dt').at(0).contains('Original Pickup Address')).toBe(true); + expect(wrapper.find('dd').at(0).contains('Origin Original Tampa, FL 33621')).toBe(true); + + expect(wrapper.find('dt').at(1).contains('SIT entry date')).toBe(true); + expect(wrapper.find('dd').at(1).contains('25 Dec 2023')).toBe(true); + expect(wrapper.find('dt').at(2).contains('Reason')).toBe(true); + expect(wrapper.find('dd').at(2).contains('This is the reason')).toBe(true); + }); + it('calls the update service item status handler when the accept button is clicked', () => { const serviceItems = [ { diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.jsx index 1bb2f9c517d..a56dfd8a78c 100644 --- a/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.jsx +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.jsx @@ -5,6 +5,8 @@ import PropTypes from 'prop-types'; import styles from './CreateShipmentServiceItemForm.module.scss'; import DestinationSITServiceItemForm from './DestinationSITServiceItemForm'; import OriginSITServiceItemForm from './OriginSITServiceItemForm'; +import InternationalDestinationSITServiceItemForm from './InternationalDestinationSITServiceItemForm'; +import InternationalOriginSITServiceItemForm from './InternationalOriginSITServiceItemForm'; import ShuttleSITServiceItemForm from './ShuttleSITServiceItemForm'; import DomesticCratingForm from './DomesticCratingForm'; import InternationalCratingForm from './InternationalCratingForm'; @@ -20,6 +22,8 @@ const CreateShipmentServiceItemForm = ({ shipment, createServiceItemMutation }) const { MTOServiceItemOriginSIT, MTOServiceItemDestSIT, + MTOServiceItemInternationalOriginSIT, + MTOServiceItemInternationalDestSIT, MTOServiceItemDomesticShuttle, MTOServiceItemDomesticCrating, MTOServiceItemInternationalCrating, @@ -49,6 +53,8 @@ const CreateShipmentServiceItemForm = ({ shipment, createServiceItemMutation }) <> + + @@ -61,6 +67,14 @@ const CreateShipmentServiceItemForm = ({ shipment, createServiceItemMutation }) {selectedServiceItemType === MTOServiceItemDestSIT && ( )} + + {selectedServiceItemType === MTOServiceItemInternationalOriginSIT && ( + + )} + {selectedServiceItemType === MTOServiceItemInternationalDestSIT && ( + + )} + {selectedServiceItemType === MTOServiceItemDomesticShuttle && ( )} diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.test.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.test.jsx index 59c136325ce..3efc032ed9e 100644 --- a/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.test.jsx +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/CreateShipmentServiceItemForm.test.jsx @@ -88,6 +88,8 @@ describe('CreateShipmentServiceItemForm component', () => { it.each([ ['originSITServiceItemForm', createServiceItemModelTypes.MTOServiceItemOriginSIT], ['destinationSITServiceItemForm', createServiceItemModelTypes.MTOServiceItemDestSIT], + ['internationalOriginSITServiceItemForm', createServiceItemModelTypes.MTOServiceItemInternationalOriginSIT], + ['internationalDestinationSITServiceItemForm', createServiceItemModelTypes.MTOServiceItemInternationalDestSIT], ['shuttleSITServiceItemForm', createServiceItemModelTypes.MTOServiceItemDomesticShuttle], ['DomesticCratingForm', createServiceItemModelTypes.MTOServiceItemDomesticCrating], ['InternationalCratingForm', createServiceItemModelTypes.MTOServiceItemInternationalCrating], diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalDestinationSITServiceItemForm.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalDestinationSITServiceItemForm.jsx new file mode 100644 index 00000000000..0a4c4ffeb70 --- /dev/null +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalDestinationSITServiceItemForm.jsx @@ -0,0 +1,133 @@ +import * as Yup from 'yup'; +import { Formik } from 'formik'; +import { Button } from '@trussworks/react-uswds'; +import React from 'react'; +import PropTypes from 'prop-types'; + +import { Form } from 'components/form/Form'; +import MaskedTextField from 'components/form/fields/MaskedTextField/MaskedTextField'; +import { formatDateForSwagger } from 'shared/dates'; +import { formatAddressForPrimeAPI } from 'utils/formatters'; +import { DatePickerInput } from 'components/form/fields'; +import { ShipmentShape } from 'types/shipment'; +import TextField from 'components/form/fields/TextField/TextField'; +import Hint from 'components/Hint'; + +const destinationSITValidationSchema = Yup.object().shape({ + reason: Yup.string().required('Required'), + firstAvailableDeliveryDate1: Yup.date().typeError('Enter a complete date in DD MMM YYYY format (day, month, year).'), + timeMilitary1: Yup.string().matches(/^(\d{4}Z)$/, 'Must be a valid military time (e.g. 1400Z)'), + firstAvailableDeliveryDate2: Yup.date().typeError('Enter a complete date in DD MMM YYYY format (day, month, year).'), + timeMilitary2: Yup.string().matches(/^(\d{4}Z)$/, 'Must be a valid military time (e.g. 1400Z)'), + sitEntryDate: Yup.date() + .typeError('Enter a complete date in DD MMM YYYY format (day, month, year).') + .required('Required'), + sitDepartureDate: Yup.date().typeError('Enter a complete date in DD MMM YYYY format (day, month, year).'), +}); + +const InternationalDestinationSITServiceItemForm = ({ shipment, submission }) => { + const initialValues = { + moveTaskOrderID: shipment.moveTaskOrderID, + mtoShipmentID: shipment.id, + modelType: 'MTOServiceItemInternationalDestSIT', + reServiceCode: 'IDFSIT', + reason: '', + firstAvailableDeliveryDate1: '', + dateOfContact1: '', + timeMilitary1: '', + firstAvailableDeliveryDate2: '', + dateOfContact2: '', + timeMilitary2: '', + sitEntryDate: '', + sitDepartureDate: '', + sitDestinationFinalAddress: { streetAddress1: '', streetAddress2: '', city: '', state: '', postalCode: '' }, + }; + + const onSubmit = (values) => { + const { + firstAvailableDeliveryDate1, + firstAvailableDeliveryDate2, + sitEntryDate, + sitDepartureDate, + sitDestinationFinalAddress, + timeMilitary1, + timeMilitary2, + dateOfContact1, + dateOfContact2, + ...serviceItemValues + } = values; + const body = { + firstAvailableDeliveryDate1: formatDateForSwagger(firstAvailableDeliveryDate1), + firstAvailableDeliveryDate2: formatDateForSwagger(firstAvailableDeliveryDate2), + dateOfContact1: formatDateForSwagger(dateOfContact1), + dateOfContact2: formatDateForSwagger(dateOfContact2), + sitEntryDate: formatDateForSwagger(sitEntryDate), + sitDepartureDate: sitDepartureDate ? formatDateForSwagger(sitDepartureDate) : null, + sitDestinationFinalAddress: sitDestinationFinalAddress.streetAddress1 + ? formatAddressForPrimeAPI(sitDestinationFinalAddress) + : null, + timeMilitary1: timeMilitary1 || null, + timeMilitary2: timeMilitary2 || null, + ...serviceItemValues, + }; + submission({ body }); + }; + + return ( + +
+ + + + + + + + + + + + + + + The following service items will be created:
+ IDFSIT (Destination 1st day SIT)
+ IDASIT (Destination additional days SIT)
+ IDDSIT (Destination SIT delivery)
+ IDSFSC (Destination SIT fuel surcharge)
+
+ NOTE: The above service items will use the current delivery address of the shipment as their + final delivery address. Ensure the shipment address is accurate before creating these service items. +
+ + +
+ ); +}; + +InternationalDestinationSITServiceItemForm.propTypes = { + shipment: ShipmentShape.isRequired, + submission: PropTypes.func.isRequired, +}; + +export default InternationalDestinationSITServiceItemForm; diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalDestinationSITServiceItemForm.test.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalDestinationSITServiceItemForm.test.jsx new file mode 100644 index 00000000000..f4cce2860c3 --- /dev/null +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalDestinationSITServiceItemForm.test.jsx @@ -0,0 +1,156 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import InternationalDestinationSITServiceItemForm from './InternationalDestinationSITServiceItemForm'; + +const approvedMoveTaskOrder = { + moveTaskOrder: { + id: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + moveCode: 'LR4T8V', + mtoShipments: [ + { + actualPickupDate: '2020-03-17', + agents: [], + approvedDate: '2021-10-20', + createdAt: '2021-10-21', + customerRemarks: 'Please treat gently', + destinationAddress: { + city: 'Fairfield', + id: 'bfe61147-5fd7-426e-b473-54ccf77bde35', + postalCode: '94535', + state: 'CA', + streetAddress1: '987 Any Avenue', + streetAddress2: 'P.O. Box 9876', + streetAddress3: 'c/o Some Person', + }, + eTag: 'MjAyMS0xMC0xOFQxODoyNDo0MS4zNzc5Nzha', + firstAvailableDeliveryDate: null, + id: 'ce01a5b8-9b44-4511-8a8d-edb60f2a4aee', + moveTaskOrderID: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + pickupAddress: { + city: 'Beverly Hills', + id: 'cf159eca-162c-4131-84a0-795e684416a6', + postalCode: '90210', + state: 'CA', + streetAddress1: '123 Any Street', + streetAddress2: 'P.O. Box 12345', + streetAddress3: 'c/o Some Person', + }, + primeActualWeight: 2000, + primeEstimatedWeight: 1400, + primeEstimatedWeightRecordedDate: null, + requestedPickupDate: '2020-03-15', + requiredDeliveryDate: null, + scheduledPickupDate: '2020-03-16', + secondaryDeliveryAddress: { + city: null, + postalCode: null, + state: null, + streetAddress1: null, + }, + shipmentType: 'HHG', + status: 'APPROVED', + updatedAt: '2021-10-22', + mtoServiceItems: null, + reweigh: { + id: '1234', + weight: 9000, + requestedAt: '2021-10-23', + }, + }, + ], + }, +}; + +describe('InternationalDestinationSITServiceItemForm component', () => { + it.each([ + ['Reason', 'reason'], + ['First available delivery date', 'firstAvailableDeliveryDate1'], + ['First date of attempted contact', 'dateOfContact1'], + ['First time of attempted contact', 'timeMilitary1'], + ['Second available delivery date', 'firstAvailableDeliveryDate2'], + ['Second date of attempted contact', 'dateOfContact2'], + ['Second time of attempted contact', 'timeMilitary2'], + ['SIT entry date', 'sitEntryDate'], + ['SIT departure date', 'sitDepartureDate'], + ])('renders field %s in form', (labelName) => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + render(); + + const field = screen.getByText(labelName); + expect(field).toBeInTheDocument(); + }); + + it('renders hint component at bottom of page - international', async () => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + render( + , + ); + + const hintInfo = screen.getByTestId('destinationSitInfo'); + expect(hintInfo).toBeInTheDocument(); + + expect(hintInfo).toHaveTextContent('The following service items will be created:'); + expect(hintInfo).toHaveTextContent('IDFSIT (Destination 1st day SIT)'); + expect(hintInfo).toHaveTextContent('IDASIT (Destination additional days SIT)'); + expect(hintInfo).toHaveTextContent('IDDSIT (Destination SIT delivery)'); + expect(hintInfo).toHaveTextContent('IDSFSC (Destination SIT fuel surcharge)'); + expect(hintInfo).toHaveTextContent( + 'NOTE: The above service items will use the current delivery address of the shipment as their final delivery address. Ensure the shipment address is accurate before creating these service items.', + ); + }); + + it('renders the Create Service Item button', async () => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + render(); + + // Check if the button renders + const createBtn = screen.getByRole('button', { name: 'Create service item' }); + expect(createBtn).toBeInTheDocument(); + }); + + it('submits values when create service item button is clicked for international destination SIT', async () => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + const submissionMock = jest.fn(); + + render( + , + ); + + await userEvent.type(screen.getByLabelText('Reason'), 'Testing'); + await userEvent.type(screen.getByLabelText('First available delivery date'), '01 Feb 2024'); + await userEvent.type(screen.getByLabelText('First date of attempted contact'), '28 Dec 2023'); + await userEvent.type(screen.getByLabelText('First time of attempted contact'), '1400Z'); + await userEvent.type(screen.getByLabelText('Second available delivery date'), '05 Feb 2024'); + await userEvent.type(screen.getByLabelText('Second date of attempted contact'), '05 Jan 2024'); + await userEvent.type(screen.getByLabelText('Second time of attempted contact'), '1400Z'); + await userEvent.type(screen.getByLabelText('SIT entry date'), '10 Jan 2024'); + await userEvent.type(screen.getByLabelText('SIT departure date'), '24 Jan 2024'); + + // Submit form + await userEvent.click(screen.getByRole('button', { name: 'Create service item' })); + expect(submissionMock).toHaveBeenCalledTimes(1); + expect(submissionMock).toHaveBeenCalledWith({ + body: { + reason: 'Testing', + dateOfContact1: '2023-12-28', + dateOfContact2: '2024-01-05', + firstAvailableDeliveryDate1: '2024-02-01', + firstAvailableDeliveryDate2: '2024-02-05', + modelType: 'MTOServiceItemInternationalDestSIT', + moveTaskOrderID: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + mtoShipmentID: 'ce01a5b8-9b44-4511-8a8d-edb60f2a4aee', + reServiceCode: 'IDFSIT', + sitDepartureDate: '2024-01-24', + sitDestinationFinalAddress: null, + sitEntryDate: '2024-01-10', + timeMilitary1: '1400Z', + timeMilitary2: '1400Z', + }, + }); + }); +}); diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalOriginSITServiceItemForm.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalOriginSITServiceItemForm.jsx new file mode 100644 index 00000000000..76db6a191d6 --- /dev/null +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalOriginSITServiceItemForm.jsx @@ -0,0 +1,110 @@ +import * as Yup from 'yup'; +import { Formik } from 'formik'; +import { Button } from '@trussworks/react-uswds'; +import React from 'react'; +import { useNavigate, useParams, generatePath } from 'react-router-dom'; +import PropTypes from 'prop-types'; + +import { requiredAddressSchema, ZIP_CODE_REGEX } from 'utils/validation'; +import { formatDateForSwagger } from 'shared/dates'; +import { formatAddressForPrimeAPI } from 'utils/formatters'; +import { Form } from 'components/form/Form'; +import TextField from 'components/form/fields/TextField/TextField'; +import MaskedTextField from 'components/form/fields/MaskedTextField/MaskedTextField'; +import { DatePickerInput } from 'components/form/fields'; +import { AddressFields } from 'components/form/AddressFields/AddressFields'; +import { ShipmentShape } from 'types/shipment'; +import { primeSimulatorRoutes } from 'constants/routes'; + +const originSITValidationSchema = Yup.object().shape({ + reason: Yup.string().required('Required'), + sitPostalCode: Yup.string().matches(ZIP_CODE_REGEX, 'Must be valid zip code').required('Required'), + sitEntryDate: Yup.date() + .typeError('Enter a complete date in DD MMM YYYY format (day, month, year).') + .required('Required'), + sitDepartureDate: Yup.date().typeError('Enter a complete date in DD MMM YYYY format (day, month, year).'), + sitHHGActualOrigin: requiredAddressSchema, +}); + +const InternationalOriginSITServiceItemForm = ({ shipment, submission }) => { + const initialValues = { + moveTaskOrderID: shipment.moveTaskOrderID, + mtoShipmentID: shipment.id, + modelType: 'MTOServiceItemInternationalOriginSIT', + reServiceCode: 'IOFSIT', + reason: '', + sitPostalCode: '', + sitEntryDate: '', + sitDepartureDate: '', // The Prime API is currently ignoring origin SIT departure date on creation + sitHHGActualOrigin: { + streetAddress1: '', + streetAddress2: '', + streetAddress3: '', + city: '', + state: '', + postalCode: '', + county: '', + }, + }; + + const onSubmit = (values) => { + const { sitEntryDate, sitDepartureDate, sitHHGActualOrigin, ...serviceItemValues } = values; + const body = { + sitEntryDate: formatDateForSwagger(sitEntryDate), + sitDepartureDate: sitDepartureDate ? formatDateForSwagger(sitDepartureDate) : null, + sitHHGActualOrigin: sitHHGActualOrigin.streetAddress1 ? formatAddressForPrimeAPI(sitHHGActualOrigin) : null, + ...serviceItemValues, + }; + submission({ body }); + }; + + const { moveCodeOrID } = useParams(); + const navigate = useNavigate(); + const handleCancel = () => { + navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); + }; + + return ( + + {({ isValid, isSubmitting, handleSubmit, ...formikProps }) => { + return ( +
+ + + + + + + + + + + + + ); + }} +
+ ); +}; + +InternationalOriginSITServiceItemForm.propTypes = { + shipment: ShipmentShape.isRequired, + submission: PropTypes.func.isRequired, +}; + +export default InternationalOriginSITServiceItemForm; diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalOriginSITServiceItemForm.test.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalOriginSITServiceItemForm.test.jsx new file mode 100644 index 00000000000..f7445e10751 --- /dev/null +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/InternationalOriginSITServiceItemForm.test.jsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; + +import InternationalOriginSITServiceItemForm from './InternationalOriginSITServiceItemForm'; + +import { MockProviders } from 'testUtils'; + +const approvedMoveTaskOrder = { + moveTaskOrder: { + id: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + moveCode: 'LR4T8V', + mtoShipments: [ + { + actualPickupDate: '2020-03-17', + agents: [], + approvedDate: '2021-10-20', + createdAt: '2021-10-21', + customerRemarks: 'Please treat gently', + destinationAddress: { + city: 'Fairfield', + id: 'bfe61147-5fd7-426e-b473-54ccf77bde35', + postalCode: '94535', + state: 'CA', + streetAddress1: '987 Any Avenue', + streetAddress2: 'P.O. Box 9876', + streetAddress3: 'c/o Some Person', + }, + eTag: 'MjAyMS0xMC0xOFQxODoyNDo0MS4zNzc5Nzha', + firstAvailableDeliveryDate: null, + id: 'ce01a5b8-9b44-4511-8a8d-edb60f2a4aee', + moveTaskOrderID: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + pickupAddress: { + city: 'Beverly Hills', + id: 'cf159eca-162c-4131-84a0-795e684416a6', + postalCode: '90210', + state: 'CA', + streetAddress1: '123 Any Street', + streetAddress2: 'P.O. Box 12345', + streetAddress3: 'c/o Some Person', + }, + primeActualWeight: 2000, + primeEstimatedWeight: 1400, + primeEstimatedWeightRecordedDate: null, + requestedPickupDate: '2020-03-15', + requiredDeliveryDate: null, + scheduledPickupDate: '2020-03-16', + secondaryDeliveryAddress: { + city: null, + postalCode: null, + state: null, + streetAddress1: null, + }, + shipmentType: 'HHG', + status: 'APPROVED', + updatedAt: '2021-10-22', + mtoServiceItems: null, + reweigh: { + id: '1234', + weight: 9000, + requestedAt: '2021-10-23', + }, + }, + ], + }, +}; + +const renderWithProviders = (component) => { + render({component}); +}; + +describe('InternationalOriginSITServiceItemForm component', () => { + it.each([ + ['Reason', 'reason'], + ['SIT postal code', 'sitPostalCode'], + ['SIT entry Date', 'sitEntryDate'], + ['SIT departure Date', 'sitDepartureDate'], + ['SIT HHG actual origin', 'sitHHGActualOrigin'], + ])('renders field %s in form', (labelName) => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + renderWithProviders(); + + const field = screen.getByText(labelName); + expect(field).toBeInTheDocument(); + }); + + it('renders the Create Service Item button', async () => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + renderWithProviders(); + + // Check if the button renders + const createBtn = screen.getByRole('button', { name: 'Create service item' }); + expect(createBtn).toBeInTheDocument(); + }); +}); diff --git a/src/components/PrimeUI/CreateShipmentServiceItemForm/OriginSITServiceItemForm.test.jsx b/src/components/PrimeUI/CreateShipmentServiceItemForm/OriginSITServiceItemForm.test.jsx new file mode 100644 index 00000000000..5b261199a02 --- /dev/null +++ b/src/components/PrimeUI/CreateShipmentServiceItemForm/OriginSITServiceItemForm.test.jsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; + +import OriginSITServiceItemForm from './OriginSITServiceItemForm'; + +import { MockProviders } from 'testUtils'; + +const approvedMoveTaskOrder = { + moveTaskOrder: { + id: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + moveCode: 'LR4T8V', + mtoShipments: [ + { + actualPickupDate: '2020-03-17', + agents: [], + approvedDate: '2021-10-20', + createdAt: '2021-10-21', + customerRemarks: 'Please treat gently', + destinationAddress: { + city: 'Fairfield', + id: 'bfe61147-5fd7-426e-b473-54ccf77bde35', + postalCode: '94535', + state: 'CA', + streetAddress1: '987 Any Avenue', + streetAddress2: 'P.O. Box 9876', + streetAddress3: 'c/o Some Person', + }, + eTag: 'MjAyMS0xMC0xOFQxODoyNDo0MS4zNzc5Nzha', + firstAvailableDeliveryDate: null, + id: 'ce01a5b8-9b44-4511-8a8d-edb60f2a4aee', + moveTaskOrderID: '9c7b255c-2981-4bf8-839f-61c7458e2b4d', + pickupAddress: { + city: 'Beverly Hills', + id: 'cf159eca-162c-4131-84a0-795e684416a6', + postalCode: '90210', + state: 'CA', + streetAddress1: '123 Any Street', + streetAddress2: 'P.O. Box 12345', + streetAddress3: 'c/o Some Person', + }, + primeActualWeight: 2000, + primeEstimatedWeight: 1400, + primeEstimatedWeightRecordedDate: null, + requestedPickupDate: '2020-03-15', + requiredDeliveryDate: null, + scheduledPickupDate: '2020-03-16', + secondaryDeliveryAddress: { + city: null, + postalCode: null, + state: null, + streetAddress1: null, + }, + shipmentType: 'HHG', + status: 'APPROVED', + updatedAt: '2021-10-22', + mtoServiceItems: null, + reweigh: { + id: '1234', + weight: 9000, + requestedAt: '2021-10-23', + }, + }, + ], + }, +}; + +const renderWithProviders = (component) => { + render({component}); +}; + +describe('OriginSITServiceItemForm component', () => { + it.each([ + ['Reason', 'reason'], + ['SIT postal code', 'sitPostalCode'], + ['SIT entry Date', 'sitEntryDate'], + ['SIT departure Date', 'sitDepartureDate'], + ['SIT HHG actual origin', 'sitHHGActualOrigin'], + ])('renders field %s in form', (labelName) => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + renderWithProviders(); + + const field = screen.getByText(labelName); + expect(field).toBeInTheDocument(); + }); + + it('renders the Create Service Item button', async () => { + const shipment = approvedMoveTaskOrder.moveTaskOrder.mtoShipments[0]; + + renderWithProviders(); + + // Check if the button renders + const createBtn = screen.getByRole('button', { name: 'Create service item' }); + expect(createBtn).toBeInTheDocument(); + }); +}); diff --git a/src/components/Table/TableQueue.stories.jsx b/src/components/Table/TableQueue.stories.jsx index 346e67fb7dd..94d9321a75d 100644 --- a/src/components/Table/TableQueue.stories.jsx +++ b/src/components/Table/TableQueue.stories.jsx @@ -10,6 +10,7 @@ import { BRANCH_OPTIONS, MOVE_STATUS_OPTIONS } from 'constants/queues'; import SelectFilter from 'components/Table/Filters/SelectFilter'; import DateSelectFilter from 'components/Table/Filters/DateSelectFilter'; import { store } from 'shared/store'; +import { MockProviders } from 'testUtils'; export default { title: 'Office Components/Table', @@ -87,25 +88,32 @@ const defaultProps = { export const TXOTable = () => (
- + + +
); export const TXOTableSortable = () => (
- + + +
); export const TXOTableFilters = () => (
- + + +
); export const TXOTablePagination = () => (
- {' '} - + + +
); diff --git a/src/constants/prime.js b/src/constants/prime.js index 358ea7508de..3316a91955a 100644 --- a/src/constants/prime.js +++ b/src/constants/prime.js @@ -4,6 +4,8 @@ import { serviceItemCodes } from 'content/serviceItems'; export const createServiceItemModelTypes = { MTOServiceItemOriginSIT: 'MTOServiceItemOriginSIT', MTOServiceItemDestSIT: 'MTOServiceItemDestSIT', + MTOServiceItemInternationalOriginSIT: 'MTOServiceItemInternationalOriginSIT', + MTOServiceItemInternationalDestSIT: 'MTOServiceItemInternationalDestSIT', MTOServiceItemDomesticShuttle: 'MTOServiceItemDomesticShuttle', MTOServiceItemDomesticCrating: 'MTOServiceItemDomesticCrating', MTOServiceItemInternationalCrating: 'MTOServiceItemInternationalCrating', diff --git a/src/constants/serviceItems.js b/src/constants/serviceItems.js index a5b7e850b3c..39f62d6511c 100644 --- a/src/constants/serviceItems.js +++ b/src/constants/serviceItems.js @@ -153,6 +153,7 @@ const SERVICE_ITEM_CODES = { FSC: 'FSC', DDSHUT: 'DDSHUT', IDSHUT: 'IDSHUT', + DCRTSA: 'DCRTSA', DCRT: 'DCRT', DUCRT: 'DUCRT', ICRT: 'ICRT', @@ -165,6 +166,17 @@ const SERVICE_ITEM_CODES = { IHPK: 'IHPK', IHUPK: 'IHUPK', ISLH: 'ISLH', + IDDSIT: 'IDDSIT', + IDASIT: 'IDASIT', + IOASIT: 'IOASIT', + IOFSIT: 'IOFSIT', + IOPSIT: 'IOPSIT', + IDFSIT: 'IDFSIT', + IOSFSC: 'IOSFSC', + IDSFSC: 'IDSFSC', + IUBPK: 'IUBPK', + IUBUPK: 'IUBUPK', + UBP: 'UBP', }; const SERVICE_ITEMS_ALLOWED_WEIGHT_BILLED_PARAM = [ @@ -196,6 +208,14 @@ const SERVICE_ITEMS_ALLOWED_UPDATE = [ SERVICE_ITEM_CODES.IOSHUT, SERVICE_ITEM_CODES.PODFSC, SERVICE_ITEM_CODES.POEFSC, + SERVICE_ITEM_CODES.IDDSIT, + SERVICE_ITEM_CODES.IDASIT, + SERVICE_ITEM_CODES.IOASIT, + SERVICE_ITEM_CODES.IOFSIT, + SERVICE_ITEM_CODES.IOPSIT, + SERVICE_ITEM_CODES.IDFSIT, + SERVICE_ITEM_CODES.IOSFSC, + SERVICE_ITEM_CODES.IDSFSC, ]; /** @@ -214,6 +234,18 @@ const SIT_SERVICE_ITEM_CODES = { DDASIT: 'DDASIT', /** Domestic destination SIT delivery */ DDDSIT: 'DDDSIT', + /** International origin 1st day SIT */ + IOFSIT: 'IOFSIT', + /** International origin Additional day SIT */ + IOASIT: 'IOASIT', + /** International origin SIT pickup */ + IOPSIT: 'IOPSIT', + /** International destination 1st day SIT */ + IDFSIT: 'IDFSIT', + /** International destination Additional day SIT */ + IDASIT: 'IDASIT', + /** International destination SIT delivery */ + IDDSIT: 'IDDSIT', }; // TODO - temporary, will remove once all service item calculations are implemented diff --git a/src/constants/sitUpdates.js b/src/constants/sitUpdates.js index 6a724b5e205..7e7bedb2fc2 100644 --- a/src/constants/sitUpdates.js +++ b/src/constants/sitUpdates.js @@ -1,6 +1,6 @@ // allowing edit of SIT entry date for Domestic destination 1st day SIT (DDFSIT) // allowing edit of SIT entry date for Domestic origin 1st day SIT (DOFSIT) -export const ALLOWED_SIT_UPDATE_SI_CODES = ['DOFSIT', 'DDFSIT']; +export const ALLOWED_SIT_UPDATE_SI_CODES = ['DOFSIT', 'DDFSIT', 'IOFSIT', 'IDFSIT']; // allowing display of old service item details for following SIT types which can be resubmitted export const ALLOWED_RESUBMISSION_SI_CODES = [ @@ -12,4 +12,12 @@ export const ALLOWED_RESUBMISSION_SI_CODES = [ 'DOSFSC', 'DDASIT', 'DDSFSC', + 'IDFSIT', + 'IDASIT', + 'IDDSIT', + 'IDSFSC', + 'IOFSIT', + 'IOASIT', + 'IOPSIT', + 'IOSFSC', ]; diff --git a/src/pages/Admin/Offices/OfficeList.jsx b/src/pages/Admin/Offices/OfficeList.jsx index 27a0df55625..50abfc385c4 100644 --- a/src/pages/Admin/Offices/OfficeList.jsx +++ b/src/pages/Admin/Offices/OfficeList.jsx @@ -16,8 +16,6 @@ const OfficeList = () => ( - - diff --git a/src/pages/MyMove/AddOrders.test.jsx b/src/pages/MyMove/AddOrders.test.jsx index fa87055adfd..eddd30dc4fd 100644 --- a/src/pages/MyMove/AddOrders.test.jsx +++ b/src/pages/MyMove/AddOrders.test.jsx @@ -9,7 +9,7 @@ import { createOrders, getServiceMember, showCounselingOffices } from 'services/ import { renderWithProviders } from 'testUtils'; import { customerRoutes, generalRoutes } from 'constants/routes'; import { selectCanAddOrders, selectServiceMemberFromLoggedInUser } from 'store/entities/selectors'; -import { setCanAddOrders, setMoveId } from 'store/general/actions'; +import { setCanAddOrders, setMoveId, setShowLoadingSpinner } from 'store/general/actions'; import { isBooleanFlagEnabled } from 'utils/featureFlags'; import { ORDERS_TYPE } from 'constants/orders'; @@ -54,6 +54,11 @@ jest.mock('store/general/actions', () => ({ type: '', payload: '', })), + setShowLoadingSpinner: jest.fn().mockImplementation(() => ({ + type: '', + showSpinner: false, + loadingSpinnerMessage: '', + })), })); const mockNavigate = jest.fn(); @@ -296,6 +301,23 @@ describe('Add Orders page', () => { ).not.toBeInTheDocument(); }); + it('calls the loading spinner when a current duty location is selected', async () => { + isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true)); + selectServiceMemberFromLoggedInUser.mockImplementation(() => serviceMember); + renderWithProviders(, { + path: customerRoutes.ORDERS_ADD_PATH, + }); + + await screen.findByRole('heading', { level: 1, name: 'Tell us about your move orders' }); + // Select a CONUS current duty location + await userEvent.type(screen.getByLabelText(/Current duty location/), 'AFB', { delay: 100 }); + const selectedOptionCurrent = await screen.findByText(/Altus/); + await userEvent.click(selectedOptionCurrent); + await waitFor(() => { + expect(setShowLoadingSpinner).toHaveBeenCalled(); + }); + }); + it('does not render the input boxes for number of dependents over or under 12 if both locations are CONUS', async () => { selectServiceMemberFromLoggedInUser.mockImplementation(() => serviceMember); renderWithProviders(, { diff --git a/src/pages/MyMove/EditOrders.test.jsx b/src/pages/MyMove/EditOrders.test.jsx index 666e44b65e2..5542da5bddf 100644 --- a/src/pages/MyMove/EditOrders.test.jsx +++ b/src/pages/MyMove/EditOrders.test.jsx @@ -15,6 +15,7 @@ import { } from 'store/entities/selectors'; import { isBooleanFlagEnabled } from 'utils/featureFlags'; import { ORDERS_TYPE } from 'constants/orders'; +import { setShowLoadingSpinner } from 'store/general/actions'; const mockNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ @@ -55,6 +56,15 @@ jest.mock('utils/featureFlags', () => ({ isBooleanFlagEnabled: jest.fn().mockImplementation(() => Promise.resolve(false)), })); +jest.mock('store/general/actions', () => ({ + ...jest.requireActual('store/general/actions'), + setShowLoadingSpinner: jest.fn().mockImplementation(() => ({ + type: '', + showSpinner: false, + loadingSpinnerMessage: '', + })), +})); + describe('EditOrders Page', () => { const testProps = { serviceMember: { @@ -440,5 +450,23 @@ describe('EditOrders Page', () => { }); }); + it('calls the loading spinner on page load', async () => { + renderWithProviders(, { + path: customerRoutes.ORDERS_EDIT_PATH, + params: { moveId: 'testMoveId', orderId: 'testOrders1' }, + }); + + // calls the loading spinner on load + await waitFor(() => { + expect(setShowLoadingSpinner).toHaveBeenCalled(); + }); + + const h1 = await screen.findByRole('heading', { name: 'Orders', level: 1 }); + expect(h1).toBeInTheDocument(); + + const editOrdersHeader = await screen.findByRole('heading', { name: 'Edit Orders:', level: 2 }); + expect(editOrdersHeader).toBeInTheDocument(); + }); + afterEach(jest.clearAllMocks); }); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalDestSITForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalDestSITForm.jsx new file mode 100644 index 00000000000..4de27935ee3 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalDestSITForm.jsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { Formik } from 'formik'; +import { useNavigate, useParams, generatePath } from 'react-router-dom'; +import { FormGroup } from '@trussworks/react-uswds'; +import classnames from 'classnames'; + +import styles from './PrimeUIUpdateSITForms.module.scss'; + +import SectionWrapper from 'components/Customer/SectionWrapper'; +import formStyles from 'styles/form.module.scss'; +import { Form } from 'components/form/Form'; +import TextField from 'components/form/fields/TextField/TextField'; +import WizardNavigation from 'components/Customer/WizardNavigation/WizardNavigation'; +import descriptionListStyles from 'styles/descriptionList.module.scss'; +import { primeSimulatorRoutes } from 'constants/routes'; +import { DatePickerInput } from 'components/form/fields'; +import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; + +const PrimeUIUpdateInternationalDestSITForm = ({ initialValues, onSubmit, serviceItem }) => { + const { moveCodeOrID } = useParams(); + const navigate = useNavigate(); + + const handleClose = () => { + navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); + }; + + return ( + + {({ handleSubmit }) => ( +
+ +
+

Update International Destination SIT Service Item

+ +
+ Here you can update specific fields for an international destination SIT service item.
+ At this time, only the following values can be updated:
{' '} + + SIT Departure Date
+ SIT Requested Delivery
+ SIT Customer Contacted
+ Update Reason +
+
+
+
+ +

+ {serviceItem.reServiceCode} - {serviceItem.reServiceName} +

+
+
+
ID:
+
{serviceItem.id}
+
+
+
MTO ID:
+
{serviceItem.moveTaskOrderID}
+
+
+
Shipment ID:
+
{serviceItem.mtoShipmentID}
+
+
+
Status:
+
{serviceItem.status}
+
+
+
+ + + +
+ {serviceItem.status === SERVICE_ITEM_STATUSES.REJECTED && ( + + )} +
+ +
+
+
+ )} +
+ ); +}; + +export default PrimeUIUpdateInternationalDestSITForm; diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalDestSITForm.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalDestSITForm.test.jsx new file mode 100644 index 00000000000..2286ccacac8 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalDestSITForm.test.jsx @@ -0,0 +1,99 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import PrimeUIUpdateDestSITForm from './PrimeUIUpdateDestSITForm'; + +import { fromPrimeAPIAddressFormat } from 'utils/formatters'; +import { renderWithProviders } from 'testUtils'; +import { primeSimulatorRoutes } from 'constants/routes'; + +const shipmentAddress = { + streetAddress1: '444 Main Ave', + streetAddress2: 'Apartment 9000', + streetAddress3: 'Something else', + city: 'Anytown', + state: 'AL', + postalCode: '90210', +}; + +const serviceItem = { + reServiceCode: 'IDDSIT', + reServiceName: 'International destination SIT delivery', +}; + +const reformatPrimeApiSITDestinationAddress = fromPrimeAPIAddressFormat(shipmentAddress); + +const destSitInitialValues = { + sitDestinationFinalAddress: reformatPrimeApiSITDestinationAddress, + sitDepartureDate: '01 Nov 2023', + sitRequestedDelivery: '01 Dec 2023', + sitCustomerContacted: '15 Oct 2023', + mtoServiceItemID: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + reServiceCode: 'IDDSIT', +}; + +// Mock the react-router-dom functions +const mockNavigate = jest.fn(); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockNavigate, + useParams: jest.fn().mockReturnValue({ moveCodeOrID: ':moveCodeOrID' }), +})); + +describe('PrimeUIRequestInternationalSITDestAddressChangeForm', () => { + it('renders the address change request form', async () => { + renderWithProviders( + , + ); + + expect(screen.getByRole('heading', { name: 'Update Destination SIT Service Item', level: 2 })).toBeInTheDocument(); + expect( + screen.getByRole('heading', { name: 'IDDSIT - International destination SIT delivery', level: 3 }), + ).toBeInTheDocument(); + expect(await screen.findByLabelText('SIT Departure Date')).toHaveValue('01 Nov 2023'); + expect(await screen.findByLabelText('SIT Requested Delivery')).toHaveValue('01 Dec 2023'); + expect(await screen.findByLabelText('SIT Customer Contacted')).toHaveValue('15 Oct 2023'); + expect(screen.getByRole('button', { name: 'Save' })).toBeEnabled(); + expect(screen.getByRole('button', { name: 'Cancel' })).toBeEnabled(); + }); + + it('fires off onSubmit function when save button is clicked', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).toHaveBeenCalled(); + }); + + it('directs the user back to the move page when cancel button is clicked', async () => { + renderWithProviders( + , + ); + + const cancelButton = await screen.findByRole('button', { name: 'Cancel' }); + + await userEvent.click(cancelButton); + + expect(mockNavigate).toHaveBeenCalledWith(primeSimulatorRoutes.VIEW_MOVE_PATH); + }); +}); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalOriginSITForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalOriginSITForm.jsx new file mode 100644 index 00000000000..eead130eff2 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalOriginSITForm.jsx @@ -0,0 +1,103 @@ +import React from 'react'; +import { Formik } from 'formik'; +import { useNavigate, useParams, generatePath } from 'react-router-dom'; +import { FormGroup } from '@trussworks/react-uswds'; +import classnames from 'classnames'; + +import styles from './PrimeUIUpdateSITForms.module.scss'; + +import SectionWrapper from 'components/Customer/SectionWrapper'; +import formStyles from 'styles/form.module.scss'; +import { Form } from 'components/form/Form'; +import TextField from 'components/form/fields/TextField/TextField'; +import WizardNavigation from 'components/Customer/WizardNavigation/WizardNavigation'; +import descriptionListStyles from 'styles/descriptionList.module.scss'; +import { primeSimulatorRoutes } from 'constants/routes'; +import { DatePickerInput } from 'components/form/fields'; +import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; + +const PrimeUIUpdateInternationalOriginSITForm = ({ initialValues, onSubmit, serviceItem }) => { + const { moveCodeOrID } = useParams(); + const navigate = useNavigate(); + + const handleClose = () => { + navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); + }; + + return ( + + {({ handleSubmit }) => ( +
+ +
+

Update International Origin SIT Service Item

+ +
+ Here you can update specific fields for an origin SIT service item.
+ At this time, only the following values can be updated:
{' '} + + SIT Departure Date
+ SIT Requested Delivery
+ SIT Customer Contacted
+ Update Reason +
+
+
+
+ +

+ {serviceItem.reServiceCode} - {serviceItem.reServiceName} +

+
+
+
ID:
+
{serviceItem.id}
+
+
+
MTO ID:
+
{serviceItem.moveTaskOrderID}
+
+
+
Shipment ID:
+
{serviceItem.mtoShipmentID}
+
+
+
Status:
+
{serviceItem.status}
+
+
+
+ + + +
+ {serviceItem.status === SERVICE_ITEM_STATUSES.REJECTED && ( + + )} +
+ +
+
+
+ )} +
+ ); +}; + +export default PrimeUIUpdateInternationalOriginSITForm; diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalOriginSITForm.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalOriginSITForm.test.jsx new file mode 100644 index 00000000000..cad194d17c6 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalOriginSITForm.test.jsx @@ -0,0 +1,84 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import PrimeUIUpdateOriginSITForm from './PrimeUIUpdateOriginSITForm'; + +import { renderWithProviders } from 'testUtils'; +import { primeSimulatorRoutes } from 'constants/routes'; + +const originSitInitialValues = { + sitDepartureDate: '01 Nov 2023', + sitRequestedDelivery: '01 Dec 2023', + sitCustomerContacted: '15 Oct 2023', + mtoServiceItemID: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + reServiceCode: 'IOPSIT', +}; + +const serviceItem = { + reServiceCode: 'IOPSIT', + reServiceName: 'International origin SIT pickup', +}; + +// Mock the react-router-dom functions +const mockNavigate = jest.fn(); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockNavigate, + useParams: jest.fn().mockReturnValue({ moveCodeOrID: ':moveCodeOrID' }), +})); + +describe('PrimeUIRequestInternationalSITDestAddressChangeForm', () => { + it('renders the address change request form', async () => { + renderWithProviders( + , + ); + + expect(screen.getByRole('heading', { name: 'Update Origin SIT Service Item', level: 2 })).toBeInTheDocument(); + expect( + screen.getByRole('heading', { name: 'IOPSIT - International origin SIT pickup', level: 3 }), + ).toBeInTheDocument(); + expect(await screen.findByLabelText('SIT Departure Date')).toHaveValue('01 Nov 2023'); + expect(await screen.findByLabelText('SIT Requested Delivery')).toHaveValue('01 Dec 2023'); + expect(await screen.findByLabelText('SIT Customer Contacted')).toHaveValue('15 Oct 2023'); + expect(screen.getByRole('button', { name: 'Save' })).toBeEnabled(); + expect(screen.getByRole('button', { name: 'Cancel' })).toBeEnabled(); + }); + + it('fires off onSubmit function when save button is clicked', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).toHaveBeenCalled(); + }); + + it('directs the user back to the move page when cancel button is clicked', async () => { + renderWithProviders( + , + ); + + const cancelButton = await screen.findByRole('button', { name: 'Cancel' }); + + await userEvent.click(cancelButton); + + expect(mockNavigate).toHaveBeenCalledWith(primeSimulatorRoutes.VIEW_MOVE_PATH); + }); +}); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx index 307303284f2..de05308a0d6 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx @@ -6,6 +6,8 @@ import { connect } from 'react-redux'; import PrimeUIUpdateOriginSITForm from './PrimeUIUpdateOriginSITForm'; import PrimeUIUpdateDestSITForm from './PrimeUIUpdateDestSITForm'; +import PrimeUIUpdateInternationalOriginSITForm from './PrimeUIUpdateInternationalOriginSITForm'; +import PrimeUIUpdateInternationalDestSITForm from './PrimeUIUpdateInternationalDestSITForm'; import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; import PrimeUIUpdateInternationalShuttleForm from './PrimeUIUpdateInternationalShuttleForm'; @@ -72,7 +74,12 @@ const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { const { modelType } = serviceItem; let initialValues; let onSubmit; - if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { + if ( + modelType === 'MTOServiceItemOriginSIT' || + modelType === 'MTOServiceItemDestSIT' || + modelType === 'MTOServiceItemInternationalDestSIT' || + modelType === 'MTOServiceItemInternationalOriginSIT' + ) { initialValues = { sitEntryDate: formatDateWithUTC(serviceItem.sitEntryDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', @@ -145,6 +152,21 @@ const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { onSubmit={onSubmit} /> ) : null} + {modelType === 'MTOServiceItemInternationalDestSIT' ? ( + + ) : null} + {modelType === 'MTOServiceItemInternationalOriginSIT' ? ( + + ) : null} {modelType === 'MTOServiceItemInternationalFuelSurcharge' ? ( { expect(screen.getByRole('textbox', { name: 'SIT Customer Contacted' })).toBeInTheDocument(); expect(screen.getByRole('textbox', { name: 'Update Reason' })).toBeInTheDocument(); }); + + it('renders the destination sit service item form - international', async () => { + const routingParams = { + moveCodeOrID: 'bf2fc98f-3cb5-40a0-a125-4c222096c35b', + mtoServiceItemId: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + }; + + const renderComponent = () => { + render( + + + + + , + ); + }; + + const moveTaskOrder = { + id: '1', + moveCode: 'LN4T89', + mtoShipments: [ + { + id: '2', + shipmentType: 'HHG', + requestedPickupDate: '2021-11-26', + pickupAddress: { streetAddress1: '100 1st Avenue', city: 'New York', state: 'NY', postalCode: '10001' }, + }, + ], + mtoServiceItems: [ + { + reServiceCode: 'IDDSIT', + modelType: 'MTOServiceItemInternationalDestSIT', + reason: 'Holiday break', + sitDestinationFinalAddress: { + streetAddress1: '444 Main Ave', + streetAddress2: 'Apartment 9000', + streetAddress3: 'c/o Some Person', + city: 'Anytown', + state: 'AL', + postalCode: '90210', + }, + id: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + status: 'REJECTED', + }, + ], + }; + + const moveReturnValue = { + moveTaskOrder, + isLoading: false, + isError: false, + }; + usePrimeSimulatorGetMove.mockReturnValue(moveReturnValue); + + renderComponent(); + + expect( + screen.getByRole('heading', { name: 'Update International Destination SIT Service Item', level: 2 }), + ).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'SIT Departure Date' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'SIT Requested Delivery' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'SIT Customer Contacted' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'Update Reason' })).toBeInTheDocument(); + }); + + it('renders the origin sit service item form - international', async () => { + const routingParams = { + moveCodeOrID: 'bf2fc98f-3cb5-40a0-a125-4c222096c35b', + mtoServiceItemId: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + }; + + const renderComponent = () => { + render( + + + + + , + ); + }; + + const moveTaskOrder = { + id: '1', + moveCode: 'LN4T89', + mtoShipments: [ + { + id: '2', + shipmentType: 'HHG', + requestedPickupDate: '2021-11-26', + pickupAddress: { streetAddress1: '100 1st Avenue', city: 'New York', state: 'NY', postalCode: '10001' }, + }, + ], + mtoServiceItems: [ + { + reServiceCode: 'IDDSIT', + modelType: 'MTOServiceItemInternationalOriginSIT', + reason: 'Holiday break', + sitDestinationFinalAddress: { + streetAddress1: '444 Main Ave', + streetAddress2: 'Apartment 9000', + streetAddress3: 'c/o Some Person', + city: 'Anytown', + state: 'AL', + postalCode: '90210', + }, + id: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + status: 'REJECTED', + }, + ], + }; + + const moveReturnValue = { + moveTaskOrder, + isLoading: false, + isError: false, + }; + usePrimeSimulatorGetMove.mockReturnValue(moveReturnValue); + + renderComponent(); + + expect( + screen.getByRole('heading', { name: 'Update International Origin SIT Service Item', level: 2 }), + ).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'SIT Departure Date' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'SIT Requested Delivery' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'SIT Customer Contacted' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'Update Reason' })).toBeInTheDocument(); + }); }); diff --git a/src/shared/constants.js b/src/shared/constants.js index bdc43c7d035..177e21bb087 100644 --- a/src/shared/constants.js +++ b/src/shared/constants.js @@ -118,6 +118,18 @@ export const SHIPMENT_TYPES = { UNACCOMPANIED_BAGGAGE: 'UNACCOMPANIED_BAGGAGE', }; +export const PPM_TYPES = { + INCENTIVE_BASED: 'INCENTIVE_BASED', + ACTUAL_EXPENSE: 'ACTUAL_EXPENSE', + SMALL_PACKAGE: 'SMALL_PACKAGE', +}; + +export const ppmTypeLabels = [ + { key: PPM_TYPES.INCENTIVE_BASED, label: 'Incentive-based' }, + { key: PPM_TYPES.ACTUAL_EXPENSE, label: 'Actual Expense' }, + { key: PPM_TYPES.SMALL_PACKAGE, label: 'Small Package' }, +]; + // These constants are used for forming URLs that have the shipment type in // them so that they are human readable. export const SHIPMENT_OPTIONS_URL = { @@ -219,6 +231,7 @@ export const DEFAULT_EMPTY_VALUE = '—'; // emdash export const FEATURE_FLAG_KEYS = { PPM: 'ppm', + PPM_SPR: 'ppm_spr', NTS: 'nts', NTSR: 'ntsr', BOAT: 'boat', diff --git a/swagger-def/admin.yaml b/swagger-def/admin.yaml index ccbce27b6bb..f381b35b799 100644 --- a/swagger-def/admin.yaml +++ b/swagger-def/admin.yaml @@ -1047,14 +1047,6 @@ definitions: type: string pattern: "^[A-Z]{4}$" example: JENQ - latitude: - type: number - format: float - example: 29.382973 - longitude: - type: number - format: float - example: -98.62759 createdAt: type: string format: date-time diff --git a/swagger-def/definitions/PPMShipment.yaml b/swagger-def/definitions/PPMShipment.yaml index c75524f94eb..274ec216a0b 100644 --- a/swagger-def/definitions/PPMShipment.yaml +++ b/swagger-def/definitions/PPMShipment.yaml @@ -7,6 +7,8 @@ properties: format: uuid type: string readOnly: true + ppmType: + $ref: 'PPMType.yaml' shipmentId: description: The id of the parent MTOShipment object example: 1f2270c7-7166-40ae-981e-b200ebdf3054 diff --git a/swagger-def/definitions/PPMType.yaml b/swagger-def/definitions/PPMType.yaml new file mode 100644 index 00000000000..a87dc0c57ee --- /dev/null +++ b/swagger-def/definitions/PPMType.yaml @@ -0,0 +1,8 @@ +type: string +title: PPM Type +description: Defines a PPM type +readOnly: true +enum: + - INCENTIVE_BASED + - ACTUAL_EXPENSE + - SMALL_PACKAGE diff --git a/swagger-def/definitions/prime/MTOServiceItemInternationalDestSIT.yaml b/swagger-def/definitions/prime/MTOServiceItemInternationalDestSIT.yaml new file mode 100644 index 00000000000..c356798e521 --- /dev/null +++ b/swagger-def/definitions/prime/MTOServiceItemInternationalDestSIT.yaml @@ -0,0 +1,74 @@ +description: Describes a international destination SIT service item. Subtype of a MTOServiceItem. +allOf: + - $ref: 'MTOServiceItem.yaml' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IDFSIT # International Destination First Day SIT + - IDASIT # International Destination Additional SIT + dateOfContact1: + format: date + type: string + description: Date of attempted contact by the prime corresponding to `timeMilitary1`. + x-nullable: true + dateOfContact2: + format: date + type: string + description: Date of attempted contact by the prime corresponding to `timeMilitary2`. + x-nullable: true + timeMilitary1: + type: string + example: 1400Z + description: Time of attempted contact corresponding to `dateOfContact1`, in military format. + pattern: '\d{4}Z' + x-nullable: true + timeMilitary2: + type: string + example: 1400Z + description: Time of attempted contact corresponding to `dateOfContact2`, in military format. + pattern: '\d{4}Z' + x-nullable: true + firstAvailableDeliveryDate1: + format: date + type: string + description: First available date that Prime can deliver SIT service item. + x-nullable: true + firstAvailableDeliveryDate2: + format: date + type: string + description: Second available date that Prime can deliver SIT service item. + x-nullable: true + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + description: Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + x-nullable: true + sitDestinationFinalAddress: + $ref: '../Address.yaml' + reason: + type: string + description: > + The reason item has been placed in SIT. + x-nullable: true + x-omitempty: false + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: Date when the customer contacted the prime for a delivery out of SIT. + x-nullable: true + required: + - reServiceCode + - sitEntryDate + - reason diff --git a/swagger-def/definitions/prime/MTOServiceItemInternationalOriginSIT.yaml b/swagger-def/definitions/prime/MTOServiceItemInternationalOriginSIT.yaml new file mode 100644 index 00000000000..26843f1c6ec --- /dev/null +++ b/swagger-def/definitions/prime/MTOServiceItemInternationalOriginSIT.yaml @@ -0,0 +1,50 @@ +description: Describes a international origin SIT service item. Subtype of a MTOServiceItem. +allOf: + - $ref: 'MTOServiceItem.yaml' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IOFSIT # International Origin First Day SIT + - IOASIT # International Origin Additional SIT + reason: + type: string + example: Storage items need to be picked up + description: Explanation of why Prime is picking up SIT item. + sitPostalCode: + type: string + format: zip + example: '90210' + pattern: '^(\d{5}([\-]\d{4})?)$' + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + x-nullable: true + description: Departure date for SIT. This is the end date of the SIT at either origin or destination. This is optional as it can be updated using the UpdateMTOServiceItemSIT modelType at a later date. + sitHHGActualOrigin: + $ref: '../Address.yaml' + sitHHGOriginalOrigin: + $ref: '../Address.yaml' + requestApprovalsRequestedStatus: + type: boolean + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: Date when the customer contacted the prime for a delivery out of SIT. + x-nullable: true + required: + - reServiceCode + - reason + - sitPostalCode + - sitEntryDate diff --git a/swagger-def/definitions/prime/MTOServiceItemModelType.yaml b/swagger-def/definitions/prime/MTOServiceItemModelType.yaml index 402844ae3ea..cbaeb7d4afe 100644 --- a/swagger-def/definitions/prime/MTOServiceItemModelType.yaml +++ b/swagger-def/definitions/prime/MTOServiceItemModelType.yaml @@ -6,6 +6,8 @@ description: > corresponding to the service item type. * DOFSIT, DOASIT - MTOServiceItemOriginSIT * DDFSIT, DDASIT - MTOServiceItemDestSIT + * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT + * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT * DOSHUT, DDSHUT - MTOServiceItemShuttle * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -19,6 +21,8 @@ enum: - MTOServiceItemBasic - MTOServiceItemOriginSIT - MTOServiceItemDestSIT + - MTOServiceItemInternationalOriginSIT + - MTOServiceItemInternationalDestSIT - MTOServiceItemShuttle - MTOServiceItemDomesticShuttle - MTOServiceItemInternationalShuttle diff --git a/swagger-def/prime.yaml b/swagger-def/prime.yaml index a26a330da88..6bfaed1fa76 100644 --- a/swagger-def/prime.yaml +++ b/swagger-def/prime.yaml @@ -756,6 +756,82 @@ paths: **Addt'l days destination SIT service item**. This represents an additional day of storage for the same item. Additional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**. + + --- + + **`MTOServiceItemInternationalOriginSIT`** + + MTOServiceItemInternationalOriginSIT is a subtype of MTOServiceItem. + + This model type describes a international origin SIT service item. Items can be created using this + model type with the following codes: + + **IOFSIT** + + **1st day origin SIT service item**. When a IOFSIT is requested, the API will auto-create the following group of service items: + * IOFSIT - International origin 1st day SIT + * IOASIT - International origin Additional day SIT + * IOPSIT - International origin SIT pickup + * IOSFSC - International origin SIT fuel surcharge + + **IOASIT** + + **Addt'l days origin SIT service item**. This represents an additional day of storage for the same item. + Additional IOASIT service items can be created and added to an existing shipment that **includes a IOFSIT service item**. + + --- + + **`MTOServiceItemInternationalDestSIT`** + + MTOServiceItemInternationalDestSIT is a subtype of MTOServiceItem. + + This model type describes a international destination SIT service item. Items can be created using this + model type with the following codes: + + **IDFSIT** + + **1st day destination SIT service item**. + + These additional fields are optional for creating a IDFSIT: + * `firstAvailableDeliveryDate1` + * string + * First available date that Prime can deliver SIT service item. + * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together + * `dateOfContact1` + * string + * Date of attempted contact by the prime corresponding to `timeMilitary1` + * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together + * `timeMilitary1` + * string\d{4}Z + * Time of attempted contact corresponding to `dateOfContact1`, in military format. + * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together + * `firstAvailableDeliveryDate2` + * string + * Second available date that Prime can deliver SIT service item. + * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together + * `dateOfContact2` + * string + * Date of attempted contact delivery by the prime corresponding to `timeMilitary2` + * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together + * `timeMilitary2` + * string\d{4}Z + * Time of attempted contact corresponding to `dateOfContact2`, in military format. + * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together + + When a IDFSIT is requested, the API will auto-create the following group of service items: + * IDFSIT - International destination 1st day SIT + * IDASIT - International destination Additional day SIT + * IDDSIT - International destination SIT delivery + * IDSFSC - International destination SIT fuel surcharge + + **NOTE** When providing the `sitEntryDate` value in the payload, please ensure that the date is not BEFORE + `firstAvailableDeliveryDate1` or `firstAvailableDeliveryDate2`. If it is, you will receive an error response. + + **IDASIT** + + **Addt'l days destination SIT service item**. This represents an additional day of storage for the same item. + Additional IDASIT service items can be created and added to an existing shipment that **includes a IDFSIT service item**. + operationId: createMTOServiceItem tags: - mtoServiceItem @@ -822,6 +898,14 @@ paths: - DOFSIT - DDSFSC - DOSFSC + - IDASIT + - IDDSIT + - IDFSIT + - IOASIT + - IOPSIT + - IOFSIT + - IDSFSC + - IOSFSC The following Accessorial service items can be resubmitted following a rejection: - IOSHUT @@ -1758,12 +1842,16 @@ definitions: $ref: 'definitions/prime/MTOServiceItemBasic.yaml' MTOServiceItemDestSIT: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemDestSIT.yaml' + MTOServiceItemInternationalDestSIT: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalDestSIT.yaml' MTOServiceItemDomesticCrating: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemDomesticCrating.yaml' MTOServiceItemInternationalCrating: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemInternationalCrating.yaml' MTOServiceItemOriginSIT: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemOriginSIT.yaml' + MTOServiceItemInternationalOriginSIT: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalOriginSIT.yaml' MTOServiceItemShuttle: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemShuttle.yaml' MTOServiceItemDomesticShuttle: # spectral oas2-unused-definition is OK here due to polymorphism @@ -1808,6 +1896,8 @@ definitions: This should be populated for the following service items: * DOASIT(Domestic origin Additional day SIT) * DDASIT(Domestic destination Additional day SIT) + * IOASIT(International origin Additional day SIT) + * IDASIT(International destination Additional day SIT) Both take in the following param keys: * `SITPaymentRequestStart` @@ -1852,6 +1942,14 @@ definitions: * DOFSIT - UpdateMTOServiceItemSIT * DOSFSC - UpdateMTOServiceItemSIT * DDSFSC - UpdateMTOServiceItemSIT + * IDDSIT - UpdateMTOServiceItemSIT + * IDFSIT - UpdateMTOServiceItemSIT + * IDASIT - UpdateMTOServiceItemSIT + * IOPSIT - UpdateMTOServiceItemSIT + * IOASIT - UpdateMTOServiceItemSIT + * IOFSIT - UpdateMTOServiceItemSIT + * IOSFSC - UpdateMTOServiceItemSIT + * IDSFSC - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle * PODFSC - UpdateMTOServiceItemInternationalPortFSC @@ -1942,6 +2040,14 @@ definitions: - DOASIT # Domestic Origin Add'l Days SIT - DOFSIT # Domestic Origin 1st Day SIT - DOSFSC # Domestic Origin Fuel Surcharge + - IDDSIT # International Destination SIT Delivery + - IDASIT # International Destination Add'l Days SIT + - IDFSIT # International Destination 1st Day SIT + - IDSFSC # International Destination Fuel Surcharge + - IOPSIT # International Origin SIT Pickup + - IOASIT # International Origin Add'l Days SIT + - IOFSIT # International Origin 1st Day SIT + - IOSFSC # International Origin Fuel Surcharge sitDepartureDate: format: date type: string diff --git a/swagger-def/prime_v2.yaml b/swagger-def/prime_v2.yaml index 7569e750568..1458d5036a2 100644 --- a/swagger-def/prime_v2.yaml +++ b/swagger-def/prime_v2.yaml @@ -349,12 +349,16 @@ definitions: $ref: 'definitions/prime/MTOServiceItemBasic.yaml' MTOServiceItemDestSIT: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemDestSIT.yaml' + MTOServiceItemInternationalDestSIT: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalDestSIT.yaml' MTOServiceItemDomesticCrating: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemDomesticCrating.yaml' MTOServiceItemInternationalCrating: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemInternationalCrating.yaml' MTOServiceItemOriginSIT: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemOriginSIT.yaml' + MTOServiceItemInternationalOriginSIT: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalOriginSIT.yaml' MTOServiceItemShuttle: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemShuttle.yaml' MTOServiceItemDomesticShuttle: # spectral oas2-unused-definition is OK here due to polymorphism @@ -613,6 +617,10 @@ definitions: * DOPSIT - UpdateMTOServiceItemSIT * DOASIT - UpdateMTOServiceItemSIT * DOFSIT - UpdateMTOServiceItemSIT + * IDDSIT - UpdateMTOServiceItemSIT + * IOPSIT - UpdateMTOServiceItemSIT + * IOASIT - UpdateMTOServiceItemSIT + * IOFSIT - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle * IDSHUT - UpdateMTOServiceItemInternationalShuttle @@ -916,6 +924,10 @@ definitions: - DOPSIT # Domestic Origin SIT Pickup - DOASIT # Domestic Origin Add'l Days SIT - DOFSIT # Domestic Origin 1st Day SIT + - IDDSIT # International Destination SIT Delivery + - IOPSIT # International Origin SIT Pickup + - IOASIT # International Origin Add'l Days SIT + - IOFSIT # International Origin 1st Day SIT sitDepartureDate: format: date type: string diff --git a/swagger-def/prime_v3.yaml b/swagger-def/prime_v3.yaml index 23931d3b314..0ffaebeec04 100644 --- a/swagger-def/prime_v3.yaml +++ b/swagger-def/prime_v3.yaml @@ -340,12 +340,16 @@ definitions: $ref: 'definitions/prime/MTOServiceItemBasic.yaml' MTOServiceItemDestSIT: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemDestSIT.yaml' + MTOServiceItemInternationalDestSIT: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalDestSIT.yaml' MTOServiceItemDomesticCrating: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemDomesticCrating.yaml' MTOServiceItemInternationalCrating: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemInternationalCrating.yaml' MTOServiceItemOriginSIT: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemOriginSIT.yaml' + MTOServiceItemInternationalOriginSIT: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalOriginSIT.yaml' MTOServiceItemShuttle: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemShuttle.yaml' MTOServiceItemDomesticShuttle: # spectral oas2-unused-definition is OK here due to polymorphism @@ -640,6 +644,10 @@ definitions: * DOPSIT - UpdateMTOServiceItemSIT * DOASIT - UpdateMTOServiceItemSIT * DOFSIT - UpdateMTOServiceItemSIT + * IDDSIT - UpdateMTOServiceItemSIT + * IOPSIT - UpdateMTOServiceItemSIT + * IOASIT - UpdateMTOServiceItemSIT + * IOFSIT - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle * IDSHUT - UpdateMTOServiceItemInternationalShuttle @@ -1003,6 +1011,10 @@ definitions: - DOPSIT # Domestic Origin SIT Pickup - DOASIT # Domestic Origin Add'l Days SIT - DOFSIT # Domestic Origin 1st Day SIT + - IDDSIT # International Destination SIT Delivery + - IOPSIT # International Origin SIT Pickup + - IOASIT # International Origin Add'l Days SIT + - IOFSIT # International Origin 1st Day SIT sitDepartureDate: format: date type: string diff --git a/swagger/admin.yaml b/swagger/admin.yaml index 5082f703079..aec58e45fe5 100644 --- a/swagger/admin.yaml +++ b/swagger/admin.yaml @@ -1054,14 +1054,6 @@ definitions: type: string pattern: ^[A-Z]{4}$ example: JENQ - latitude: - type: number - format: float - example: 29.382973 - longitude: - type: number - format: float - example: -98.62759 createdAt: type: string format: date-time diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index a390367cc33..79b22050f44 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -9715,6 +9715,15 @@ definitions: given SIT service items for an instance of SIT (Either Origin or Destination), grouped by the date they went into SIT and service items limited explicitly to SIT related Re Service Codes. + PPMType: + type: string + title: PPM Type + description: Defines a PPM type + readOnly: true + enum: + - INCENTIVE_BASED + - ACTUAL_EXPENSE + - SMALL_PACKAGE PPMShipmentStatus: description: | Status of the PPM Shipment: @@ -10340,6 +10349,8 @@ definitions: format: uuid type: string readOnly: true + ppmType: + $ref: '#/definitions/PPMType' shipmentId: description: The id of the parent MTOShipment object example: 1f2270c7-7166-40ae-981e-b200ebdf3054 diff --git a/swagger/internal.yaml b/swagger/internal.yaml index a9d9280ea40..9f54214cf34 100644 --- a/swagger/internal.yaml +++ b/swagger/internal.yaml @@ -2967,6 +2967,15 @@ definitions: - id - service_member_id - uploads + PPMType: + type: string + title: PPM Type + description: Defines a PPM type + readOnly: true + enum: + - INCENTIVE_BASED + - ACTUAL_EXPENSE + - SMALL_PACKAGE PPMShipmentStatus: description: | Status of the PPM Shipment: @@ -3598,6 +3607,8 @@ definitions: format: uuid type: string readOnly: true + ppmType: + $ref: '#/definitions/PPMType' shipmentId: description: The id of the parent MTOShipment object example: 1f2270c7-7166-40ae-981e-b200ebdf3054 diff --git a/swagger/prime.yaml b/swagger/prime.yaml index bb6f1579545..8254fec88af 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -956,6 +956,112 @@ paths: Additional DDASIT service items can be created and added to an existing shipment that **includes a DDFSIT service item**. + + + --- + + + **`MTOServiceItemInternationalOriginSIT`** + + + MTOServiceItemInternationalOriginSIT is a subtype of MTOServiceItem. + + + This model type describes a international origin SIT service item. Items + can be created using this + + model type with the following codes: + + + **IOFSIT** + + + **1st day origin SIT service item**. When a IOFSIT is requested, the API + will auto-create the following group of service items: + * IOFSIT - International origin 1st day SIT + * IOASIT - International origin Additional day SIT + * IOPSIT - International origin SIT pickup + * IOSFSC - International origin SIT fuel surcharge + + **IOASIT** + + + **Addt'l days origin SIT service item**. This represents an additional + day of storage for the same item. + + Additional IOASIT service items can be created and added to an existing + shipment that **includes a IOFSIT service item**. + + + --- + + + **`MTOServiceItemInternationalDestSIT`** + + + MTOServiceItemInternationalDestSIT is a subtype of MTOServiceItem. + + + This model type describes a international destination SIT service item. + Items can be created using this + + model type with the following codes: + + + **IDFSIT** + + + **1st day destination SIT service item**. + + + These additional fields are optional for creating a IDFSIT: + * `firstAvailableDeliveryDate1` + * string + * First available date that Prime can deliver SIT service item. + * firstAvailableDeliveryDate1, dateOfContact1, and timeMilitary1 are required together + * `dateOfContact1` + * string + * Date of attempted contact by the prime corresponding to `timeMilitary1` + * dateOfContact1, timeMilitary1, and firstAvailableDeliveryDate1 are required together + * `timeMilitary1` + * string\d{4}Z + * Time of attempted contact corresponding to `dateOfContact1`, in military format. + * timeMilitary1, dateOfContact1, and firstAvailableDeliveryDate1 are required together + * `firstAvailableDeliveryDate2` + * string + * Second available date that Prime can deliver SIT service item. + * firstAvailableDeliveryDate2, dateOfContact2, and timeMilitary2 are required together + * `dateOfContact2` + * string + * Date of attempted contact delivery by the prime corresponding to `timeMilitary2` + * dateOfContact2, timeMilitary2, and firstAvailableDeliveryDate2 are required together + * `timeMilitary2` + * string\d{4}Z + * Time of attempted contact corresponding to `dateOfContact2`, in military format. + * timeMilitary2, dateOfContact2, and firstAvailableDeliveryDate2 are required together + + When a IDFSIT is requested, the API will auto-create the following group + of service items: + * IDFSIT - International destination 1st day SIT + * IDASIT - International destination Additional day SIT + * IDDSIT - International destination SIT delivery + * IDSFSC - International destination SIT fuel surcharge + + **NOTE** When providing the `sitEntryDate` value in the payload, please + ensure that the date is not BEFORE + + `firstAvailableDeliveryDate1` or `firstAvailableDeliveryDate2`. If it + is, you will receive an error response. + + + **IDASIT** + + + **Addt'l days destination SIT service item**. This represents an + additional day of storage for the same item. + + Additional IDASIT service items can be created and added to an existing + shipment that **includes a IDFSIT service item**. operationId: createMTOServiceItem tags: - mtoServiceItem @@ -1059,6 +1165,22 @@ paths: - DOSFSC + - IDASIT + + - IDDSIT + + - IDFSIT + + - IOASIT + + - IOPSIT + + - IOFSIT + + - IDSFSC + + - IOSFSC + The following Accessorial service items can be resubmitted following a rejection: @@ -2382,6 +2504,96 @@ definitions: - reServiceCode - sitEntryDate - reason + MTOServiceItemInternationalDestSIT: + description: >- + Describes a international destination SIT service item. Subtype of a + MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IDFSIT + - IDASIT + dateOfContact1: + format: date + type: string + description: >- + Date of attempted contact by the prime corresponding to + `timeMilitary1`. + x-nullable: true + dateOfContact2: + format: date + type: string + description: >- + Date of attempted contact by the prime corresponding to + `timeMilitary2`. + x-nullable: true + timeMilitary1: + type: string + example: 1400Z + description: >- + Time of attempted contact corresponding to `dateOfContact1`, in + military format. + pattern: \d{4}Z + x-nullable: true + timeMilitary2: + type: string + example: 1400Z + description: >- + Time of attempted contact corresponding to `dateOfContact2`, in + military format. + pattern: \d{4}Z + x-nullable: true + firstAvailableDeliveryDate1: + format: date + type: string + description: First available date that Prime can deliver SIT service item. + x-nullable: true + firstAvailableDeliveryDate2: + format: date + type: string + description: Second available date that Prime can deliver SIT service item. + x-nullable: true + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + description: >- + Departure date for SIT. This is the end date of the SIT at either + origin or destination. This is optional as it can be updated using + the UpdateMTOServiceItemSIT modelType at a later date. + x-nullable: true + sitDestinationFinalAddress: + $ref: '#/definitions/Address' + reason: + type: string + description: | + The reason item has been placed in SIT. + x-nullable: true + x-omitempty: false + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: >- + Date when the customer contacted the prime for a delivery out of + SIT. + x-nullable: true + required: + - reServiceCode + - sitEntryDate + - reason MTOServiceItemDomesticCrating: description: >- Describes a domestic crating/uncrating service item subtype of a @@ -2540,6 +2752,64 @@ definitions: - reason - sitPostalCode - sitEntryDate + MTOServiceItemInternationalOriginSIT: + description: >- + Describes a international origin SIT service item. Subtype of a + MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IOFSIT + - IOASIT + reason: + type: string + example: Storage items need to be picked up + description: Explanation of why Prime is picking up SIT item. + sitPostalCode: + type: string + format: zip + example: '90210' + pattern: ^(\d{5}([\-]\d{4})?)$ + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + x-nullable: true + description: >- + Departure date for SIT. This is the end date of the SIT at either + origin or destination. This is optional as it can be updated using + the UpdateMTOServiceItemSIT modelType at a later date. + sitHHGActualOrigin: + $ref: '#/definitions/Address' + sitHHGOriginalOrigin: + $ref: '#/definitions/Address' + requestApprovalsRequestedStatus: + type: boolean + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: >- + Date when the customer contacted the prime for a delivery out of + SIT. + x-nullable: true + required: + - reServiceCode + - reason + - sitPostalCode + - sitEntryDate MTOServiceItemShuttle: description: Describes a shuttle service item. allOf: @@ -2737,6 +3007,8 @@ definitions: This should be populated for the following service items: * DOASIT(Domestic origin Additional day SIT) * DDASIT(Domestic destination Additional day SIT) + * IOASIT(International origin Additional day SIT) + * IDASIT(International destination Additional day SIT) Both take in the following param keys: * `SITPaymentRequestStart` @@ -2785,6 +3057,14 @@ definitions: * DOFSIT - UpdateMTOServiceItemSIT * DOSFSC - UpdateMTOServiceItemSIT * DDSFSC - UpdateMTOServiceItemSIT + * IDDSIT - UpdateMTOServiceItemSIT + * IDFSIT - UpdateMTOServiceItemSIT + * IDASIT - UpdateMTOServiceItemSIT + * IOPSIT - UpdateMTOServiceItemSIT + * IOASIT - UpdateMTOServiceItemSIT + * IOFSIT - UpdateMTOServiceItemSIT + * IOSFSC - UpdateMTOServiceItemSIT + * IDSFSC - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle * PODFSC - UpdateMTOServiceItemInternationalPortFSC @@ -2889,6 +3169,14 @@ definitions: - DOASIT - DOFSIT - DOSFSC + - IDDSIT + - IDASIT + - IDFSIT + - IDSFSC + - IOPSIT + - IOASIT + - IOFSIT + - IOSFSC sitDepartureDate: format: date type: string @@ -3966,6 +4254,8 @@ definitions: corresponding to the service item type. * DOFSIT, DOASIT - MTOServiceItemOriginSIT * DDFSIT, DDASIT - MTOServiceItemDestSIT + * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT + * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT * DOSHUT, DDSHUT - MTOServiceItemShuttle * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -3979,6 +4269,8 @@ definitions: - MTOServiceItemBasic - MTOServiceItemOriginSIT - MTOServiceItemDestSIT + - MTOServiceItemInternationalOriginSIT + - MTOServiceItemInternationalDestSIT - MTOServiceItemShuttle - MTOServiceItemDomesticShuttle - MTOServiceItemInternationalShuttle diff --git a/swagger/prime_v2.yaml b/swagger/prime_v2.yaml index da357c863cd..47c35e53f01 100644 --- a/swagger/prime_v2.yaml +++ b/swagger/prime_v2.yaml @@ -487,6 +487,96 @@ definitions: - reServiceCode - sitEntryDate - reason + MTOServiceItemInternationalDestSIT: + description: >- + Describes a international destination SIT service item. Subtype of a + MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IDFSIT + - IDASIT + dateOfContact1: + format: date + type: string + description: >- + Date of attempted contact by the prime corresponding to + `timeMilitary1`. + x-nullable: true + dateOfContact2: + format: date + type: string + description: >- + Date of attempted contact by the prime corresponding to + `timeMilitary2`. + x-nullable: true + timeMilitary1: + type: string + example: 1400Z + description: >- + Time of attempted contact corresponding to `dateOfContact1`, in + military format. + pattern: \d{4}Z + x-nullable: true + timeMilitary2: + type: string + example: 1400Z + description: >- + Time of attempted contact corresponding to `dateOfContact2`, in + military format. + pattern: \d{4}Z + x-nullable: true + firstAvailableDeliveryDate1: + format: date + type: string + description: First available date that Prime can deliver SIT service item. + x-nullable: true + firstAvailableDeliveryDate2: + format: date + type: string + description: Second available date that Prime can deliver SIT service item. + x-nullable: true + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + description: >- + Departure date for SIT. This is the end date of the SIT at either + origin or destination. This is optional as it can be updated using + the UpdateMTOServiceItemSIT modelType at a later date. + x-nullable: true + sitDestinationFinalAddress: + $ref: '#/definitions/Address' + reason: + type: string + description: | + The reason item has been placed in SIT. + x-nullable: true + x-omitempty: false + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: >- + Date when the customer contacted the prime for a delivery out of + SIT. + x-nullable: true + required: + - reServiceCode + - sitEntryDate + - reason MTOServiceItemDomesticCrating: description: >- Describes a domestic crating/uncrating service item subtype of a @@ -645,6 +735,64 @@ definitions: - reason - sitPostalCode - sitEntryDate + MTOServiceItemInternationalOriginSIT: + description: >- + Describes a international origin SIT service item. Subtype of a + MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IOFSIT + - IOASIT + reason: + type: string + example: Storage items need to be picked up + description: Explanation of why Prime is picking up SIT item. + sitPostalCode: + type: string + format: zip + example: '90210' + pattern: ^(\d{5}([\-]\d{4})?)$ + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + x-nullable: true + description: >- + Departure date for SIT. This is the end date of the SIT at either + origin or destination. This is optional as it can be updated using + the UpdateMTOServiceItemSIT modelType at a later date. + sitHHGActualOrigin: + $ref: '#/definitions/Address' + sitHHGOriginalOrigin: + $ref: '#/definitions/Address' + requestApprovalsRequestedStatus: + type: boolean + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: >- + Date when the customer contacted the prime for a delivery out of + SIT. + x-nullable: true + required: + - reServiceCode + - reason + - sitPostalCode + - sitEntryDate MTOServiceItemShuttle: description: Describes a shuttle service item. allOf: @@ -1061,6 +1209,10 @@ definitions: * DOPSIT - UpdateMTOServiceItemSIT * DOASIT - UpdateMTOServiceItemSIT * DOFSIT - UpdateMTOServiceItemSIT + * IDDSIT - UpdateMTOServiceItemSIT + * IOPSIT - UpdateMTOServiceItemSIT + * IOASIT - UpdateMTOServiceItemSIT + * IOFSIT - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle * IDSHUT - UpdateMTOServiceItemInternationalShuttle @@ -1429,6 +1581,10 @@ definitions: - DOPSIT - DOASIT - DOFSIT + - IDDSIT + - IOPSIT + - IOASIT + - IOFSIT sitDepartureDate: format: date type: string @@ -2221,6 +2377,8 @@ definitions: corresponding to the service item type. * DOFSIT, DOASIT - MTOServiceItemOriginSIT * DDFSIT, DDASIT - MTOServiceItemDestSIT + * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT + * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT * DOSHUT, DDSHUT - MTOServiceItemShuttle * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -2234,6 +2392,8 @@ definitions: - MTOServiceItemBasic - MTOServiceItemOriginSIT - MTOServiceItemDestSIT + - MTOServiceItemInternationalOriginSIT + - MTOServiceItemInternationalDestSIT - MTOServiceItemShuttle - MTOServiceItemDomesticShuttle - MTOServiceItemInternationalShuttle diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index 181d35913bc..ae85dbaa9a2 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -464,6 +464,96 @@ definitions: - reServiceCode - sitEntryDate - reason + MTOServiceItemInternationalDestSIT: + description: >- + Describes a international destination SIT service item. Subtype of a + MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IDFSIT + - IDASIT + dateOfContact1: + format: date + type: string + description: >- + Date of attempted contact by the prime corresponding to + `timeMilitary1`. + x-nullable: true + dateOfContact2: + format: date + type: string + description: >- + Date of attempted contact by the prime corresponding to + `timeMilitary2`. + x-nullable: true + timeMilitary1: + type: string + example: 1400Z + description: >- + Time of attempted contact corresponding to `dateOfContact1`, in + military format. + pattern: \d{4}Z + x-nullable: true + timeMilitary2: + type: string + example: 1400Z + description: >- + Time of attempted contact corresponding to `dateOfContact2`, in + military format. + pattern: \d{4}Z + x-nullable: true + firstAvailableDeliveryDate1: + format: date + type: string + description: First available date that Prime can deliver SIT service item. + x-nullable: true + firstAvailableDeliveryDate2: + format: date + type: string + description: Second available date that Prime can deliver SIT service item. + x-nullable: true + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + description: >- + Departure date for SIT. This is the end date of the SIT at either + origin or destination. This is optional as it can be updated using + the UpdateMTOServiceItemSIT modelType at a later date. + x-nullable: true + sitDestinationFinalAddress: + $ref: '#/definitions/Address' + reason: + type: string + description: | + The reason item has been placed in SIT. + x-nullable: true + x-omitempty: false + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: >- + Date when the customer contacted the prime for a delivery out of + SIT. + x-nullable: true + required: + - reServiceCode + - sitEntryDate + - reason MTOServiceItemDomesticCrating: description: >- Describes a domestic crating/uncrating service item subtype of a @@ -622,6 +712,64 @@ definitions: - reason - sitPostalCode - sitEntryDate + MTOServiceItemInternationalOriginSIT: + description: >- + Describes a international origin SIT service item. Subtype of a + MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - IOFSIT + - IOASIT + reason: + type: string + example: Storage items need to be picked up + description: Explanation of why Prime is picking up SIT item. + sitPostalCode: + type: string + format: zip + example: '90210' + pattern: ^(\d{5}([\-]\d{4})?)$ + sitEntryDate: + format: date + type: string + description: Entry date for the SIT + sitDepartureDate: + format: date + type: string + x-nullable: true + description: >- + Departure date for SIT. This is the end date of the SIT at either + origin or destination. This is optional as it can be updated using + the UpdateMTOServiceItemSIT modelType at a later date. + sitHHGActualOrigin: + $ref: '#/definitions/Address' + sitHHGOriginalOrigin: + $ref: '#/definitions/Address' + requestApprovalsRequestedStatus: + type: boolean + sitRequestedDelivery: + format: date + type: string + description: Date when the customer has requested delivery out of SIT. + x-nullable: true + sitCustomerContacted: + format: date + type: string + description: >- + Date when the customer contacted the prime for a delivery out of + SIT. + x-nullable: true + required: + - reServiceCode + - reason + - sitPostalCode + - sitEntryDate MTOServiceItemShuttle: description: Describes a shuttle service item. allOf: @@ -1099,6 +1247,10 @@ definitions: * DOPSIT - UpdateMTOServiceItemSIT * DOASIT - UpdateMTOServiceItemSIT * DOFSIT - UpdateMTOServiceItemSIT + * IDDSIT - UpdateMTOServiceItemSIT + * IOPSIT - UpdateMTOServiceItemSIT + * IOASIT - UpdateMTOServiceItemSIT + * IOFSIT - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle * IDSHUT - UpdateMTOServiceItemInternationalShuttle @@ -1536,6 +1688,10 @@ definitions: - DOPSIT - DOASIT - DOFSIT + - IDDSIT + - IOPSIT + - IOASIT + - IOFSIT sitDepartureDate: format: date type: string @@ -2328,6 +2484,8 @@ definitions: corresponding to the service item type. * DOFSIT, DOASIT - MTOServiceItemOriginSIT * DDFSIT, DDASIT - MTOServiceItemDestSIT + * IOFSIT, IOASIT - MTOServiceItemInternationalOriginSIT + * IDFSIT, IDASIT - MTOServiceItemInternationalDestSIT * DOSHUT, DDSHUT - MTOServiceItemShuttle * DOSHUT, DDSHUT - MTOServiceItemDomesticShuttle * IOSHUT, IDSHUT - MTOServiceItemInternationalShuttle @@ -2341,6 +2499,8 @@ definitions: - MTOServiceItemBasic - MTOServiceItemOriginSIT - MTOServiceItemDestSIT + - MTOServiceItemInternationalOriginSIT + - MTOServiceItemInternationalDestSIT - MTOServiceItemShuttle - MTOServiceItemDomesticShuttle - MTOServiceItemInternationalShuttle diff --git a/yarn.lock b/yarn.lock index 73d8f770215..aa021b035ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16371,9 +16371,9 @@ stop-iteration-iterator@^1.0.0: internal-slot "^1.0.4" store2@^2.14.2: - version "2.14.2" - resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" - integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== + version "2.14.4" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.4.tgz#81b313abaddade4dcd7570c5cc0e3264a8f7a242" + integrity sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw== storybook@^7.6.20: version "7.6.20"