From 677299fd12cd7eec72b0cef7d18753524de65148 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Fri, 27 Dec 2024 22:54:26 +0000 Subject: [PATCH 01/35] B-22133 show edit button for port fsc service items --- src/constants/serviceItems.js | 6 ++- .../PrimeUI/MoveTaskOrder/MoveDetails.jsx | 4 +- .../MoveTaskOrder/MoveDetails.test.jsx | 48 ++++++++++++++++++- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/constants/serviceItems.js b/src/constants/serviceItems.js index 7a1a0f76502..cb8e35c95bf 100644 --- a/src/constants/serviceItems.js +++ b/src/constants/serviceItems.js @@ -165,7 +165,7 @@ const SERVICE_ITEMS_ALLOWED_WEIGHT_BILLED_PARAM = [ SERVICE_ITEM_CODES.FSC, ]; -const SIT_SERVICE_ITEMS_ALLOWED_UPDATE = [ +const SERVICE_ITEMS_ALLOWED_UPDATE = [ SERVICE_ITEM_CODES.DDDSIT, SERVICE_ITEM_CODES.DDASIT, SERVICE_ITEM_CODES.DOASIT, @@ -174,6 +174,8 @@ const SIT_SERVICE_ITEMS_ALLOWED_UPDATE = [ SERVICE_ITEM_CODES.DDFSIT, SERVICE_ITEM_CODES.DOSFSC, SERVICE_ITEM_CODES.DDSFSC, + SERVICE_ITEM_CODES.PODFSC, + SERVICE_ITEM_CODES.POEFSC, ]; /** @@ -228,5 +230,5 @@ export { allowedServiceItemCalculations, SERVICE_ITEM_STATUSES, SERVICE_ITEMS_ALLOWED_WEIGHT_BILLED_PARAM, - SIT_SERVICE_ITEMS_ALLOWED_UPDATE, + SERVICE_ITEMS_ALLOWED_UPDATE, }; diff --git a/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx b/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx index 92f5ec9bd55..45881d58602 100644 --- a/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx +++ b/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx @@ -21,7 +21,7 @@ import { usePrimeSimulatorGetMove } from 'hooks/queries'; import { completeCounseling, deleteShipment, downloadMoveOrder } from 'services/primeApi'; import { setFlashMessage as setFlashMessageAction } from 'store/flash/actions'; import scrollToTop from 'shared/scrollToTop'; -import { SIT_SERVICE_ITEMS_ALLOWED_UPDATE } from 'constants/serviceItems'; +import { SERVICE_ITEMS_ALLOWED_UPDATE } from 'constants/serviceItems'; import { MoveOrderDocumentType } from 'shared/constants'; import { CHECK_SPECIAL_ORDERS_TYPES, SPECIAL_ORDERS_TYPES } from 'constants/orders'; @@ -257,7 +257,7 @@ const MoveDetails = ({ setFlashMessage }) => { {serviceItem.reServiceCode} - {serviceItem.reServiceName}
- {SIT_SERVICE_ITEMS_ALLOWED_UPDATE.includes(serviceItem.reServiceCode) ? ( + {SERVICE_ITEMS_ALLOWED_UPDATE.includes(serviceItem.reServiceCode) ? ( { ); }); - it('shows edit button next to the right destination SIT service items', async () => { + it('shows edit button next to the right service items', async () => { usePrimeSimulatorGetMove.mockReturnValue(moveReturnValue); renderWithProviders(); // Check for Edit buttons const editButtons = screen.getAllByRole('link', { name: 'Edit' }); - expect(editButtons).toHaveLength(3); + expect(editButtons).toHaveLength(5); }); }); }); From 59c681a624b007e856e19f26701e2f0a99d39765 Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Wed, 27 Nov 2024 13:20:08 -0500 Subject: [PATCH 02/35] setup move level for ub excess weight risk tracking --- migrations/app/migrations_manifest.txt | 1 + ...dd_excess_ub_weight_columns_to_move.up.sql | 8 ++ pkg/models/move.go | 100 +++++++++--------- 3 files changed, 60 insertions(+), 49 deletions(-) create mode 100644 migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index eb24094411c..251622a552e 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1046,6 +1046,7 @@ 20241122155416_total_dependents_calculation.up.sql 20241122220314_create_port_and_port_location_test_data.up.sql 20241126222026_add_sort_column_to_re_service_items.up.sql +20241127125545_add_excess_ub_weight_columns_to_move.up.sql 20241127133504_add_indexes_speed_up_counseling_offices.up.sql 20241202163059_create_test_sequence_dev_env.up.sql 20241203024453_add_ppm_max_incentive_column.up.sql diff --git a/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql b/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql new file mode 100644 index 00000000000..bc1cbec6dee --- /dev/null +++ b/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql @@ -0,0 +1,8 @@ +-- enable tracking of the timestamp a move with ub shipments are at risk of excess, as well as +-- the timestamp of when an office user dismisses the notification + +ALTER TABLE moves ADD COLUMN IF NOT EXISTS excess_unaccompanied_baggage_weight_qualified_at timestamp with time zone; +ALTER TABLE moves ADD COLUMN IF NOT EXISTS excess_unaccompanied_baggage_weight_acknowledged_at timestamp with time zone; + +COMMENT ON COLUMN mto_shipments.excess_unaccompanied_baggage_weight_qualified_at IS "The date and time the sum of all the move's unaccompanied baggage shipment weights met or exceeded the excess unaccompanied baggage weight qualification threshold."; +COMMENT ON COLUMN mto_shipments.excess_unaccompanied_baggage_weight_acknowledged_at IS 'The date and time the TOO dismissed the risk of excess unaccompanied baggage weight alert.'; diff --git a/pkg/models/move.go b/pkg/models/move.go index 23c1dd7c479..749197636ea 100644 --- a/pkg/models/move.go +++ b/pkg/models/move.go @@ -52,55 +52,57 @@ var locatorLetters = []rune("346789BCDFGHJKMPQRTVWXY") // Move is an object representing a move task order which falls under an "Order" assigned to a service member type Move struct { - ID uuid.UUID `json:"id" db:"id"` - Locator string `json:"locator" db:"locator"` - CreatedAt time.Time `json:"created_at" db:"created_at"` - UpdatedAt time.Time `json:"updated_at" db:"updated_at"` - SubmittedAt *time.Time `json:"submitted_at" db:"submitted_at"` - OrdersID uuid.UUID `json:"orders_id" db:"orders_id"` - Orders Order `belongs_to:"orders" fk_id:"orders_id"` - Status MoveStatus `json:"status" db:"status"` - SignedCertifications SignedCertifications `has_many:"signed_certifications" fk_id:"move_id" order_by:"created_at desc"` - CancelReason *string `json:"cancel_reason" db:"cancel_reason"` - Show *bool `json:"show" db:"show"` - TIORemarks *string `db:"tio_remarks"` - AvailableToPrimeAt *time.Time `db:"available_to_prime_at"` - ApprovedAt *time.Time `db:"approved_at"` - ContractorID *uuid.UUID `db:"contractor_id"` - Contractor *Contractor `belongs_to:"contractors" fk_id:"contractor_id"` - PPMType *string `db:"ppm_type"` - MTOServiceItems MTOServiceItems `has_many:"mto_service_items" fk_id:"move_id"` - PaymentRequests PaymentRequests `has_many:"payment_requests" fk_id:"move_id"` - MTOShipments MTOShipments `has_many:"mto_shipments" fk_id:"move_id"` - ReferenceID *string `db:"reference_id"` - ServiceCounselingCompletedAt *time.Time `db:"service_counseling_completed_at"` - PrimeCounselingCompletedAt *time.Time `db:"prime_counseling_completed_at"` - ExcessWeightQualifiedAt *time.Time `db:"excess_weight_qualified_at"` - ExcessWeightUploadID *uuid.UUID `db:"excess_weight_upload_id"` - ExcessWeightUpload *Upload `belongs_to:"uploads" fk_id:"excess_weight_upload_id"` - ExcessWeightAcknowledgedAt *time.Time `db:"excess_weight_acknowledged_at"` - BillableWeightsReviewedAt *time.Time `db:"billable_weights_reviewed_at"` - FinancialReviewFlag bool `db:"financial_review_flag"` - FinancialReviewFlagSetAt *time.Time `db:"financial_review_flag_set_at"` - FinancialReviewRemarks *string `db:"financial_review_remarks"` - ShipmentGBLOC MoveToGBLOCs `has_many:"move_to_gbloc" fk_id:"move_id"` - CloseoutOfficeID *uuid.UUID `db:"closeout_office_id"` - CloseoutOffice *TransportationOffice `belongs_to:"transportation_offices" fk_id:"closeout_office_id"` - ApprovalsRequestedAt *time.Time `db:"approvals_requested_at"` - ShipmentSeqNum *int `db:"shipment_seq_num"` - LockedByOfficeUserID *uuid.UUID `json:"locked_by" db:"locked_by"` - LockedByOfficeUser *OfficeUser `belongs_to:"office_users" fk_id:"locked_by"` - LockExpiresAt *time.Time `json:"lock_expires_at" db:"lock_expires_at"` - AdditionalDocumentsID *uuid.UUID `json:"additional_documents_id" db:"additional_documents_id"` - AdditionalDocuments *Document `belongs_to:"documents" fk_id:"additional_documents_id"` - SCAssignedID *uuid.UUID `json:"sc_assigned_id" db:"sc_assigned_id"` - SCAssignedUser *OfficeUser `belongs_to:"office_users" fk_id:"sc_assigned_id"` - TOOAssignedID *uuid.UUID `json:"too_assigned_id" db:"too_assigned_id"` - TOOAssignedUser *OfficeUser `belongs_to:"office_users" fk_id:"too_assigned_id"` - TIOAssignedID *uuid.UUID `json:"tio_assigned_id" db:"tio_assigned_id"` - TIOAssignedUser *OfficeUser `belongs_to:"office_users" fk_id:"tio_assigned_id"` - CounselingOfficeID *uuid.UUID `json:"counseling_transportation_office_id" db:"counseling_transportation_office_id"` - CounselingOffice *TransportationOffice `belongs_to:"transportation_offices" fk_id:"counseling_transportation_office_id"` + ID uuid.UUID `json:"id" db:"id"` + Locator string `json:"locator" db:"locator"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + UpdatedAt time.Time `json:"updated_at" db:"updated_at"` + SubmittedAt *time.Time `json:"submitted_at" db:"submitted_at"` + OrdersID uuid.UUID `json:"orders_id" db:"orders_id"` + Orders Order `belongs_to:"orders" fk_id:"orders_id"` + Status MoveStatus `json:"status" db:"status"` + SignedCertifications SignedCertifications `has_many:"signed_certifications" fk_id:"move_id" order_by:"created_at desc"` + CancelReason *string `json:"cancel_reason" db:"cancel_reason"` + Show *bool `json:"show" db:"show"` + TIORemarks *string `db:"tio_remarks"` + AvailableToPrimeAt *time.Time `db:"available_to_prime_at"` + ApprovedAt *time.Time `db:"approved_at"` + ContractorID *uuid.UUID `db:"contractor_id"` + Contractor *Contractor `belongs_to:"contractors" fk_id:"contractor_id"` + PPMType *string `db:"ppm_type"` + MTOServiceItems MTOServiceItems `has_many:"mto_service_items" fk_id:"move_id"` + PaymentRequests PaymentRequests `has_many:"payment_requests" fk_id:"move_id"` + MTOShipments MTOShipments `has_many:"mto_shipments" fk_id:"move_id"` + ReferenceID *string `db:"reference_id"` + ServiceCounselingCompletedAt *time.Time `db:"service_counseling_completed_at"` + PrimeCounselingCompletedAt *time.Time `db:"prime_counseling_completed_at"` + ExcessUnaccompaniedBaggageWeightQualifiedAt *time.Time `db:"excess_unaccompanied_baggage_weight_qualified_at"` // UB specific excess tracking + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *time.Time `db:"excess_unaccompanied_baggage_weight_acknowledged_at"` + ExcessWeightQualifiedAt *time.Time `db:"excess_weight_qualified_at"` // Overall excess weight tracking (Includes UB in the sum if it violates excess) + ExcessWeightUploadID *uuid.UUID `db:"excess_weight_upload_id"` + ExcessWeightUpload *Upload `belongs_to:"uploads" fk_id:"excess_weight_upload_id"` + ExcessWeightAcknowledgedAt *time.Time `db:"excess_weight_acknowledged_at"` + BillableWeightsReviewedAt *time.Time `db:"billable_weights_reviewed_at"` + FinancialReviewFlag bool `db:"financial_review_flag"` + FinancialReviewFlagSetAt *time.Time `db:"financial_review_flag_set_at"` + FinancialReviewRemarks *string `db:"financial_review_remarks"` + ShipmentGBLOC MoveToGBLOCs `has_many:"move_to_gbloc" fk_id:"move_id"` + CloseoutOfficeID *uuid.UUID `db:"closeout_office_id"` + CloseoutOffice *TransportationOffice `belongs_to:"transportation_offices" fk_id:"closeout_office_id"` + ApprovalsRequestedAt *time.Time `db:"approvals_requested_at"` + ShipmentSeqNum *int `db:"shipment_seq_num"` + LockedByOfficeUserID *uuid.UUID `json:"locked_by" db:"locked_by"` + LockedByOfficeUser *OfficeUser `belongs_to:"office_users" fk_id:"locked_by"` + LockExpiresAt *time.Time `json:"lock_expires_at" db:"lock_expires_at"` + AdditionalDocumentsID *uuid.UUID `json:"additional_documents_id" db:"additional_documents_id"` + AdditionalDocuments *Document `belongs_to:"documents" fk_id:"additional_documents_id"` + SCAssignedID *uuid.UUID `json:"sc_assigned_id" db:"sc_assigned_id"` + SCAssignedUser *OfficeUser `belongs_to:"office_users" fk_id:"sc_assigned_id"` + TOOAssignedID *uuid.UUID `json:"too_assigned_id" db:"too_assigned_id"` + TOOAssignedUser *OfficeUser `belongs_to:"office_users" fk_id:"too_assigned_id"` + TIOAssignedID *uuid.UUID `json:"tio_assigned_id" db:"tio_assigned_id"` + TIOAssignedUser *OfficeUser `belongs_to:"office_users" fk_id:"tio_assigned_id"` + CounselingOfficeID *uuid.UUID `json:"counseling_transportation_office_id" db:"counseling_transportation_office_id"` + CounselingOffice *TransportationOffice `belongs_to:"transportation_offices" fk_id:"counseling_transportation_office_id"` } // TableName overrides the table name used by Pop. From 1510ee9805657d9404914f79c94a51bcc82bc27c Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Wed, 27 Nov 2024 19:47:01 +0000 Subject: [PATCH 03/35] fix migration --- ...20241127125545_add_excess_ub_weight_columns_to_move.up.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql b/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql index bc1cbec6dee..e88fbe69325 100644 --- a/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql +++ b/migrations/app/schema/20241127125545_add_excess_ub_weight_columns_to_move.up.sql @@ -4,5 +4,5 @@ ALTER TABLE moves ADD COLUMN IF NOT EXISTS excess_unaccompanied_baggage_weight_qualified_at timestamp with time zone; ALTER TABLE moves ADD COLUMN IF NOT EXISTS excess_unaccompanied_baggage_weight_acknowledged_at timestamp with time zone; -COMMENT ON COLUMN mto_shipments.excess_unaccompanied_baggage_weight_qualified_at IS "The date and time the sum of all the move's unaccompanied baggage shipment weights met or exceeded the excess unaccompanied baggage weight qualification threshold."; -COMMENT ON COLUMN mto_shipments.excess_unaccompanied_baggage_weight_acknowledged_at IS 'The date and time the TOO dismissed the risk of excess unaccompanied baggage weight alert.'; +COMMENT ON COLUMN moves.excess_unaccompanied_baggage_weight_qualified_at IS 'The date and time the sum of all the move''s unaccompanied baggage shipment weights met or exceeded the excess unaccompanied baggage weight qualification threshold.'; +COMMENT ON COLUMN moves.excess_unaccompanied_baggage_weight_acknowledged_at IS 'The date and time the TOO dismissed the risk of excess unaccompanied baggage weight alert.'; From 461dc3b9d6f4ddfc6a6fc7d298b6392bb1962e8b Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Wed, 27 Nov 2024 20:09:03 +0000 Subject: [PATCH 04/35] excess weight calculation refactor --- pkg/services/move/move_weights.go | 142 +++++++++++++++++++++--------- 1 file changed, 102 insertions(+), 40 deletions(-) diff --git a/pkg/services/move/move_weights.go b/pkg/services/move/move_weights.go index cf75d604652..c68cbb14fa1 100644 --- a/pkg/services/move/move_weights.go +++ b/pkg/services/move/move_weights.go @@ -98,53 +98,42 @@ func (w moveWeights) CheckExcessWeight(appCtx appcontext.AppContext, moveID uuid return nil, nil, errors.New("could not determine excess weight entitlement without dependents authorization value") } + var isHHGAtRiskOfExcessWeight bool + var isUBAtRiskOfExcessWeight bool + totalWeightAllowance := models.GetWeightAllotment(*move.Orders.Grade, move.Orders.OrdersType) - weight := totalWeightAllowance.TotalWeightSelf + overallWeightAllowance := totalWeightAllowance.TotalWeightSelf if *move.Orders.Entitlement.DependentsAuthorized { - weight = totalWeightAllowance.TotalWeightSelfPlusDependents + overallWeightAllowance = totalWeightAllowance.TotalWeightSelfPlusDependents } + ubWeightAllowance := totalWeightAllowance.UnaccompaniedBaggageAllowance - // the shipment being updated/created potentially has not yet been saved in the database so use the weight in the - // incoming payload that will be saved after - estimatedWeightTotal := 0 - if updatedShipment.Status == models.MTOShipmentStatusApproved { - if updatedShipment.PrimeEstimatedWeight != nil { - estimatedWeightTotal += updatedShipment.PrimeEstimatedWeight.Int() - } - if updatedShipment.PPMShipment != nil && updatedShipment.PPMShipment.EstimatedWeight != nil { - estimatedWeightTotal += updatedShipment.PPMShipment.EstimatedWeight.Int() - } - } + sumOfWeights := calculateSumOfWeights(move, &updatedShipment) + now := time.Now() // Prepare a shared time for risk excess flagging - for _, shipment := range move.MTOShipments { - // We should avoid counting shipments that haven't been approved yet and will need to account for diversions - // and cancellations factoring into the estimated weight total. - if shipment.Status == models.MTOShipmentStatusApproved && shipment.PrimeEstimatedWeight != nil { - if shipment.ID != updatedShipment.ID { - if shipment.PrimeEstimatedWeight != nil { - estimatedWeightTotal += shipment.PrimeEstimatedWeight.Int() - } - if shipment.PPMShipment != nil && shipment.PPMShipment.EstimatedWeight != nil { - estimatedWeightTotal += shipment.PPMShipment.EstimatedWeight.Int() - } - } - } - } - - // may need to take into account floating point precision here but should be dealing with whole numbers - if int(float32(weight)*RiskOfExcessThreshold) <= estimatedWeightTotal { - excessWeightQualifiedAt := time.Now() + // Check for risk of excess of the total move allowance (HHG and PPM) + if int(float32(overallWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfMove { + isHHGAtRiskOfExcessWeight = true + excessWeightQualifiedAt := now move.ExcessWeightQualifiedAt = &excessWeightQualifiedAt - - verrs, err := validateAndSave(appCtx, &move) - if (verrs != nil && verrs.HasAny()) || err != nil { - return nil, verrs, err - } } else if move.ExcessWeightQualifiedAt != nil { - // the move had previously qualified for excess weight but does not any longer so reset the value + // Reset qualified at move.ExcessWeightQualifiedAt = nil + } + // Check for risk of excess of UB allowance + if (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfUbShipments) || (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumActualWeightOfUbShipments) { + isUBAtRiskOfExcessWeight = true + excessUbWeightQualifiedAt := now + move.ExcessUnaccompaniedBaggageWeightQualifiedAt = &excessUbWeightQualifiedAt + } else if move.ExcessUnaccompaniedBaggageWeightQualifiedAt != nil { + // Reset qualified at + move.ExcessUnaccompaniedBaggageWeightQualifiedAt = nil + } + + if isHHGAtRiskOfExcessWeight || isUBAtRiskOfExcessWeight { + // Save risk excess flags verrs, err := validateAndSave(appCtx, &move) if (verrs != nil && verrs.HasAny()) || err != nil { return nil, verrs, err @@ -154,6 +143,79 @@ func (w moveWeights) CheckExcessWeight(appCtx appcontext.AppContext, moveID uuid return &move, nil, nil } +type SumOfWeights struct { + SumEstimatedWeightOfMove int + SumEstimatedWeightOfUbShipments int + SumActualWeightOfUbShipments int +} + +func sumWeightsFromShipment(shipment models.MTOShipment) SumOfWeights { + var sumEstimatedWeightOfMove int + var sumEstimatedWeightOfUbShipments int + var sumActualWeightOfUbShipments int + + if shipment.Status != models.MTOShipmentStatusApproved { + return SumOfWeights{} + } + + // Sum the prime estimated weights + if shipment.PrimeEstimatedWeight != nil { + primeEstimatedWeightInt := shipment.PrimeEstimatedWeight.Int() + sumEstimatedWeightOfMove += primeEstimatedWeightInt + if shipment.ShipmentType == models.MTOShipmentTypeUnaccompaniedBaggage { + // Sum the UB estimated weight separately + sumEstimatedWeightOfUbShipments += primeEstimatedWeightInt + } + } + + if shipment.PPMShipment != nil && shipment.PPMShipment.EstimatedWeight != nil { + // Sum the PPM estimated weight into the overall sum + sumEstimatedWeightOfMove += shipment.PPMShipment.EstimatedWeight.Int() + } + + if shipment.PrimeActualWeight != nil && shipment.ShipmentType == models.MTOShipmentTypeUnaccompaniedBaggage { + // Sum the actual weight of UB, we don't sum the actual weight of HHG or PPM at this time for determining if a move is at risk of excess + sumActualWeightOfUbShipments += shipment.PrimeActualWeight.Int() + } + + return SumOfWeights{ + SumEstimatedWeightOfMove: sumEstimatedWeightOfMove, + SumEstimatedWeightOfUbShipments: sumEstimatedWeightOfUbShipments, + SumActualWeightOfUbShipments: sumActualWeightOfUbShipments, + } +} + +// Calculates the sum of weights for a move, including an optional updated shipment that may not be persisted to the database yet +// If updatedShipment is nil, it calculates sums for the move as is +// If updatedShipment is provided, it excludes it from the existing shipments and adds its weights separately since we don't want to include it +// +// in the normal sum (Since the normal sum won't accurately reflect the not-saved shipment being updated) +func calculateSumOfWeights(move models.Move, updatedShipment *models.MTOShipment) SumOfWeights { + sumOfWeights := SumOfWeights{} + + // Sum weights from existing shipments + for _, shipment := range move.MTOShipments { + if updatedShipment != nil && shipment.ID == updatedShipment.ID { + // Skip shipments that are not approved + continue + } + shipmentWeights := sumWeightsFromShipment(shipment) + sumOfWeights.SumEstimatedWeightOfMove += shipmentWeights.SumEstimatedWeightOfMove + sumOfWeights.SumEstimatedWeightOfUbShipments += shipmentWeights.SumEstimatedWeightOfUbShipments + sumOfWeights.SumActualWeightOfUbShipments += shipmentWeights.SumActualWeightOfUbShipments + } + + // Sum weights from the updated shipment + if updatedShipment != nil { + updatedWeights := sumWeightsFromShipment(*updatedShipment) + sumOfWeights.SumEstimatedWeightOfMove += updatedWeights.SumEstimatedWeightOfMove + sumOfWeights.SumEstimatedWeightOfUbShipments += updatedWeights.SumEstimatedWeightOfUbShipments + sumOfWeights.SumActualWeightOfUbShipments += updatedWeights.SumActualWeightOfUbShipments + } + + return sumOfWeights +} + func (w moveWeights) CheckAutoReweigh(appCtx appcontext.AppContext, moveID uuid.UUID, updatedShipment *models.MTOShipment) (models.MTOShipments, error) { db := appCtx.DB() var move models.Move @@ -177,9 +239,9 @@ func (w moveWeights) CheckAutoReweigh(appCtx appcontext.AppContext, moveID uuid. totalWeightAllowance := models.GetWeightAllotment(*move.Orders.Grade, move.Orders.OrdersType) - weight := totalWeightAllowance.TotalWeightSelf + overallWeightAllowance := totalWeightAllowance.TotalWeightSelf if *move.Orders.Entitlement.DependentsAuthorized { - weight = totalWeightAllowance.TotalWeightSelfPlusDependents + overallWeightAllowance = totalWeightAllowance.TotalWeightSelfPlusDependents } moveWeightTotal := 0 @@ -199,7 +261,7 @@ func (w moveWeights) CheckAutoReweigh(appCtx appcontext.AppContext, moveID uuid. autoReweighShipments := models.MTOShipments{} // may need to take into account floating point precision here but should be dealing with whole numbers - if int(float32(weight)*AutoReweighRequestThreshold) <= moveWeightTotal { + if int(float32(overallWeightAllowance)*AutoReweighRequestThreshold) <= moveWeightTotal { for _, shipment := range move.MTOShipments { // We should avoid counting shipments that haven't been approved yet and will need to account for diversions // and cancellations factoring into the weight total. From b7185db56e6d8aba92b4973a1eb2b173d817b343 Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Fri, 29 Nov 2024 15:42:18 +0000 Subject: [PATCH 05/35] excess weight calculate refactor and tests --- pkg/services/move/move_weights.go | 40 ++++-- pkg/services/move/move_weights_test.go | 173 +++++++++++++++++++++---- 2 files changed, 174 insertions(+), 39 deletions(-) diff --git a/pkg/services/move/move_weights.go b/pkg/services/move/move_weights.go index c68cbb14fa1..92e10d4047f 100644 --- a/pkg/services/move/move_weights.go +++ b/pkg/services/move/move_weights.go @@ -80,7 +80,7 @@ func lowerShipmentWeight(shipment models.MTOShipment) int { func (w moveWeights) CheckExcessWeight(appCtx appcontext.AppContext, moveID uuid.UUID, updatedShipment models.MTOShipment) (*models.Move, *validate.Errors, error) { db := appCtx.DB() var move models.Move - err := db.EagerPreload("MTOShipments", "Orders.Entitlement").Find(&move, moveID) + err := db.EagerPreload("MTOShipments", "Orders.Entitlement", "Orders.OriginDutyLocation.Address", "Orders.NewDutyLocation.Address", "Orders.ServiceMember").Find(&move, moveID) if err != nil { switch err { case sql.ErrNoRows: @@ -98,49 +98,63 @@ func (w moveWeights) CheckExcessWeight(appCtx appcontext.AppContext, moveID uuid return nil, nil, errors.New("could not determine excess weight entitlement without dependents authorization value") } - var isHHGAtRiskOfExcessWeight bool - var isUBAtRiskOfExcessWeight bool - totalWeightAllowance := models.GetWeightAllotment(*move.Orders.Grade, move.Orders.OrdersType) overallWeightAllowance := totalWeightAllowance.TotalWeightSelf if *move.Orders.Entitlement.DependentsAuthorized { overallWeightAllowance = totalWeightAllowance.TotalWeightSelfPlusDependents } - ubWeightAllowance := totalWeightAllowance.UnaccompaniedBaggageAllowance - + ubWeightAllowance, err := models.GetUBWeightAllowance(appCtx, move.Orders.OriginDutyLocation.Address.IsOconus, move.Orders.NewDutyLocation.Address.IsOconus, move.Orders.ServiceMember.Affiliation, move.Orders.Grade, &move.Orders.OrdersType, move.Orders.Entitlement.DependentsAuthorized, move.Orders.Entitlement.AccompaniedTour, move.Orders.Entitlement.DependentsUnderTwelve, move.Orders.Entitlement.DependentsTwelveAndOver) + if err != nil { + return nil, nil, err + } sumOfWeights := calculateSumOfWeights(move, &updatedShipment) + verrs, err := saveMoveExcessWeightValues(appCtx, &move, overallWeightAllowance, ubWeightAllowance, sumOfWeights) + if (verrs != nil && verrs.HasAny()) || err != nil { + return nil, verrs, err + } + return &move, nil, nil +} + +// Handle move excess weight values by updating +// the move in place. This handles setting when the move qualified +// for risk of excess weight as well as resetting it if the weight has been +// updated to a new weight not at risk of excess +func saveMoveExcessWeightValues(appCtx appcontext.AppContext, move *models.Move, overallWeightAllowance int, ubWeightAllowance int, sumOfWeights SumOfWeights) (*validate.Errors, error) { now := time.Now() // Prepare a shared time for risk excess flagging + var isTheMoveBeingUpdated bool + // Check for risk of excess of the total move allowance (HHG and PPM) if int(float32(overallWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfMove { - isHHGAtRiskOfExcessWeight = true + isTheMoveBeingUpdated = true excessWeightQualifiedAt := now move.ExcessWeightQualifiedAt = &excessWeightQualifiedAt } else if move.ExcessWeightQualifiedAt != nil { // Reset qualified at + isTheMoveBeingUpdated = true move.ExcessWeightQualifiedAt = nil } // Check for risk of excess of UB allowance if (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfUbShipments) || (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumActualWeightOfUbShipments) { - isUBAtRiskOfExcessWeight = true + isTheMoveBeingUpdated = true excessUbWeightQualifiedAt := now move.ExcessUnaccompaniedBaggageWeightQualifiedAt = &excessUbWeightQualifiedAt } else if move.ExcessUnaccompaniedBaggageWeightQualifiedAt != nil { // Reset qualified at + isTheMoveBeingUpdated = true move.ExcessUnaccompaniedBaggageWeightQualifiedAt = nil } - if isHHGAtRiskOfExcessWeight || isUBAtRiskOfExcessWeight { + if isTheMoveBeingUpdated { // Save risk excess flags - verrs, err := validateAndSave(appCtx, &move) + verrs, err := validateAndSave(appCtx, move) if (verrs != nil && verrs.HasAny()) || err != nil { - return nil, verrs, err + return verrs, err } } - - return &move, nil, nil + return nil, nil } type SumOfWeights struct { diff --git a/pkg/services/move/move_weights_test.go b/pkg/services/move/move_weights_test.go index 6ae571c088c..6528830e2e4 100644 --- a/pkg/services/move/move_weights_test.go +++ b/pkg/services/move/move_weights_test.go @@ -22,7 +22,7 @@ func (suite *MoveServiceSuite) TestExcessWeight() { approvedMove := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) now := time.Now() pickupDate := now.AddDate(0, 0, 10) - approvedShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ + approvedHHGShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ { Model: models.MTOShipment{ Status: models.MTOShipmentStatusApproved, @@ -35,28 +35,78 @@ func (suite *MoveServiceSuite) TestExcessWeight() { LinkOnly: true, }, }, nil) + approvedUbShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + ApprovedDate: &now, + ScheduledPickupDate: &pickupDate, + ShipmentType: models.MTOShipmentTypeUnaccompaniedBaggage, + }, + }, + { + Model: approvedMove, + LinkOnly: true, + }, + }, nil) estimatedWeight := unit.Pound(7200) - approvedShipment.PrimeEstimatedWeight = &estimatedWeight - updatedMove, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), approvedMove.ID, approvedShipment) - + approvedHHGShipment.PrimeEstimatedWeight = &estimatedWeight + approvedUbShipment.PrimeEstimatedWeight = &estimatedWeight + _, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), approvedMove.ID, approvedHHGShipment) + suite.Nil(verrs) + suite.NoError(err) + updatedMove, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), approvedMove.ID, approvedUbShipment) suite.Nil(verrs) suite.NoError(err) + // Move has nil excess weight risks before checking for excess weight suite.Nil(approvedMove.ExcessWeightQualifiedAt) + suite.Nil(approvedMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) + // Move has not nil excess weight risks after checking for excess weight suite.NotNil(updatedMove.ExcessWeightQualifiedAt) + suite.NotNil(updatedMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) // refetch the move from the database not just the return value err = suite.DB().Reload(&approvedMove) suite.NoError(err) + // Ensure it saved to db suite.NotNil(approvedMove.ExcessWeightQualifiedAt) + suite.NotNil(approvedMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) }) suite.Run("does not flag move for excess weight when an approved shipment estimated weight is lower than threshold", func() { - approvedMove := factory.BuildAvailableToPrimeMove(suite.DB(), nil, nil) + // Create a move with an oconus duty location so it qualifies for UB allowance + // The allowance based on these params should be 500 ub + oconusAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ + { + Model: models.Address{ + IsOconus: models.BoolPointer(true), + }, + }, + }, nil) + oconusDutyLocation := factory.BuildDutyLocation(suite.DB(), []factory.Customization{ + { + Model: oconusAddress, + LinkOnly: true, + }, + }, nil) + order := factory.BuildOrder(suite.DB(), []factory.Customization{ + { + Model: oconusDutyLocation, + LinkOnly: true, + Type: &factory.DutyLocations.OriginDutyLocation, + }, + }, nil) + move := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: order, + LinkOnly: true, + }}, nil) now := time.Now() pickupDate := now.AddDate(0, 0, 10) - approvedShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ + + approvedHHGShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ { Model: models.MTOShipment{ Status: models.MTOShipmentStatusApproved, @@ -65,24 +115,45 @@ func (suite *MoveServiceSuite) TestExcessWeight() { }, }, { - Model: approvedMove, + Model: move, + LinkOnly: true, + }, + }, nil) + approvedUbShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + ApprovedDate: &now, + ScheduledPickupDate: &pickupDate, + ShipmentType: models.MTOShipmentTypeUnaccompaniedBaggage, + }, + }, + { + Model: move, LinkOnly: true, }, }, nil) - estimatedWeight := unit.Pound(7199) - approvedShipment.PrimeEstimatedWeight = &estimatedWeight - updatedMove, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), approvedMove.ID, approvedShipment) - + estimatedHHGWeight := unit.Pound(7199) + estimatedUBWeight := unit.Pound(250) + approvedHHGShipment.PrimeEstimatedWeight = &estimatedHHGWeight + approvedUbShipment.PrimeEstimatedWeight = &estimatedUBWeight + _, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), move.ID, approvedHHGShipment) + suite.Nil(verrs) + suite.NoError(err) + updatedMove, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), move.ID, approvedUbShipment) suite.Nil(verrs) suite.NoError(err) - suite.Nil(approvedMove.ExcessWeightQualifiedAt) + suite.Nil(move.ExcessWeightQualifiedAt) suite.Nil(updatedMove.ExcessWeightQualifiedAt) + suite.Nil(move.ExcessUnaccompaniedBaggageWeightQualifiedAt) + suite.Nil(updatedMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) - err = suite.DB().Reload(&approvedMove) + err = suite.DB().Reload(&move) suite.NoError(err) - suite.Nil(approvedMove.ExcessWeightQualifiedAt) + suite.Nil(move.ExcessWeightQualifiedAt) + suite.Nil(move.ExcessUnaccompaniedBaggageWeightQualifiedAt) }) suite.Run("qualifies move for excess weight when the sum of approved shipments is updated within threshold", func() { @@ -218,17 +289,46 @@ func (suite *MoveServiceSuite) TestExcessWeight() { suite.Run("removes excess weight qualification when estimated weight drops below previously met threshold", func() { now := time.Now() - approvedMove := factory.BuildAvailableToPrimeMove(suite.DB(), []factory.Customization{ + estimatedUbWeight := unit.Pound(250) + estimatedWeight := unit.Pound(7199 - estimatedUbWeight) + + // Add an OCONUS address so it qualifies for UB allowance + // The allowance based on these params should be 500 ub + oconusAddress := factory.BuildAddress(suite.DB(), []factory.Customization{ { - Model: models.Move{ - ExcessWeightQualifiedAt: &now, + Model: models.Address{ + IsOconus: models.BoolPointer(true), }, }, }, nil) + oconusDutyLocation := factory.BuildDutyLocation(suite.DB(), []factory.Customization{ + { + Model: oconusAddress, + LinkOnly: true, + }, + }, nil) + order := factory.BuildOrder(suite.DB(), []factory.Customization{ + { + Model: oconusDutyLocation, + LinkOnly: true, + Type: &factory.DutyLocations.OriginDutyLocation, + }, + }, nil) + // By default have excess weight turned on, we want to simulate it resetting + initialMove := factory.BuildMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + ExcessWeightQualifiedAt: &now, + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }, + { + Model: order, + LinkOnly: true, + }}, nil) pickupDate := now.AddDate(0, 0, 10) - estimatedWeight := unit.Pound(7200) - approvedShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ + factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ { Model: models.MTOShipment{ Status: models.MTOShipmentStatusApproved, @@ -238,24 +338,45 @@ func (suite *MoveServiceSuite) TestExcessWeight() { }, }, { - Model: approvedMove, + Model: initialMove, + LinkOnly: true, + }, + }, nil) + approvedUbShipment := factory.BuildMTOShipmentMinimal(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + Status: models.MTOShipmentStatusApproved, + ApprovedDate: &now, + ScheduledPickupDate: &pickupDate, + ShipmentType: models.MTOShipmentTypeUnaccompaniedBaggage, + PrimeEstimatedWeight: &estimatedUbWeight, + }, + }, + { + Model: initialMove, LinkOnly: true, }, }, nil) - updatedEstimatedWeight := unit.Pound(7199) - approvedShipment.PrimeEstimatedWeight = &updatedEstimatedWeight - updatedMove, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), approvedMove.ID, approvedShipment) + // We defaulted to excess amounts + suite.NotNil(initialMove.ExcessWeightQualifiedAt) + suite.NotNil(initialMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) + updatedMove, verrs, err := moveWeights.CheckExcessWeight(suite.AppContextForTest(), initialMove.ID, approvedUbShipment) suite.Nil(verrs) suite.NoError(err) - suite.NotNil(approvedMove.ExcessWeightQualifiedAt) + // The shipments we created will not qualify for risk of excess + // This means that after we CheckExcessWeight again, the suite.Nil(updatedMove.ExcessWeightQualifiedAt) + suite.Nil(updatedMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) - err = suite.DB().Reload(&approvedMove) + // Reload our original move that had excess weight qualified at present + // and now make sure it is nil + err = suite.DB().Reload(&initialMove) suite.NoError(err) - suite.Nil(approvedMove.ExcessWeightQualifiedAt) + suite.Nil(initialMove.ExcessWeightQualifiedAt) + suite.Nil(initialMove.ExcessUnaccompaniedBaggageWeightQualifiedAt) }) suite.Run("returns error if orders grade is unset to lookup weight allowance", func() { From 5de680ae93e1e68998e6bd444c41574e4027a650 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 15:13:50 +0000 Subject: [PATCH 06/35] B-22133 adds port fsc prime ui --- pkg/gen/primev3api/embedded_spec.go | 50 ++ pkg/gen/primev3messages/m_t_o_service_item.go | 6 + ...rvice_item_international_fuel_surcharge.go | 575 ++++++++++++++++++ .../primeapiv3/payloads/model_to_payload.go | 13 + ...dateInternationalFuelSurcharge.module.scss | 12 + ...UIUpdateInternationalFuelSurchargeForm.jsx | 102 ++++ ...ateInternationalFuelSurchargeForm.test.jsx | 101 +++ .../PrimeUIUpdateSitServiceItem.jsx | 21 + swagger-def/prime_v3.yaml | 2 + swagger/prime_v3.yaml | 19 + 10 files changed, 901 insertions(+) create mode 100644 pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go create mode 100644 src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss create mode 100644 src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx create mode 100644 src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index bb5a844cfe0..f68a9ea6ebd 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -1636,6 +1636,31 @@ func init() { } ] }, + "MTOServiceItemInternationalFuelSurcharge": { + "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "properties": { + "portCode": { + "description": "A unique code for a Port", + "type": "string" + }, + "reServiceCode": { + "description": "A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC).", + "type": "string", + "enum": [ + "PODFSC", + "POEFSC" + ] + } + } + } + ] + }, "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 * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", @@ -5890,6 +5915,31 @@ func init() { } ] }, + "MTOServiceItemInternationalFuelSurcharge": { + "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "properties": { + "portCode": { + "description": "A unique code for a Port", + "type": "string" + }, + "reServiceCode": { + "description": "A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC).", + "type": "string", + "enum": [ + "PODFSC", + "POEFSC" + ] + } + } + } + ] + }, "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 * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", diff --git a/pkg/gen/primev3messages/m_t_o_service_item.go b/pkg/gen/primev3messages/m_t_o_service_item.go index 9559114c004..d6861255a80 100644 --- a/pkg/gen/primev3messages/m_t_o_service_item.go +++ b/pkg/gen/primev3messages/m_t_o_service_item.go @@ -279,6 +279,12 @@ func unmarshalMTOServiceItem(data []byte, consumer runtime.Consumer) (MTOService 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 "MTOServiceItemOriginSIT": var result MTOServiceItemOriginSIT if err := consumer.Consume(buf2, &result); err != nil { diff --git a/pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go b/pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go new file mode 100644 index 00000000000..73d7c4e4c0b --- /dev/null +++ b/pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go @@ -0,0 +1,575 @@ +// 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" +) + +// MTOServiceItemInternationalFuelSurcharge Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalFuelSurcharge +type MTOServiceItemInternationalFuelSurcharge struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // A unique code for a Port + PortCode string `json:"portCode,omitempty"` + + // A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC). + // Enum: [PODFSC POEFSC] + ReServiceCode string `json:"reServiceCode,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalFuelSurcharge" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalFuelSurcharge) UnmarshalJSON(raw []byte) error { + var data struct { + + // A unique code for a Port + PortCode string `json:"portCode,omitempty"` + + // A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC). + // Enum: [PODFSC POEFSC] + ReServiceCode string `json:"reServiceCode,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 MTOServiceItemInternationalFuelSurcharge + + 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.PortCode = data.PortCode + result.ReServiceCode = data.ReServiceCode + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalFuelSurcharge) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // A unique code for a Port + PortCode string `json:"portCode,omitempty"` + + // A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC). + // Enum: [PODFSC POEFSC] + ReServiceCode string `json:"reServiceCode,omitempty"` + }{ + + PortCode: m.PortCode, + + ReServiceCode: m.ReServiceCode, + }) + 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 fuel surcharge +func (m *MTOServiceItemInternationalFuelSurcharge) 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 len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["PODFSC","POEFSC"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum = append(mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalFuelSurcharge) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) validateReServiceCode(formats strfmt.Registry) error { + + if swag.IsZero(m.ReServiceCode) { // not required + return nil + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international fuel surcharge based on the context it is used +func (m *MTOServiceItemInternationalFuelSurcharge) 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 len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 *MTOServiceItemInternationalFuelSurcharge) 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 +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalFuelSurcharge) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalFuelSurcharge) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalFuelSurcharge + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload.go b/pkg/handlers/primeapiv3/payloads/model_to_payload.go index f4cd6ab2609..d5cfb359355 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload.go @@ -803,6 +803,19 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primev3messages.MTOSe EstimatedWeight: handlers.FmtPoundPtr(mtoServiceItem.EstimatedWeight), ActualWeight: handlers.FmtPoundPtr(mtoServiceItem.ActualWeight), } + + case models.ReServiceCodePODFSC, models.ReServiceCodePOEFSC: + var portCode string + if mtoServiceItem.POELocation != nil { + portCode = mtoServiceItem.POELocation.Port.PortCode + } else if mtoServiceItem.PODLocation != nil { + portCode = mtoServiceItem.PODLocation.Port.PortCode + } + payload = &primev3messages.MTOServiceItemInternationalFuelSurcharge{ + ReServiceCode: string(mtoServiceItem.ReService.Code), + PortCode: portCode, + } + default: // otherwise, basic service item payload = &primev3messages.MTOServiceItemBasic{ diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss new file mode 100644 index 00000000000..985dcabf2b0 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss @@ -0,0 +1,12 @@ +@import 'shared/styles/basics'; +@import 'shared/styles/colors'; + +.IntlFsc { + + .intlFscHeader { + text-align: center; + } + + @include u-margin-bottom(4); + + } diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx new file mode 100644 index 00000000000..5092ae351a6 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -0,0 +1,102 @@ +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 './PrimeUIUpdateInternationalFuelSurcharge.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 { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; + +const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, serviceItem, port }) => { + const { moveCodeOrID } = useParams(); + const navigate = useNavigate(); + + const handleClose = () => { + navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); + }; + + return ( + + {({ handleSubmit }) => ( +
+ +
+

Update International Fuel Surcharge Service Item

+ +
+ Here you can update specific fields for an International Fuel Surcharge service item.
+ At this time, only the following values can be updated:
{' '} + + Port Code
+
+
+
+ +

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

+
+
+
ID:
+
{serviceItem.id}
+
+
+
MTO ID:
+
{serviceItem.moveTaskOrderID}
+
+
+
Shipment ID:
+
{serviceItem.mtoShipmentID}
+
+
+
Status:
+
{serviceItem.status}
+
+
+
Port:
+
{port && port.portName}
+
+
+
Port Location:
+
+ {port && port.city}, {port && port.state} {port && port.zip} +
+
+
+ {serviceItem.status === SERVICE_ITEM_STATUSES.APPROVED && ( + + )} +
+ +
+
+
+ )} +
+ ); +}; + +export default PrimeUIUpdateInternationalFuelSurchargeForm; diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx new file mode 100644 index 00000000000..f87bd27d8cc --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; + +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: 'DOPSIT', +}; + +const serviceItem = { + reServiceCode: 'POEFSC', + reServiceName: 'International POE Fuel Surcharge', +}; + +const port = { + city: 'SEATTLE', + country: 'UNITED STATES', + county: 'KING', + id: '48569958-2889-41e5-8101-82c56ec48430', + portCode: 'SEA', + portName: 'SEATTLE TACOMA INTL', + portType: 'A', + state: 'WASHINGTON', + zip: '98158', +}; + +// 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('PrimeUIUpdateInternationalFuelSurchargeForm', () => { + it('renders the address change request form', async () => { + renderWithProviders( + , + ); + + expect( + screen.getByRole('heading', { name: 'Update International Fuel Surcharge Service Item', level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole('heading', { name: 'POEFSC - International POE Fuel Surcharge', level: 3 }), + ).toBeInTheDocument(); + expect(screen.getByText('Port:')).toBeInTheDocument(); + expect(screen.getByText('SEATTLE TACOMA INTL')).toBeInTheDocument(); + expect(screen.getByText('SEATTLE, WASHINGTON 98158')).toBeInTheDocument(); + 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/PrimeUIUpdateSitServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx index 0a39bc1e6a3..4ff8a1a3651 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx @@ -6,6 +6,7 @@ import { connect } from 'react-redux'; import PrimeUIUpdateOriginSITForm from './PrimeUIUpdateOriginSITForm'; import PrimeUIUpdateDestSITForm from './PrimeUIUpdateDestSITForm'; +import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; import { updateMTOServiceItem } from 'services/primeApi'; import scrollToTop from 'shared/scrollToTop'; @@ -67,7 +68,18 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { if (isError) return ; const serviceItem = moveTaskOrder?.mtoServiceItems.find((s) => s?.id === mtoServiceItemId); + const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); const { modelType } = serviceItem; + let port; + if (modelType === 'MTOServiceItemInternationalFuelSurcharge') { + if (mtoShipment.portOfEmbarkation) { + port = mtoShipment.portOfEmbarkation; + } else if (mtoShipment.portOfDebarkation) { + port = mtoShipment.portOfDebarkation; + } else { + port = null; + } + } const initialValues = { sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', @@ -76,6 +88,7 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { mtoServiceItemID: serviceItem.id, reServiceCode: serviceItem.reServiceCode, eTag: serviceItem.eTag, + portCode: port?.portCode, }; // sending the data submitted in the form to the API @@ -136,6 +149,14 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { onSubmit={onSubmit} /> ) : null} + {modelType === 'MTOServiceItemInternationalFuelSurcharge' ? ( + + ) : null} diff --git a/swagger-def/prime_v3.yaml b/swagger-def/prime_v3.yaml index 344db2011d1..7b9be659619 100644 --- a/swagger-def/prime_v3.yaml +++ b/swagger-def/prime_v3.yaml @@ -348,6 +348,8 @@ definitions: $ref: 'definitions/prime/MTOServiceItemOriginSIT.yaml' MTOServiceItemShuttle: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemShuttle.yaml' + MTOServiceItemInternationalFuelSurcharge: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalFuelSurcharge.yaml' CreateMTOShipment: type: object properties: diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index cb7c5a5d10a..925437e9091 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -663,6 +663,25 @@ definitions: required: - reason - reServiceCode + MTOServiceItemInternationalFuelSurcharge: + description: >- + Describes a international Port of Embarkation/Debarkation fuel surcharge + service item subtype of a MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: >- + A unique code for the service item. Indicates if the service is + for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC). + enum: + - PODFSC + - POEFSC + portCode: + description: A unique code for a Port + type: string CreateMTOShipment: type: object properties: From bc76138a661a682f0eef110ad2b866fb01dc4c6e Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Fri, 29 Nov 2024 16:02:53 +0000 Subject: [PATCH 07/35] add excess ub weight to api defs --- pkg/gen/ghcapi/embedded_spec.go | 24 +++++ pkg/gen/ghcmessages/move.go | 40 +++++++++ pkg/gen/primeapi/embedded_spec.go | 60 +++++++++++++ pkg/gen/primemessages/excess_weight_record.go | 88 +++++++++++++++++++ pkg/gen/primemessages/move_task_order.go | 86 ++++++++++++++++++ pkg/gen/primev2api/embedded_spec.go | 28 ++++++ pkg/gen/primev2messages/move_task_order.go | 86 ++++++++++++++++++ pkg/gen/primev3api/embedded_spec.go | 28 ++++++ pkg/gen/primev3messages/move_task_order.go | 86 ++++++++++++++++++ .../definitions/ExcessWeightRecord.yaml | 18 ++++ .../definitions/prime/MoveTaskOrder.yaml | 12 +++ .../definitions/prime/v2/MoveTaskOrder.yaml | 12 +++ .../definitions/prime/v3/MoveTaskOrder.yaml | 12 +++ swagger-def/ghc.yaml | 10 +++ swagger/ghc.yaml | 15 ++++ swagger/prime.yaml | 34 +++++++ swagger/prime_v2.yaml | 12 +++ swagger/prime_v3.yaml | 12 +++ 18 files changed, 663 insertions(+) diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 361f666c222..e2a6dde23e0 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -9966,6 +9966,18 @@ func init() { "eTag": { "type": "string" }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "description": "Timestamp of when the TOO acknowledged the excess unaccompanied baggage weight risk by either dismissing the alert or updating the max billable weight", + "type": "string", + "format": "date-time", + "x-nullable": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "description": "Timestamp of when the sum of estimated or actual unaccompanied baggage shipment weights of the move reached 90% of the weight allowance", + "type": "string", + "format": "date-time", + "x-nullable": true + }, "excess_weight_acknowledged_at": { "description": "Timestamp of when the TOO acknowledged the excess weight risk by either dismissing the alert or updating the max billable weight", "type": "string", @@ -26710,6 +26722,18 @@ func init() { "eTag": { "type": "string" }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "description": "Timestamp of when the TOO acknowledged the excess unaccompanied baggage weight risk by either dismissing the alert or updating the max billable weight", + "type": "string", + "format": "date-time", + "x-nullable": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "description": "Timestamp of when the sum of estimated or actual unaccompanied baggage shipment weights of the move reached 90% of the weight allowance", + "type": "string", + "format": "date-time", + "x-nullable": true + }, "excess_weight_acknowledged_at": { "description": "Timestamp of when the TOO acknowledged the excess weight risk by either dismissing the alert or updating the max billable weight", "type": "string", diff --git a/pkg/gen/ghcmessages/move.go b/pkg/gen/ghcmessages/move.go index bb67e748b11..26d652a3f42 100644 --- a/pkg/gen/ghcmessages/move.go +++ b/pkg/gen/ghcmessages/move.go @@ -68,6 +68,14 @@ type Move struct { // e tag ETag string `json:"eTag,omitempty"` + // Timestamp of when the TOO acknowledged the excess unaccompanied baggage weight risk by either dismissing the alert or updating the max billable weight + // Format: date-time + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt,omitempty"` + + // Timestamp of when the sum of estimated or actual unaccompanied baggage shipment weights of the move reached 90% of the weight allowance + // Format: date-time + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt,omitempty"` + // Timestamp of when the TOO acknowledged the excess weight risk by either dismissing the alert or updating the max billable weight // Format: date-time ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excess_weight_acknowledged_at,omitempty"` @@ -197,6 +205,14 @@ func (m *Move) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats); err != nil { + res = append(res, err) + } + if err := m.validateExcessWeightAcknowledgedAt(formats); err != nil { res = append(res, err) } @@ -453,6 +469,30 @@ func (m *Move) validateCreatedAt(formats strfmt.Registry) error { return nil } +func (m *Move) validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *Move) validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightQualifiedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightQualifiedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightQualifiedAt.String(), formats); err != nil { + return err + } + + return nil +} + func (m *Move) validateExcessWeightAcknowledgedAt(formats strfmt.Registry) error { if swag.IsZero(m.ExcessWeightAcknowledgedAt) { // not required return nil diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index 52039d783cc..197a34780d7 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -1835,6 +1835,22 @@ func init() { "moveId" ], "properties": { + "moveExcessUnaccompaniedBaggageWeightAcknowledgedAt": { + "description": "The date and time when the TOO acknowledged the excess unaccompanied baggage weight alert, either by dismissing the risk or updating the max billable weight. This will occur after the excess weight record has been uploaded.\n", + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "moveExcessUnaccompaniedBaggageWeightQualifiedAt": { + "description": "The date and time when the sum of all the move's unaccompanied baggage shipments met the excess weight qualification threshold. The system monitors these weights and will update this field automatically.\n", + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "moveExcessWeightAcknowledgedAt": { "description": "The date and time when the TOO acknowledged the excess weight alert, either by dismissing the risk or updating the max billable weight. This will occur after the excess weight record has been uploaded.\n", "type": "string", @@ -2851,6 +2867,20 @@ func init() { "type": "string", "readOnly": true }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "excessWeightAcknowledgedAt": { "type": "string", "format": "date-time", @@ -6729,6 +6759,22 @@ func init() { "moveId" ], "properties": { + "moveExcessUnaccompaniedBaggageWeightAcknowledgedAt": { + "description": "The date and time when the TOO acknowledged the excess unaccompanied baggage weight alert, either by dismissing the risk or updating the max billable weight. This will occur after the excess weight record has been uploaded.\n", + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "moveExcessUnaccompaniedBaggageWeightQualifiedAt": { + "description": "The date and time when the sum of all the move's unaccompanied baggage shipments met the excess weight qualification threshold. The system monitors these weights and will update this field automatically.\n", + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "moveExcessWeightAcknowledgedAt": { "description": "The date and time when the TOO acknowledged the excess weight alert, either by dismissing the risk or updating the max billable weight. This will occur after the excess weight record has been uploaded.\n", "type": "string", @@ -7745,6 +7791,20 @@ func init() { "type": "string", "readOnly": true }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "excessWeightAcknowledgedAt": { "type": "string", "format": "date-time", diff --git a/pkg/gen/primemessages/excess_weight_record.go b/pkg/gen/primemessages/excess_weight_record.go index 03c572134ba..a057c0258b6 100644 --- a/pkg/gen/primemessages/excess_weight_record.go +++ b/pkg/gen/primemessages/excess_weight_record.go @@ -20,6 +20,18 @@ import ( type ExcessWeightRecord struct { UploadWithOmissions + // The date and time when the TOO acknowledged the excess unaccompanied baggage weight alert, either by dismissing the risk or updating the max billable weight. This will occur after the excess weight record has been uploaded. + // + // Read Only: true + // Format: date-time + MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"moveExcessUnaccompaniedBaggageWeightAcknowledgedAt"` + + // The date and time when the sum of all the move's unaccompanied baggage shipments met the excess weight qualification threshold. The system monitors these weights and will update this field automatically. + // + // Read Only: true + // Format: date-time + MoveExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"moveExcessUnaccompaniedBaggageWeightQualifiedAt"` + // The date and time when the TOO acknowledged the excess weight alert, either by dismissing the risk or updating the max billable weight. This will occur after the excess weight record has been uploaded. // // Read Only: true @@ -50,6 +62,10 @@ func (m *ExcessWeightRecord) UnmarshalJSON(raw []byte) error { // AO1 var dataAO1 struct { + MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"moveExcessUnaccompaniedBaggageWeightAcknowledgedAt"` + + MoveExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"moveExcessUnaccompaniedBaggageWeightQualifiedAt"` + MoveExcessWeightAcknowledgedAt *strfmt.DateTime `json:"moveExcessWeightAcknowledgedAt"` MoveExcessWeightQualifiedAt *strfmt.DateTime `json:"moveExcessWeightQualifiedAt"` @@ -60,6 +76,10 @@ func (m *ExcessWeightRecord) UnmarshalJSON(raw []byte) error { return err } + m.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt = dataAO1.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt + + m.MoveExcessUnaccompaniedBaggageWeightQualifiedAt = dataAO1.MoveExcessUnaccompaniedBaggageWeightQualifiedAt + m.MoveExcessWeightAcknowledgedAt = dataAO1.MoveExcessWeightAcknowledgedAt m.MoveExcessWeightQualifiedAt = dataAO1.MoveExcessWeightQualifiedAt @@ -79,6 +99,10 @@ func (m ExcessWeightRecord) MarshalJSON() ([]byte, error) { } _parts = append(_parts, aO0) var dataAO1 struct { + MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"moveExcessUnaccompaniedBaggageWeightAcknowledgedAt"` + + MoveExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"moveExcessUnaccompaniedBaggageWeightQualifiedAt"` + MoveExcessWeightAcknowledgedAt *strfmt.DateTime `json:"moveExcessWeightAcknowledgedAt"` MoveExcessWeightQualifiedAt *strfmt.DateTime `json:"moveExcessWeightQualifiedAt"` @@ -86,6 +110,10 @@ func (m ExcessWeightRecord) MarshalJSON() ([]byte, error) { MoveID *strfmt.UUID `json:"moveId"` } + dataAO1.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt = m.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt + + dataAO1.MoveExcessUnaccompaniedBaggageWeightQualifiedAt = m.MoveExcessUnaccompaniedBaggageWeightQualifiedAt + dataAO1.MoveExcessWeightAcknowledgedAt = m.MoveExcessWeightAcknowledgedAt dataAO1.MoveExcessWeightQualifiedAt = m.MoveExcessWeightQualifiedAt @@ -109,6 +137,14 @@ func (m *ExcessWeightRecord) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateMoveExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveExcessUnaccompaniedBaggageWeightQualifiedAt(formats); err != nil { + res = append(res, err) + } + if err := m.validateMoveExcessWeightAcknowledgedAt(formats); err != nil { res = append(res, err) } @@ -127,6 +163,32 @@ func (m *ExcessWeightRecord) Validate(formats strfmt.Registry) error { return nil } +func (m *ExcessWeightRecord) validateMoveExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats strfmt.Registry) error { + + if swag.IsZero(m.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt) { // not required + return nil + } + + if err := validate.FormatOf("moveExcessUnaccompaniedBaggageWeightAcknowledgedAt", "body", "date-time", m.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *ExcessWeightRecord) validateMoveExcessUnaccompaniedBaggageWeightQualifiedAt(formats strfmt.Registry) error { + + if swag.IsZero(m.MoveExcessUnaccompaniedBaggageWeightQualifiedAt) { // not required + return nil + } + + if err := validate.FormatOf("moveExcessUnaccompaniedBaggageWeightQualifiedAt", "body", "date-time", m.MoveExcessUnaccompaniedBaggageWeightQualifiedAt.String(), formats); err != nil { + return err + } + + return nil +} + func (m *ExcessWeightRecord) validateMoveExcessWeightAcknowledgedAt(formats strfmt.Registry) error { if swag.IsZero(m.MoveExcessWeightAcknowledgedAt) { // not required @@ -175,6 +237,14 @@ func (m *ExcessWeightRecord) ContextValidate(ctx context.Context, formats strfmt res = append(res, err) } + if err := m.contextValidateMoveExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateMoveExcessUnaccompaniedBaggageWeightQualifiedAt(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateMoveExcessWeightAcknowledgedAt(ctx, formats); err != nil { res = append(res, err) } @@ -189,6 +259,24 @@ func (m *ExcessWeightRecord) ContextValidate(ctx context.Context, formats strfmt return nil } +func (m *ExcessWeightRecord) contextValidateMoveExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "moveExcessUnaccompaniedBaggageWeightAcknowledgedAt", "body", m.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt); err != nil { + return err + } + + return nil +} + +func (m *ExcessWeightRecord) contextValidateMoveExcessUnaccompaniedBaggageWeightQualifiedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "moveExcessUnaccompaniedBaggageWeightQualifiedAt", "body", m.MoveExcessUnaccompaniedBaggageWeightQualifiedAt); err != nil { + return err + } + + return nil +} + func (m *ExcessWeightRecord) contextValidateMoveExcessWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { if err := validate.ReadOnly(ctx, "moveExcessWeightAcknowledgedAt", "body", m.MoveExcessWeightAcknowledgedAt); err != nil { diff --git a/pkg/gen/primemessages/move_task_order.go b/pkg/gen/primemessages/move_task_order.go index 3d5f5854487..4871e2e7316 100644 --- a/pkg/gen/primemessages/move_task_order.go +++ b/pkg/gen/primemessages/move_task_order.go @@ -43,6 +43,16 @@ type MoveTaskOrder struct { // Read Only: true ETag string `json:"eTag,omitempty"` + // excess unaccompanied baggage weight acknowledged at + // Read Only: true + // Format: date-time + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + // excess unaccompanied baggage weight qualified at + // Read Only: true + // Format: date-time + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + // excess weight acknowledged at // Read Only: true // Format: date-time @@ -129,6 +139,10 @@ func (m *MoveTaskOrder) UnmarshalJSON(raw []byte) error { ETag string `json:"eTag,omitempty"` + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excessWeightAcknowledgedAt"` ExcessWeightQualifiedAt *strfmt.DateTime `json:"excessWeightQualifiedAt"` @@ -186,6 +200,12 @@ func (m *MoveTaskOrder) UnmarshalJSON(raw []byte) error { // eTag result.ETag = data.ETag + // excessUnaccompaniedBaggageWeightAcknowledgedAt + result.ExcessUnaccompaniedBaggageWeightAcknowledgedAt = data.ExcessUnaccompaniedBaggageWeightAcknowledgedAt + + // excessUnaccompaniedBaggageWeightQualifiedAt + result.ExcessUnaccompaniedBaggageWeightQualifiedAt = data.ExcessUnaccompaniedBaggageWeightQualifiedAt + // excessWeightAcknowledgedAt result.ExcessWeightAcknowledgedAt = data.ExcessWeightAcknowledgedAt @@ -249,6 +269,10 @@ func (m MoveTaskOrder) MarshalJSON() ([]byte, error) { ETag string `json:"eTag,omitempty"` + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excessWeightAcknowledgedAt"` ExcessWeightQualifiedAt *strfmt.DateTime `json:"excessWeightQualifiedAt"` @@ -286,6 +310,10 @@ func (m MoveTaskOrder) MarshalJSON() ([]byte, error) { ETag: m.ETag, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt, + + ExcessUnaccompaniedBaggageWeightQualifiedAt: m.ExcessUnaccompaniedBaggageWeightQualifiedAt, + ExcessWeightAcknowledgedAt: m.ExcessWeightAcknowledgedAt, ExcessWeightQualifiedAt: m.ExcessWeightQualifiedAt, @@ -346,6 +374,14 @@ func (m *MoveTaskOrder) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats); err != nil { + res = append(res, err) + } + if err := m.validateExcessWeightAcknowledgedAt(formats); err != nil { res = append(res, err) } @@ -436,6 +472,30 @@ func (m *MoveTaskOrder) validateCreatedAt(formats strfmt.Registry) error { return nil } +func (m *MoveTaskOrder) validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MoveTaskOrder) validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightQualifiedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightQualifiedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightQualifiedAt.String(), formats); err != nil { + return err + } + + return nil +} + func (m *MoveTaskOrder) validateExcessWeightAcknowledgedAt(formats strfmt.Registry) error { if swag.IsZero(m.ExcessWeightAcknowledgedAt) { // not required return nil @@ -659,6 +719,14 @@ func (m *MoveTaskOrder) ContextValidate(ctx context.Context, formats strfmt.Regi res = append(res, err) } + if err := m.contextValidateExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateExcessUnaccompaniedBaggageWeightQualifiedAt(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateExcessWeightAcknowledgedAt(ctx, formats); err != nil { res = append(res, err) } @@ -741,6 +809,24 @@ func (m *MoveTaskOrder) contextValidateETag(ctx context.Context, formats strfmt. return nil } +func (m *MoveTaskOrder) contextValidateExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt); err != nil { + return err + } + + return nil +} + +func (m *MoveTaskOrder) contextValidateExcessUnaccompaniedBaggageWeightQualifiedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "excessUnaccompaniedBaggageWeightQualifiedAt", "body", m.ExcessUnaccompaniedBaggageWeightQualifiedAt); err != nil { + return err + } + + return nil +} + func (m *MoveTaskOrder) contextValidateExcessWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { if err := validate.ReadOnly(ctx, "excessWeightAcknowledgedAt", "body", m.ExcessWeightAcknowledgedAt); err != nil { diff --git a/pkg/gen/primev2api/embedded_spec.go b/pkg/gen/primev2api/embedded_spec.go index f0468e10884..8de9114e31a 100644 --- a/pkg/gen/primev2api/embedded_spec.go +++ b/pkg/gen/primev2api/embedded_spec.go @@ -1961,6 +1961,20 @@ func init() { "type": "string", "readOnly": true }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "excessWeightAcknowledgedAt": { "type": "string", "format": "date-time", @@ -5568,6 +5582,20 @@ func init() { "type": "string", "readOnly": true }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "excessWeightAcknowledgedAt": { "type": "string", "format": "date-time", diff --git a/pkg/gen/primev2messages/move_task_order.go b/pkg/gen/primev2messages/move_task_order.go index af1390e30c7..28ad294e284 100644 --- a/pkg/gen/primev2messages/move_task_order.go +++ b/pkg/gen/primev2messages/move_task_order.go @@ -47,6 +47,16 @@ type MoveTaskOrder struct { // Read Only: true ETag string `json:"eTag,omitempty"` + // excess unaccompanied baggage weight acknowledged at + // Read Only: true + // Format: date-time + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + // excess unaccompanied baggage weight qualified at + // Read Only: true + // Format: date-time + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + // excess weight acknowledged at // Read Only: true // Format: date-time @@ -135,6 +145,10 @@ func (m *MoveTaskOrder) UnmarshalJSON(raw []byte) error { ETag string `json:"eTag,omitempty"` + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excessWeightAcknowledgedAt"` ExcessWeightQualifiedAt *strfmt.DateTime `json:"excessWeightQualifiedAt"` @@ -195,6 +209,12 @@ func (m *MoveTaskOrder) UnmarshalJSON(raw []byte) error { // eTag result.ETag = data.ETag + // excessUnaccompaniedBaggageWeightAcknowledgedAt + result.ExcessUnaccompaniedBaggageWeightAcknowledgedAt = data.ExcessUnaccompaniedBaggageWeightAcknowledgedAt + + // excessUnaccompaniedBaggageWeightQualifiedAt + result.ExcessUnaccompaniedBaggageWeightQualifiedAt = data.ExcessUnaccompaniedBaggageWeightQualifiedAt + // excessWeightAcknowledgedAt result.ExcessWeightAcknowledgedAt = data.ExcessWeightAcknowledgedAt @@ -260,6 +280,10 @@ func (m MoveTaskOrder) MarshalJSON() ([]byte, error) { ETag string `json:"eTag,omitempty"` + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excessWeightAcknowledgedAt"` ExcessWeightQualifiedAt *strfmt.DateTime `json:"excessWeightQualifiedAt"` @@ -299,6 +323,10 @@ func (m MoveTaskOrder) MarshalJSON() ([]byte, error) { ETag: m.ETag, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt, + + ExcessUnaccompaniedBaggageWeightQualifiedAt: m.ExcessUnaccompaniedBaggageWeightQualifiedAt, + ExcessWeightAcknowledgedAt: m.ExcessWeightAcknowledgedAt, ExcessWeightQualifiedAt: m.ExcessWeightQualifiedAt, @@ -359,6 +387,14 @@ func (m *MoveTaskOrder) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats); err != nil { + res = append(res, err) + } + if err := m.validateExcessWeightAcknowledgedAt(formats); err != nil { res = append(res, err) } @@ -449,6 +485,30 @@ func (m *MoveTaskOrder) validateCreatedAt(formats strfmt.Registry) error { return nil } +func (m *MoveTaskOrder) validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MoveTaskOrder) validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightQualifiedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightQualifiedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightQualifiedAt.String(), formats); err != nil { + return err + } + + return nil +} + func (m *MoveTaskOrder) validateExcessWeightAcknowledgedAt(formats strfmt.Registry) error { if swag.IsZero(m.ExcessWeightAcknowledgedAt) { // not required return nil @@ -676,6 +736,14 @@ func (m *MoveTaskOrder) ContextValidate(ctx context.Context, formats strfmt.Regi res = append(res, err) } + if err := m.contextValidateExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateExcessUnaccompaniedBaggageWeightQualifiedAt(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateExcessWeightAcknowledgedAt(ctx, formats); err != nil { res = append(res, err) } @@ -767,6 +835,24 @@ func (m *MoveTaskOrder) contextValidateETag(ctx context.Context, formats strfmt. return nil } +func (m *MoveTaskOrder) contextValidateExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt); err != nil { + return err + } + + return nil +} + +func (m *MoveTaskOrder) contextValidateExcessUnaccompaniedBaggageWeightQualifiedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "excessUnaccompaniedBaggageWeightQualifiedAt", "body", m.ExcessUnaccompaniedBaggageWeightQualifiedAt); err != nil { + return err + } + + return nil +} + func (m *MoveTaskOrder) contextValidateExcessWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { if err := validate.ReadOnly(ctx, "excessWeightAcknowledgedAt", "body", m.ExcessWeightAcknowledgedAt); err != nil { diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index bb5a844cfe0..326b6d3c562 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -2189,6 +2189,20 @@ func init() { "type": "string", "readOnly": true }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "excessWeightAcknowledgedAt": { "type": "string", "format": "date-time", @@ -6443,6 +6457,20 @@ func init() { "type": "string", "readOnly": true }, + "excessUnaccompaniedBaggageWeightAcknowledgedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, + "excessUnaccompaniedBaggageWeightQualifiedAt": { + "type": "string", + "format": "date-time", + "x-nullable": true, + "x-omitempty": false, + "readOnly": true + }, "excessWeightAcknowledgedAt": { "type": "string", "format": "date-time", diff --git a/pkg/gen/primev3messages/move_task_order.go b/pkg/gen/primev3messages/move_task_order.go index 4d295abc872..bf83af40d6e 100644 --- a/pkg/gen/primev3messages/move_task_order.go +++ b/pkg/gen/primev3messages/move_task_order.go @@ -47,6 +47,16 @@ type MoveTaskOrder struct { // Read Only: true ETag string `json:"eTag,omitempty"` + // excess unaccompanied baggage weight acknowledged at + // Read Only: true + // Format: date-time + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + // excess unaccompanied baggage weight qualified at + // Read Only: true + // Format: date-time + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + // excess weight acknowledged at // Read Only: true // Format: date-time @@ -135,6 +145,10 @@ func (m *MoveTaskOrder) UnmarshalJSON(raw []byte) error { ETag string `json:"eTag,omitempty"` + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excessWeightAcknowledgedAt"` ExcessWeightQualifiedAt *strfmt.DateTime `json:"excessWeightQualifiedAt"` @@ -195,6 +209,12 @@ func (m *MoveTaskOrder) UnmarshalJSON(raw []byte) error { // eTag result.ETag = data.ETag + // excessUnaccompaniedBaggageWeightAcknowledgedAt + result.ExcessUnaccompaniedBaggageWeightAcknowledgedAt = data.ExcessUnaccompaniedBaggageWeightAcknowledgedAt + + // excessUnaccompaniedBaggageWeightQualifiedAt + result.ExcessUnaccompaniedBaggageWeightQualifiedAt = data.ExcessUnaccompaniedBaggageWeightQualifiedAt + // excessWeightAcknowledgedAt result.ExcessWeightAcknowledgedAt = data.ExcessWeightAcknowledgedAt @@ -260,6 +280,10 @@ func (m MoveTaskOrder) MarshalJSON() ([]byte, error) { ETag string `json:"eTag,omitempty"` + ExcessUnaccompaniedBaggageWeightAcknowledgedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightAcknowledgedAt"` + + ExcessUnaccompaniedBaggageWeightQualifiedAt *strfmt.DateTime `json:"excessUnaccompaniedBaggageWeightQualifiedAt"` + ExcessWeightAcknowledgedAt *strfmt.DateTime `json:"excessWeightAcknowledgedAt"` ExcessWeightQualifiedAt *strfmt.DateTime `json:"excessWeightQualifiedAt"` @@ -299,6 +323,10 @@ func (m MoveTaskOrder) MarshalJSON() ([]byte, error) { ETag: m.ETag, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt, + + ExcessUnaccompaniedBaggageWeightQualifiedAt: m.ExcessUnaccompaniedBaggageWeightQualifiedAt, + ExcessWeightAcknowledgedAt: m.ExcessWeightAcknowledgedAt, ExcessWeightQualifiedAt: m.ExcessWeightQualifiedAt, @@ -359,6 +387,14 @@ func (m *MoveTaskOrder) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats); err != nil { + res = append(res, err) + } + + if err := m.validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats); err != nil { + res = append(res, err) + } + if err := m.validateExcessWeightAcknowledgedAt(formats); err != nil { res = append(res, err) } @@ -449,6 +485,30 @@ func (m *MoveTaskOrder) validateCreatedAt(formats strfmt.Registry) error { return nil } +func (m *MoveTaskOrder) validateExcessUnaccompaniedBaggageWeightAcknowledgedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MoveTaskOrder) validateExcessUnaccompaniedBaggageWeightQualifiedAt(formats strfmt.Registry) error { + if swag.IsZero(m.ExcessUnaccompaniedBaggageWeightQualifiedAt) { // not required + return nil + } + + if err := validate.FormatOf("excessUnaccompaniedBaggageWeightQualifiedAt", "body", "date-time", m.ExcessUnaccompaniedBaggageWeightQualifiedAt.String(), formats); err != nil { + return err + } + + return nil +} + func (m *MoveTaskOrder) validateExcessWeightAcknowledgedAt(formats strfmt.Registry) error { if swag.IsZero(m.ExcessWeightAcknowledgedAt) { // not required return nil @@ -676,6 +736,14 @@ func (m *MoveTaskOrder) ContextValidate(ctx context.Context, formats strfmt.Regi res = append(res, err) } + if err := m.contextValidateExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateExcessUnaccompaniedBaggageWeightQualifiedAt(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateExcessWeightAcknowledgedAt(ctx, formats); err != nil { res = append(res, err) } @@ -767,6 +835,24 @@ func (m *MoveTaskOrder) contextValidateETag(ctx context.Context, formats strfmt. return nil } +func (m *MoveTaskOrder) contextValidateExcessUnaccompaniedBaggageWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "excessUnaccompaniedBaggageWeightAcknowledgedAt", "body", m.ExcessUnaccompaniedBaggageWeightAcknowledgedAt); err != nil { + return err + } + + return nil +} + +func (m *MoveTaskOrder) contextValidateExcessUnaccompaniedBaggageWeightQualifiedAt(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "excessUnaccompaniedBaggageWeightQualifiedAt", "body", m.ExcessUnaccompaniedBaggageWeightQualifiedAt); err != nil { + return err + } + + return nil +} + func (m *MoveTaskOrder) contextValidateExcessWeightAcknowledgedAt(ctx context.Context, formats strfmt.Registry) error { if err := validate.ReadOnly(ctx, "excessWeightAcknowledgedAt", "body", m.ExcessWeightAcknowledgedAt); err != nil { diff --git a/swagger-def/definitions/ExcessWeightRecord.yaml b/swagger-def/definitions/ExcessWeightRecord.yaml index f280fa8a163..873a2a54354 100644 --- a/swagger-def/definitions/ExcessWeightRecord.yaml +++ b/swagger-def/definitions/ExcessWeightRecord.yaml @@ -26,5 +26,23 @@ allOf: readOnly: true x-nullable: true x-omitempty: false + moveExcessUnaccompaniedBaggageWeightQualifiedAt: + description: > + The date and time when the sum of all the move's unaccompanied baggage shipments met the excess weight qualification threshold. + The system monitors these weights and will update this field automatically. + type: string + format: date-time + readOnly: true + x-nullable: true + x-omitempty: false + moveExcessUnaccompaniedBaggageWeightAcknowledgedAt: + description: > + The date and time when the TOO acknowledged the excess unaccompanied baggage weight alert, either by dismissing the risk or updating + the max billable weight. This will occur after the excess weight record has been uploaded. + type: string + format: date-time + readOnly: true + x-nullable: true + x-omitempty: false required: - moveId diff --git a/swagger-def/definitions/prime/MoveTaskOrder.yaml b/swagger-def/definitions/prime/MoveTaskOrder.yaml index 1cc5e0458d8..a52afebce6d 100644 --- a/swagger-def/definitions/prime/MoveTaskOrder.yaml +++ b/swagger-def/definitions/prime/MoveTaskOrder.yaml @@ -71,6 +71,18 @@ properties: readOnly: true x-omitempty: false x-nullable: true + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true excessWeightUploadId: type: string format: uuid diff --git a/swagger-def/definitions/prime/v2/MoveTaskOrder.yaml b/swagger-def/definitions/prime/v2/MoveTaskOrder.yaml index a609c3d4e41..439148f2592 100644 --- a/swagger-def/definitions/prime/v2/MoveTaskOrder.yaml +++ b/swagger-def/definitions/prime/v2/MoveTaskOrder.yaml @@ -59,6 +59,18 @@ properties: - FULL ppmEstimatedWeight: type: integer + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true excessWeightQualifiedAt: type: string format: date-time diff --git a/swagger-def/definitions/prime/v3/MoveTaskOrder.yaml b/swagger-def/definitions/prime/v3/MoveTaskOrder.yaml index d10dae35eab..8707ecca023 100644 --- a/swagger-def/definitions/prime/v3/MoveTaskOrder.yaml +++ b/swagger-def/definitions/prime/v3/MoveTaskOrder.yaml @@ -59,6 +59,18 @@ properties: - FULL ppmEstimatedWeight: type: integer + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true excessWeightQualifiedAt: type: string format: date-time diff --git a/swagger-def/ghc.yaml b/swagger-def/ghc.yaml index a0df07f3800..01fb4a4a313 100644 --- a/swagger-def/ghc.yaml +++ b/swagger-def/ghc.yaml @@ -5118,6 +5118,16 @@ definitions: x-nullable: true status: $ref: '#/definitions/MoveStatus' + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + description: Timestamp of when the sum of estimated or actual unaccompanied baggage shipment weights of the move reached 90% of the weight allowance + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + description: Timestamp of when the TOO acknowledged the excess unaccompanied baggage weight risk by either dismissing the alert or updating the max billable weight + x-nullable: true excess_weight_qualified_at: type: string format: date-time diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index ab568b434c8..fd684bfc42a 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -5345,6 +5345,21 @@ definitions: x-nullable: true status: $ref: '#/definitions/MoveStatus' + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + description: >- + Timestamp of when the sum of estimated or actual unaccompanied baggage + shipment weights of the move reached 90% of the weight allowance + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + description: >- + Timestamp of when the TOO acknowledged the excess unaccompanied + baggage weight risk by either dismissing the alert or updating the max + billable weight + x-nullable: true excess_weight_qualified_at: type: string format: date-time diff --git a/swagger/prime.yaml b/swagger/prime.yaml index 83ef52b06c7..042a04f2fb2 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -1953,6 +1953,18 @@ definitions: readOnly: true x-omitempty: false x-nullable: true + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true excessWeightUploadId: type: string format: uuid @@ -4414,6 +4426,28 @@ definitions: readOnly: true x-nullable: true x-omitempty: false + moveExcessUnaccompaniedBaggageWeightQualifiedAt: + description: > + The date and time when the sum of all the move's unaccompanied + baggage shipments met the excess weight qualification threshold. + The system monitors these weights and will update this field + automatically. + type: string + format: date-time + readOnly: true + x-nullable: true + x-omitempty: false + moveExcessUnaccompaniedBaggageWeightAcknowledgedAt: + description: > + The date and time when the TOO acknowledged the excess + unaccompanied baggage weight alert, either by dismissing the risk + or updating the max billable weight. This will occur after the + excess weight record has been uploaded. + type: string + format: date-time + readOnly: true + x-nullable: true + x-omitempty: false required: - moveId ValidationError: diff --git a/swagger/prime_v2.yaml b/swagger/prime_v2.yaml index 00c4e8d169b..18e7689af27 100644 --- a/swagger/prime_v2.yaml +++ b/swagger/prime_v2.yaml @@ -3065,6 +3065,18 @@ definitions: - FULL ppmEstimatedWeight: type: integer + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true excessWeightQualifiedAt: type: string format: date-time diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index cb7c5a5d10a..d0751be100c 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -3568,6 +3568,18 @@ definitions: - FULL ppmEstimatedWeight: type: integer + excessUnaccompaniedBaggageWeightQualifiedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true + excessUnaccompaniedBaggageWeightAcknowledgedAt: + type: string + format: date-time + readOnly: true + x-omitempty: false + x-nullable: true excessWeightQualifiedAt: type: string format: date-time From 022c8930d96a478918dd1c43868cce64c2d00a8e Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Fri, 29 Nov 2024 16:17:06 +0000 Subject: [PATCH 08/35] add excess ub weight to api model to payloads --- .../internal/payloads/model_to_payload.go | 66 ++++++++++--------- .../payloads/model_to_payload_test.go | 21 ++++++ .../primeapi/payloads/model_to_payload.go | 24 ++++--- .../payloads/model_to_payload_test.go | 56 +++++++++------- .../primeapiv2/payloads/model_to_payload.go | 24 ++++--- .../payloads/model_to_payload_test.go | 28 ++++---- .../primeapiv3/payloads/model_to_payload.go | 24 ++++--- .../payloads/model_to_payload_test.go | 12 +++- 8 files changed, 157 insertions(+), 98 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index caa4aef11d5..269627241f0 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -88,38 +88,40 @@ func Move(move *models.Move, storer storage.FileStorer) (*ghcmessages.Move, erro } payload := &ghcmessages.Move{ - ID: strfmt.UUID(move.ID.String()), - AvailableToPrimeAt: handlers.FmtDateTimePtr(move.AvailableToPrimeAt), - ApprovedAt: handlers.FmtDateTimePtr(move.ApprovedAt), - ContractorID: handlers.FmtUUIDPtr(move.ContractorID), - Contractor: Contractor(move.Contractor), - Locator: move.Locator, - OrdersID: strfmt.UUID(move.OrdersID.String()), - Orders: Order(&move.Orders), - ReferenceID: handlers.FmtStringPtr(move.ReferenceID), - Status: ghcmessages.MoveStatus(move.Status), - ExcessWeightQualifiedAt: handlers.FmtDateTimePtr(move.ExcessWeightQualifiedAt), - BillableWeightsReviewedAt: handlers.FmtDateTimePtr(move.BillableWeightsReviewedAt), - CreatedAt: strfmt.DateTime(move.CreatedAt), - SubmittedAt: handlers.FmtDateTimePtr(move.SubmittedAt), - ApprovalsRequestedAt: handlers.FmtDateTimePtr(move.ApprovalsRequestedAt), - UpdatedAt: strfmt.DateTime(move.UpdatedAt), - ETag: etag.GenerateEtag(move.UpdatedAt), - ServiceCounselingCompletedAt: handlers.FmtDateTimePtr(move.ServiceCounselingCompletedAt), - ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(move.ExcessWeightAcknowledgedAt), - TioRemarks: handlers.FmtStringPtr(move.TIORemarks), - FinancialReviewFlag: move.FinancialReviewFlag, - FinancialReviewRemarks: move.FinancialReviewRemarks, - CloseoutOfficeID: handlers.FmtUUIDPtr(move.CloseoutOfficeID), - CloseoutOffice: TransportationOffice(move.CloseoutOffice), - ShipmentGBLOC: gbloc, - LockedByOfficeUserID: handlers.FmtUUIDPtr(move.LockedByOfficeUserID), - LockedByOfficeUser: OfficeUser(move.LockedByOfficeUser), - LockExpiresAt: handlers.FmtDateTimePtr(move.LockExpiresAt), - AdditionalDocuments: additionalDocumentsPayload, - SCAssignedUser: AssignedOfficeUser(move.SCAssignedUser), - TOOAssignedUser: AssignedOfficeUser(move.TOOAssignedUser), - TIOAssignedUser: AssignedOfficeUser(move.TIOAssignedUser), + ID: strfmt.UUID(move.ID.String()), + AvailableToPrimeAt: handlers.FmtDateTimePtr(move.AvailableToPrimeAt), + ApprovedAt: handlers.FmtDateTimePtr(move.ApprovedAt), + ContractorID: handlers.FmtUUIDPtr(move.ContractorID), + Contractor: Contractor(move.Contractor), + Locator: move.Locator, + OrdersID: strfmt.UUID(move.OrdersID.String()), + Orders: Order(&move.Orders), + ReferenceID: handlers.FmtStringPtr(move.ReferenceID), + Status: ghcmessages.MoveStatus(move.Status), + ExcessWeightQualifiedAt: handlers.FmtDateTimePtr(move.ExcessWeightQualifiedAt), + ExcessUnaccompaniedBaggageWeightQualifiedAt: handlers.FmtDateTimePtr(move.ExcessUnaccompaniedBaggageWeightQualifiedAt), + BillableWeightsReviewedAt: handlers.FmtDateTimePtr(move.BillableWeightsReviewedAt), + CreatedAt: strfmt.DateTime(move.CreatedAt), + SubmittedAt: handlers.FmtDateTimePtr(move.SubmittedAt), + ApprovalsRequestedAt: handlers.FmtDateTimePtr(move.ApprovalsRequestedAt), + UpdatedAt: strfmt.DateTime(move.UpdatedAt), + ETag: etag.GenerateEtag(move.UpdatedAt), + ServiceCounselingCompletedAt: handlers.FmtDateTimePtr(move.ServiceCounselingCompletedAt), + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: handlers.FmtDateTimePtr(move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt), + ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(move.ExcessWeightAcknowledgedAt), + TioRemarks: handlers.FmtStringPtr(move.TIORemarks), + FinancialReviewFlag: move.FinancialReviewFlag, + FinancialReviewRemarks: move.FinancialReviewRemarks, + CloseoutOfficeID: handlers.FmtUUIDPtr(move.CloseoutOfficeID), + CloseoutOffice: TransportationOffice(move.CloseoutOffice), + ShipmentGBLOC: gbloc, + LockedByOfficeUserID: handlers.FmtUUIDPtr(move.LockedByOfficeUserID), + LockedByOfficeUser: OfficeUser(move.LockedByOfficeUser), + LockExpiresAt: handlers.FmtDateTimePtr(move.LockExpiresAt), + AdditionalDocuments: additionalDocumentsPayload, + SCAssignedUser: AssignedOfficeUser(move.SCAssignedUser), + TOOAssignedUser: AssignedOfficeUser(move.TOOAssignedUser), + TIOAssignedUser: AssignedOfficeUser(move.TIOAssignedUser), } return payload, nil diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index ec3072d2ca0..b41cd3271e8 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -28,6 +28,27 @@ func TestMove(t *testing.T) { } } +func (suite *PayloadsSuite) TestExcessWeightInMovePayload() { + now := time.Now() + + suite.Run("successfully converts excess weight in model to payload", func() { + move := models.Move{ + + ExcessWeightQualifiedAt: &now, + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: &now, + ExcessWeightAcknowledgedAt: &now, + } + + payload, err := Move(&move, &test.FakeS3Storage{}) + suite.NoError(err) + suite.Equal(handlers.FmtDateTimePtr(move.ExcessWeightQualifiedAt), payload.ExcessWeightQualifiedAt) + suite.Equal(handlers.FmtDateTimePtr(move.ExcessUnaccompaniedBaggageWeightQualifiedAt), payload.ExcessUnaccompaniedBaggageWeightQualifiedAt) + suite.Equal(handlers.FmtDateTimePtr(move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt), payload.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) + suite.Equal(handlers.FmtDateTimePtr(move.ExcessWeightAcknowledgedAt), payload.ExcessWeightAcknowledgedAt) + }) +} + func (suite *PayloadsSuite) TestPaymentRequestQueue() { officeUser := factory.BuildOfficeUserWithPrivileges(suite.DB(), []factory.Customization{ { diff --git a/pkg/handlers/primeapi/payloads/model_to_payload.go b/pkg/handlers/primeapi/payloads/model_to_payload.go index d5c76723fa4..06f8db79c6e 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload.go @@ -36,15 +36,19 @@ func MoveTaskOrder(moveTaskOrder *models.Move) *primemessages.MoveTaskOrder { ApprovedAt: handlers.FmtDateTimePtr(moveTaskOrder.ApprovedAt), PrimeCounselingCompletedAt: handlers.FmtDateTimePtr(moveTaskOrder.PrimeCounselingCompletedAt), ExcessWeightQualifiedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightQualifiedAt), - ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightAcknowledgedAt), - ExcessWeightUploadID: handlers.FmtUUIDPtr(moveTaskOrder.ExcessWeightUploadID), - OrderID: strfmt.UUID(moveTaskOrder.OrdersID.String()), - Order: Order(&moveTaskOrder.Orders), - ReferenceID: *moveTaskOrder.ReferenceID, - PaymentRequests: *paymentRequests, - MtoShipments: *mtoShipments, - UpdatedAt: strfmt.DateTime(moveTaskOrder.UpdatedAt), - ETag: etag.GenerateEtag(moveTaskOrder.UpdatedAt), + ExcessUnaccompaniedBaggageWeightQualifiedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessUnaccompaniedBaggageWeightQualifiedAt), + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessUnaccompaniedBaggageWeightAcknowledgedAt), + ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightAcknowledgedAt), + ExcessWeightUploadID: handlers.FmtUUIDPtr(moveTaskOrder.ExcessWeightUploadID), + OrderID: strfmt.UUID(moveTaskOrder.OrdersID.String()), + Order: Order(&moveTaskOrder.Orders), + DestinationGBLOC: destGbloc, + DestinationPostalCode: destZip, + ReferenceID: *moveTaskOrder.ReferenceID, + PaymentRequests: *paymentRequests, + MtoShipments: *mtoShipments, + UpdatedAt: strfmt.DateTime(moveTaskOrder.UpdatedAt), + ETag: etag.GenerateEtag(moveTaskOrder.UpdatedAt), } if moveTaskOrder.PPMType != nil { @@ -856,6 +860,8 @@ func ExcessWeightRecord(appCtx appcontext.AppContext, storer storage.FileStorer, MoveID: handlers.FmtUUIDPtr(&move.ID), MoveExcessWeightQualifiedAt: handlers.FmtDateTimePtr(move.ExcessWeightQualifiedAt), MoveExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(move.ExcessWeightAcknowledgedAt), + MoveExcessUnaccompaniedBaggageWeightQualifiedAt: handlers.FmtDateTimePtr(move.ExcessUnaccompaniedBaggageWeightQualifiedAt), + MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt: handlers.FmtDateTimePtr(move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt), } upload := Upload(appCtx, storer, move.ExcessWeightUpload) diff --git a/pkg/handlers/primeapi/payloads/model_to_payload_test.go b/pkg/handlers/primeapi/payloads/model_to_payload_test.go index 73342af2430..37c2eea09fd 100644 --- a/pkg/handlers/primeapi/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapi/payloads/model_to_payload_test.go @@ -24,31 +24,35 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { primeTime := time.Now() submittedAt := time.Now() excessWeightQualifiedAt := time.Now() + excessUnaccompaniedBaggageWeightQualifiedAt := time.Now() excessWeightAcknowledgedAt := time.Now() + excessUnaccompaniedBaggageWeightAcknowledgedAt := time.Now() excessWeightUploadID := uuid.Must(uuid.NewV4()) ordersType := primemessages.OrdersTypeRETIREMENT originDutyGBLOC := "KKFA" shipmentGBLOC := "AGFM" basicMove := models.Move{ - ID: moveTaskOrderID, - Locator: "TESTTEST", - CreatedAt: time.Now(), - AvailableToPrimeAt: &primeTime, - ApprovedAt: &primeTime, - OrdersID: ordersID, - Orders: models.Order{OrdersType: internalmessages.OrdersType(ordersType), OriginDutyLocationGBLOC: &originDutyGBLOC}, - ReferenceID: &referenceID, - PaymentRequests: models.PaymentRequests{}, - SubmittedAt: &submittedAt, - UpdatedAt: time.Now(), - Status: models.MoveStatusAPPROVED, - SignedCertifications: models.SignedCertifications{}, - MTOServiceItems: models.MTOServiceItems{}, - MTOShipments: models.MTOShipments{}, - ExcessWeightQualifiedAt: &excessWeightQualifiedAt, - ExcessWeightAcknowledgedAt: &excessWeightAcknowledgedAt, - ExcessWeightUploadID: &excessWeightUploadID, + ID: moveTaskOrderID, + Locator: "TESTTEST", + CreatedAt: time.Now(), + AvailableToPrimeAt: &primeTime, + ApprovedAt: &primeTime, + OrdersID: ordersID, + Orders: models.Order{OrdersType: internalmessages.OrdersType(ordersType), OriginDutyLocationGBLOC: &originDutyGBLOC}, + ReferenceID: &referenceID, + PaymentRequests: models.PaymentRequests{}, + SubmittedAt: &submittedAt, + UpdatedAt: time.Now(), + Status: models.MoveStatusAPPROVED, + SignedCertifications: models.SignedCertifications{}, + MTOServiceItems: models.MTOServiceItems{}, + MTOShipments: models.MTOShipments{}, + ExcessWeightQualifiedAt: &excessWeightQualifiedAt, + ExcessUnaccompaniedBaggageWeightQualifiedAt: &excessUnaccompaniedBaggageWeightQualifiedAt, + ExcessWeightAcknowledgedAt: &excessWeightAcknowledgedAt, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: &excessUnaccompaniedBaggageWeightAcknowledgedAt, + ExcessWeightUploadID: &excessWeightUploadID, ShipmentGBLOC: models.MoveToGBLOCs{ models.MoveToGBLOC{GBLOC: &shipmentGBLOC}, }, @@ -70,7 +74,9 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { suite.Equal(strfmt.DateTime(basicMove.UpdatedAt), returnedModel.UpdatedAt) suite.NotEmpty(returnedModel.ETag) suite.True(returnedModel.ExcessWeightQualifiedAt.Equal(strfmt.DateTime(*basicMove.ExcessWeightQualifiedAt))) + suite.True(returnedModel.ExcessUnaccompaniedBaggageWeightQualifiedAt.Equal(strfmt.DateTime(*basicMove.ExcessUnaccompaniedBaggageWeightQualifiedAt))) suite.True(returnedModel.ExcessWeightAcknowledgedAt.Equal(strfmt.DateTime(*basicMove.ExcessWeightAcknowledgedAt))) + suite.True(returnedModel.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.Equal(strfmt.DateTime(*basicMove.ExcessUnaccompaniedBaggageWeightAcknowledgedAt))) suite.Require().NotNil(returnedModel.ExcessWeightUploadID) suite.Equal(strfmt.UUID(basicMove.ExcessWeightUploadID.String()), *returnedModel.ExcessWeightUploadID) }) @@ -153,17 +159,21 @@ func (suite *PayloadsSuite) TestExcessWeightRecord() { }, []factory.Trait{factory.GetTraitTimestampedUpload}) move := models.Move{ - ID: id, - ExcessWeightQualifiedAt: &now, - ExcessWeightAcknowledgedAt: &now, - ExcessWeightUploadID: &upload.ID, - ExcessWeightUpload: &upload, + ID: id, + ExcessWeightQualifiedAt: &now, + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + ExcessWeightAcknowledgedAt: &now, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: &now, + ExcessWeightUploadID: &upload.ID, + ExcessWeightUpload: &upload, } excessWeightRecord := ExcessWeightRecord(suite.AppContextForTest(), fakeFileStorer, &move) suite.Equal(move.ID.String(), excessWeightRecord.MoveID.String()) suite.Equal(strfmt.DateTime(*move.ExcessWeightQualifiedAt).String(), excessWeightRecord.MoveExcessWeightQualifiedAt.String()) + suite.Equal(strfmt.DateTime(*move.ExcessUnaccompaniedBaggageWeightQualifiedAt).String(), excessWeightRecord.MoveExcessUnaccompaniedBaggageWeightQualifiedAt.String()) suite.Equal(strfmt.DateTime(*move.ExcessWeightAcknowledgedAt).String(), excessWeightRecord.MoveExcessWeightAcknowledgedAt.String()) + suite.Equal(strfmt.DateTime(*move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt).String(), excessWeightRecord.MoveExcessUnaccompaniedBaggageWeightAcknowledgedAt.String()) suite.Equal(move.ExcessWeightUploadID.String(), excessWeightRecord.ID.String()) suite.Equal(move.ExcessWeightUpload.ID.String(), excessWeightRecord.ID.String()) diff --git a/pkg/handlers/primeapiv2/payloads/model_to_payload.go b/pkg/handlers/primeapiv2/payloads/model_to_payload.go index 56ad6caabcb..d74b44f0dbb 100644 --- a/pkg/handlers/primeapiv2/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv2/payloads/model_to_payload.go @@ -32,16 +32,20 @@ func MoveTaskOrder(moveTaskOrder *models.Move) *primev2messages.MoveTaskOrder { ApprovedAt: handlers.FmtDateTimePtr(moveTaskOrder.ApprovedAt), PrimeCounselingCompletedAt: handlers.FmtDateTimePtr(moveTaskOrder.PrimeCounselingCompletedAt), ExcessWeightQualifiedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightQualifiedAt), - ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightAcknowledgedAt), - ExcessWeightUploadID: handlers.FmtUUIDPtr(moveTaskOrder.ExcessWeightUploadID), - OrderID: strfmt.UUID(moveTaskOrder.OrdersID.String()), - Order: Order(&moveTaskOrder.Orders), - ReferenceID: *moveTaskOrder.ReferenceID, - PaymentRequests: *paymentRequests, - MtoShipments: *mtoShipments, - ContractNumber: moveTaskOrder.Contractor.ContractNumber, - UpdatedAt: strfmt.DateTime(moveTaskOrder.UpdatedAt), - ETag: etag.GenerateEtag(moveTaskOrder.UpdatedAt), + ExcessUnaccompaniedBaggageWeightQualifiedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessUnaccompaniedBaggageWeightQualifiedAt), + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessUnaccompaniedBaggageWeightAcknowledgedAt), + ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightAcknowledgedAt), + ExcessWeightUploadID: handlers.FmtUUIDPtr(moveTaskOrder.ExcessWeightUploadID), + OrderID: strfmt.UUID(moveTaskOrder.OrdersID.String()), + Order: Order(&moveTaskOrder.Orders), + DestinationGBLOC: destGbloc, + DestinationPostalCode: destZip, + ReferenceID: *moveTaskOrder.ReferenceID, + PaymentRequests: *paymentRequests, + MtoShipments: *mtoShipments, + ContractNumber: moveTaskOrder.Contractor.ContractNumber, + UpdatedAt: strfmt.DateTime(moveTaskOrder.UpdatedAt), + ETag: etag.GenerateEtag(moveTaskOrder.UpdatedAt), } if moveTaskOrder.PPMType != nil { diff --git a/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go b/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go index 13e3bd35e3c..f2b4c07ef0c 100644 --- a/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapiv2/payloads/model_to_payload_test.go @@ -23,7 +23,9 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { primeTime := time.Now() submittedAt := time.Now() excessWeightQualifiedAt := time.Now() + excessUnaccompaniedBaggageWeightQualifiedAt := time.Now() excessWeightAcknowledgedAt := time.Now() + excessUnaccompaniedBaggageWeightAcknowledgedAt := time.Now() excessWeightUploadID := uuid.Must(uuid.NewV4()) ordersType := primev2messages.OrdersTypeRETIREMENT originDutyGBLOC := "KKFA" @@ -44,17 +46,19 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { NAICS: models.NAICS, PackingAndShippingInstructions: packingInstructions, }, - ReferenceID: &referenceID, - PaymentRequests: models.PaymentRequests{}, - SubmittedAt: &submittedAt, - UpdatedAt: time.Now(), - Status: models.MoveStatusAPPROVED, - SignedCertifications: models.SignedCertifications{}, - MTOServiceItems: models.MTOServiceItems{}, - MTOShipments: models.MTOShipments{}, - ExcessWeightQualifiedAt: &excessWeightQualifiedAt, - ExcessWeightAcknowledgedAt: &excessWeightAcknowledgedAt, - ExcessWeightUploadID: &excessWeightUploadID, + ReferenceID: &referenceID, + PaymentRequests: models.PaymentRequests{}, + SubmittedAt: &submittedAt, + UpdatedAt: time.Now(), + Status: models.MoveStatusAPPROVED, + SignedCertifications: models.SignedCertifications{}, + MTOServiceItems: models.MTOServiceItems{}, + MTOShipments: models.MTOShipments{}, + ExcessWeightQualifiedAt: &excessWeightQualifiedAt, + ExcessUnaccompaniedBaggageWeightQualifiedAt: &excessUnaccompaniedBaggageWeightQualifiedAt, + ExcessWeightAcknowledgedAt: &excessWeightAcknowledgedAt, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: &excessUnaccompaniedBaggageWeightAcknowledgedAt, + ExcessWeightUploadID: &excessWeightUploadID, Contractor: &models.Contractor{ ContractNumber: factory.DefaultContractNumber, }, @@ -78,7 +82,9 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { suite.Equal(strfmt.DateTime(basicMove.UpdatedAt), returnedModel.UpdatedAt) suite.NotEmpty(returnedModel.ETag) suite.True(returnedModel.ExcessWeightQualifiedAt.Equal(strfmt.DateTime(*basicMove.ExcessWeightQualifiedAt))) + suite.True(returnedModel.ExcessUnaccompaniedBaggageWeightQualifiedAt.Equal(strfmt.DateTime(*basicMove.ExcessUnaccompaniedBaggageWeightQualifiedAt))) suite.True(returnedModel.ExcessWeightAcknowledgedAt.Equal(strfmt.DateTime(*basicMove.ExcessWeightAcknowledgedAt))) + suite.True(returnedModel.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.Equal(strfmt.DateTime(*basicMove.ExcessUnaccompaniedBaggageWeightAcknowledgedAt))) suite.Require().NotNil(returnedModel.ExcessWeightUploadID) suite.Equal(strfmt.UUID(basicMove.ExcessWeightUploadID.String()), *returnedModel.ExcessWeightUploadID) suite.Equal(factory.DefaultContractNumber, returnedModel.ContractNumber) diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload.go b/pkg/handlers/primeapiv3/payloads/model_to_payload.go index f4cd6ab2609..103ba9bceb3 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload.go @@ -33,16 +33,20 @@ func MoveTaskOrder(moveTaskOrder *models.Move) *primev3messages.MoveTaskOrder { AvailableToPrimeAt: handlers.FmtDateTimePtr(moveTaskOrder.AvailableToPrimeAt), PrimeCounselingCompletedAt: handlers.FmtDateTimePtr(moveTaskOrder.PrimeCounselingCompletedAt), ExcessWeightQualifiedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightQualifiedAt), - ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightAcknowledgedAt), - ExcessWeightUploadID: handlers.FmtUUIDPtr(moveTaskOrder.ExcessWeightUploadID), - OrderID: strfmt.UUID(moveTaskOrder.OrdersID.String()), - Order: Order(&moveTaskOrder.Orders), - ReferenceID: *moveTaskOrder.ReferenceID, - PaymentRequests: *paymentRequests, - MtoShipments: *mtoShipments, - ContractNumber: moveTaskOrder.Contractor.ContractNumber, - UpdatedAt: strfmt.DateTime(moveTaskOrder.UpdatedAt), - ETag: etag.GenerateEtag(moveTaskOrder.UpdatedAt), + ExcessUnaccompaniedBaggageWeightQualifiedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessUnaccompaniedBaggageWeightQualifiedAt), + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessUnaccompaniedBaggageWeightAcknowledgedAt), + ExcessWeightAcknowledgedAt: handlers.FmtDateTimePtr(moveTaskOrder.ExcessWeightAcknowledgedAt), + ExcessWeightUploadID: handlers.FmtUUIDPtr(moveTaskOrder.ExcessWeightUploadID), + OrderID: strfmt.UUID(moveTaskOrder.OrdersID.String()), + Order: Order(&moveTaskOrder.Orders), + DestinationGBLOC: destGbloc, + DestinationPostalCode: destZip, + ReferenceID: *moveTaskOrder.ReferenceID, + PaymentRequests: *paymentRequests, + MtoShipments: *mtoShipments, + ContractNumber: moveTaskOrder.Contractor.ContractNumber, + UpdatedAt: strfmt.DateTime(moveTaskOrder.UpdatedAt), + ETag: etag.GenerateEtag(moveTaskOrder.UpdatedAt), } if moveTaskOrder.PPMType != nil { diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go b/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go index 5f7e78e43ed..ad076508521 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload_test.go @@ -23,7 +23,9 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { primeTime := time.Now() submittedAt := time.Now() excessWeightQualifiedAt := time.Now() + excessUnaccompaniedBaggageWeightQualifiedAt := time.Now() excessWeightAcknowledgedAt := time.Now() + excessUnaccompaniedBaggageWeightAcknowledgedAt := time.Now() excessWeightUploadID := uuid.Must(uuid.NewV4()) ordersType := primev3messages.OrdersTypeRETIREMENT originDutyGBLOC := "KKFA" @@ -67,9 +69,11 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { }, }, }, - ExcessWeightQualifiedAt: &excessWeightQualifiedAt, - ExcessWeightAcknowledgedAt: &excessWeightAcknowledgedAt, - ExcessWeightUploadID: &excessWeightUploadID, + ExcessWeightQualifiedAt: &excessWeightQualifiedAt, + ExcessWeightAcknowledgedAt: &excessWeightAcknowledgedAt, + ExcessUnaccompaniedBaggageWeightQualifiedAt: &excessUnaccompaniedBaggageWeightQualifiedAt, + ExcessUnaccompaniedBaggageWeightAcknowledgedAt: &excessUnaccompaniedBaggageWeightAcknowledgedAt, + ExcessWeightUploadID: &excessWeightUploadID, Contractor: &models.Contractor{ ContractNumber: factory.DefaultContractNumber, }, @@ -92,7 +96,9 @@ func (suite *PayloadsSuite) TestMoveTaskOrder() { suite.Equal(referenceID, returnedModel.ReferenceID) suite.Equal(strfmt.DateTime(basicMove.UpdatedAt), returnedModel.UpdatedAt) suite.NotEmpty(returnedModel.ETag) + suite.True(returnedModel.ExcessUnaccompaniedBaggageWeightQualifiedAt.Equal(strfmt.DateTime(*basicMove.ExcessUnaccompaniedBaggageWeightQualifiedAt))) suite.True(returnedModel.ExcessWeightQualifiedAt.Equal(strfmt.DateTime(*basicMove.ExcessWeightQualifiedAt))) + suite.True(returnedModel.ExcessUnaccompaniedBaggageWeightAcknowledgedAt.Equal(strfmt.DateTime(*basicMove.ExcessUnaccompaniedBaggageWeightAcknowledgedAt))) suite.True(returnedModel.ExcessWeightAcknowledgedAt.Equal(strfmt.DateTime(*basicMove.ExcessWeightAcknowledgedAt))) suite.Require().NotNil(returnedModel.ExcessWeightUploadID) suite.Equal(strfmt.UUID(basicMove.ExcessWeightUploadID.String()), *returnedModel.ExcessWeightUploadID) From 3b2646e3db1c9e0746fcad36ef4658cad4803f77 Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Fri, 29 Nov 2024 18:37:11 +0000 Subject: [PATCH 09/35] api support for excess ub weight risk acknowledgement --- pkg/gen/ghcapi/configure_mymove.go | 5 + pkg/gen/ghcapi/embedded_spec.go | 135 +++++++++ pkg/gen/ghcapi/ghcoperations/mymove_api.go | 12 + ...xcess_unaccompanied_baggage_weight_risk.go | 58 ++++ ...ompanied_baggage_weight_risk_parameters.go | 120 ++++++++ ...companied_baggage_weight_risk_responses.go | 284 ++++++++++++++++++ ...ompanied_baggage_weight_risk_urlbuilder.go | 101 +++++++ pkg/handlers/ghcapi/api.go | 5 + pkg/handlers/ghcapi/orders.go | 73 +++++ pkg/handlers/ghcapi/orders_test.go | 173 +++++++++++ pkg/services/event/ghc_endpoint.go | 7 + pkg/services/mocks/ExcessWeightRiskManager.go | 30 ++ pkg/services/order.go | 1 + .../order/excess_weight_risk_manager.go | 72 ++++- .../order/excess_weight_risk_manager_test.go | 28 ++ src/services/ghcApi.js | 5 + swagger-def/ghc.yaml | 40 +++ swagger/ghc.yaml | 44 +++ 18 files changed, 1178 insertions(+), 15 deletions(-) create mode 100644 pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk.go create mode 100644 pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_parameters.go create mode 100644 pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_responses.go create mode 100644 pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_urlbuilder.go diff --git a/pkg/gen/ghcapi/configure_mymove.go b/pkg/gen/ghcapi/configure_mymove.go index c4c3d349ed6..9a048c0ef2c 100644 --- a/pkg/gen/ghcapi/configure_mymove.go +++ b/pkg/gen/ghcapi/configure_mymove.go @@ -72,6 +72,11 @@ func configureAPI(api *ghcoperations.MymoveAPI) http.Handler { // You may change here the memory limit for this multipart form parser. Below is the default (32 MB). // order.UploadAmendedOrdersMaxParseMemory = 32 << 20 + if api.OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler == nil { + api.OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler = order.AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandlerFunc(func(params order.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) middleware.Responder { + return middleware.NotImplemented("operation order.AcknowledgeExcessUnaccompaniedBaggageWeightRisk has not yet been implemented") + }) + } if api.OrderAcknowledgeExcessWeightRiskHandler == nil { api.OrderAcknowledgeExcessWeightRiskHandler = order.AcknowledgeExcessWeightRiskHandlerFunc(func(params order.AcknowledgeExcessWeightRiskParams) middleware.Responder { return middleware.NotImplemented("operation order.AcknowledgeExcessWeightRisk has not yet been implemented") diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index e2a6dde23e0..b70de31dce3 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -3167,6 +3167,66 @@ func init() { } ] }, + "/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk": { + "post": { + "description": "Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "order" + ], + "summary": "Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert", + "operationId": "acknowledgeExcessUnaccompaniedBaggageWeightRisk", + "parameters": [ + { + "type": "string", + "name": "If-Match", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "updated Move", + "schema": { + "$ref": "#/definitions/Move" + } + }, + "403": { + "$ref": "#/responses/PermissionDenied" + }, + "404": { + "$ref": "#/responses/NotFound" + }, + "412": { + "$ref": "#/responses/PreconditionFailed" + }, + "422": { + "$ref": "#/responses/UnprocessableEntity" + }, + "500": { + "$ref": "#/responses/ServerError" + } + }, + "x-permissions": [ + "update.excessWeightRisk" + ] + }, + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "ID of order to use", + "name": "orderID", + "in": "path", + "required": true + } + ] + }, "/orders/{orderID}/acknowledge-excess-weight-risk": { "post": { "description": "Saves the date and time a TOO acknowledged the excess weight risk by dismissing the alert", @@ -19162,6 +19222,81 @@ func init() { } ] }, + "/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk": { + "post": { + "description": "Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "order" + ], + "summary": "Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert", + "operationId": "acknowledgeExcessUnaccompaniedBaggageWeightRisk", + "parameters": [ + { + "type": "string", + "name": "If-Match", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "updated Move", + "schema": { + "$ref": "#/definitions/Move" + } + }, + "403": { + "description": "The request was denied", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "404": { + "description": "The requested resource wasn't found", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "412": { + "description": "Precondition failed", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "422": { + "description": "The payload was unprocessable.", + "schema": { + "$ref": "#/definitions/ValidationError" + } + }, + "500": { + "description": "A server error occurred", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "x-permissions": [ + "update.excessWeightRisk" + ] + }, + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "ID of order to use", + "name": "orderID", + "in": "path", + "required": true + } + ] + }, "/orders/{orderID}/acknowledge-excess-weight-risk": { "post": { "description": "Saves the date and time a TOO acknowledged the excess weight risk by dismissing the alert", diff --git a/pkg/gen/ghcapi/ghcoperations/mymove_api.go b/pkg/gen/ghcapi/ghcoperations/mymove_api.go index 10a373d0be4..18d2b600df4 100644 --- a/pkg/gen/ghcapi/ghcoperations/mymove_api.go +++ b/pkg/gen/ghcapi/ghcoperations/mymove_api.go @@ -71,6 +71,9 @@ func NewMymoveAPI(spec *loads.Document) *MymoveAPI { BinProducer: runtime.ByteStreamProducer(), JSONProducer: runtime.JSONProducer(), + OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler: order.AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandlerFunc(func(params order.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) middleware.Responder { + return middleware.NotImplemented("operation order.AcknowledgeExcessUnaccompaniedBaggageWeightRisk has not yet been implemented") + }), OrderAcknowledgeExcessWeightRiskHandler: order.AcknowledgeExcessWeightRiskHandlerFunc(func(params order.AcknowledgeExcessWeightRiskParams) middleware.Responder { return middleware.NotImplemented("operation order.AcknowledgeExcessWeightRisk has not yet been implemented") }), @@ -435,6 +438,8 @@ type MymoveAPI struct { // - application/json JSONProducer runtime.Producer + // OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler sets the operation handler for the acknowledge excess unaccompanied baggage weight risk operation + OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler order.AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler // OrderAcknowledgeExcessWeightRiskHandler sets the operation handler for the acknowledge excess weight risk operation OrderAcknowledgeExcessWeightRiskHandler order.AcknowledgeExcessWeightRiskHandler // EvaluationReportsAddAppealToSeriousIncidentHandler sets the operation handler for the add appeal to serious incident operation @@ -730,6 +735,9 @@ func (o *MymoveAPI) Validate() error { unregistered = append(unregistered, "JSONProducer") } + if o.OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler == nil { + unregistered = append(unregistered, "order.AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler") + } if o.OrderAcknowledgeExcessWeightRiskHandler == nil { unregistered = append(unregistered, "order.AcknowledgeExcessWeightRiskHandler") } @@ -1140,6 +1148,10 @@ func (o *MymoveAPI) initHandlerCache() { o.handlers = make(map[string]map[string]http.Handler) } + if o.handlers["POST"] == nil { + o.handlers["POST"] = make(map[string]http.Handler) + } + o.handlers["POST"]["/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk"] = order.NewAcknowledgeExcessUnaccompaniedBaggageWeightRisk(o.context, o.OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } diff --git a/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk.go b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk.go new file mode 100644 index 00000000000..f41ed6bdfd7 --- /dev/null +++ b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk.go @@ -0,0 +1,58 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package order + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandlerFunc turns a function with the right signature into a acknowledge excess unaccompanied baggage weight risk handler +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandlerFunc func(AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandlerFunc) Handle(params AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) middleware.Responder { + return fn(params) +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler interface for that can handle valid acknowledge excess unaccompanied baggage weight risk params +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler interface { + Handle(AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) middleware.Responder +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRisk creates a new http.Handler for the acknowledge excess unaccompanied baggage weight risk operation +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRisk(ctx *middleware.Context, handler AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler) *AcknowledgeExcessUnaccompaniedBaggageWeightRisk { + return &AcknowledgeExcessUnaccompaniedBaggageWeightRisk{Context: ctx, Handler: handler} +} + +/* + AcknowledgeExcessUnaccompaniedBaggageWeightRisk swagger:route POST /orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk order acknowledgeExcessUnaccompaniedBaggageWeightRisk + +# Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert + +Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRisk struct { + Context *middleware.Context + Handler AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler +} + +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRisk) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_parameters.go b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_parameters.go new file mode 100644 index 00000000000..15deb918e6e --- /dev/null +++ b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_parameters.go @@ -0,0 +1,120 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package order + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" +) + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskParams creates a new AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams object +// +// There are no default values defined in the spec. +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskParams() AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams { + + return AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams{} +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams contains all the bound params for the acknowledge excess unaccompanied baggage weight risk operation +// typically these are obtained from a http.Request +// +// swagger:parameters acknowledgeExcessUnaccompaniedBaggageWeightRisk +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: header + */ + IfMatch string + /*ID of order to use + Required: true + In: path + */ + OrderID strfmt.UUID +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskParams() beforehand. +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if err := o.bindIfMatch(r.Header[http.CanonicalHeaderKey("If-Match")], true, route.Formats); err != nil { + res = append(res, err) + } + + rOrderID, rhkOrderID, _ := route.Params.GetOK("orderID") + if err := o.bindOrderID(rOrderID, rhkOrderID, route.Formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindIfMatch binds and validates parameter IfMatch from header. +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) bindIfMatch(rawData []string, hasKey bool, formats strfmt.Registry) error { + if !hasKey { + return errors.Required("If-Match", "header", rawData) + } + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + + if err := validate.RequiredString("If-Match", "header", raw); err != nil { + return err + } + o.IfMatch = raw + + return nil +} + +// bindOrderID binds and validates parameter OrderID from path. +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) bindOrderID(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + // Format: uuid + value, err := formats.Parse("uuid", raw) + if err != nil { + return errors.InvalidType("orderID", "path", "strfmt.UUID", raw) + } + o.OrderID = *(value.(*strfmt.UUID)) + + if err := o.validateOrderID(formats); err != nil { + return err + } + + return nil +} + +// validateOrderID carries on validations for parameter OrderID +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams) validateOrderID(formats strfmt.Registry) error { + + if err := validate.FormatOf("orderID", "path", "uuid", o.OrderID.String(), formats); err != nil { + return err + } + return nil +} diff --git a/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_responses.go b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_responses.go new file mode 100644 index 00000000000..04c674fc725 --- /dev/null +++ b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_responses.go @@ -0,0 +1,284 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package order + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/transcom/mymove/pkg/gen/ghcmessages" +) + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskOKCode is the HTTP code returned for type AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK +const AcknowledgeExcessUnaccompaniedBaggageWeightRiskOKCode int = 200 + +/* +AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK updated Move + +swagger:response acknowledgeExcessUnaccompaniedBaggageWeightRiskOK +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK struct { + + /* + In: Body + */ + Payload *ghcmessages.Move `json:"body,omitempty"` +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskOK creates AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK with default headers values +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskOK() *AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK { + + return &AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK{} +} + +// WithPayload adds the payload to the acknowledge excess unaccompanied baggage weight risk o k response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK) WithPayload(payload *ghcmessages.Move) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the acknowledge excess unaccompanied baggage weight risk o k response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK) SetPayload(payload *ghcmessages.Move) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbiddenCode is the HTTP code returned for type AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden +const AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbiddenCode int = 403 + +/* +AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden The request was denied + +swagger:response acknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden struct { + + /* + In: Body + */ + Payload *ghcmessages.Error `json:"body,omitempty"` +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden creates AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden with default headers values +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden() *AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden { + + return &AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden{} +} + +// WithPayload adds the payload to the acknowledge excess unaccompanied baggage weight risk forbidden response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden) WithPayload(payload *ghcmessages.Error) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the acknowledge excess unaccompanied baggage weight risk forbidden response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden) SetPayload(payload *ghcmessages.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(403) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFoundCode is the HTTP code returned for type AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound +const AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFoundCode int = 404 + +/* +AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound The requested resource wasn't found + +swagger:response acknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound struct { + + /* + In: Body + */ + Payload *ghcmessages.Error `json:"body,omitempty"` +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound creates AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound with default headers values +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound() *AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound { + + return &AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound{} +} + +// WithPayload adds the payload to the acknowledge excess unaccompanied baggage weight risk not found response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound) WithPayload(payload *ghcmessages.Error) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the acknowledge excess unaccompanied baggage weight risk not found response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound) SetPayload(payload *ghcmessages.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(404) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailedCode is the HTTP code returned for type AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed +const AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailedCode int = 412 + +/* +AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed Precondition failed + +swagger:response acknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed struct { + + /* + In: Body + */ + Payload *ghcmessages.Error `json:"body,omitempty"` +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed creates AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed with default headers values +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed() *AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed { + + return &AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed{} +} + +// WithPayload adds the payload to the acknowledge excess unaccompanied baggage weight risk precondition failed response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed) WithPayload(payload *ghcmessages.Error) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the acknowledge excess unaccompanied baggage weight risk precondition failed response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed) SetPayload(payload *ghcmessages.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(412) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntityCode is the HTTP code returned for type AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity +const AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntityCode int = 422 + +/* +AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity The payload was unprocessable. + +swagger:response acknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity struct { + + /* + In: Body + */ + Payload *ghcmessages.ValidationError `json:"body,omitempty"` +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity creates AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity with default headers values +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity() *AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity { + + return &AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity{} +} + +// WithPayload adds the payload to the acknowledge excess unaccompanied baggage weight risk unprocessable entity response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity) WithPayload(payload *ghcmessages.ValidationError) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the acknowledge excess unaccompanied baggage weight risk unprocessable entity response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity) SetPayload(payload *ghcmessages.ValidationError) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(422) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerErrorCode is the HTTP code returned for type AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError +const AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerErrorCode int = 500 + +/* +AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError A server error occurred + +swagger:response acknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError +*/ +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError struct { + + /* + In: Body + */ + Payload *ghcmessages.Error `json:"body,omitempty"` +} + +// NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError creates AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError with default headers values +func NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError() *AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError { + + return &AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError{} +} + +// WithPayload adds the payload to the acknowledge excess unaccompanied baggage weight risk internal server error response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError) WithPayload(payload *ghcmessages.Error) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the acknowledge excess unaccompanied baggage weight risk internal server error response +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError) SetPayload(payload *ghcmessages.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(500) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_urlbuilder.go b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_urlbuilder.go new file mode 100644 index 00000000000..4cd575b01eb --- /dev/null +++ b/pkg/gen/ghcapi/ghcoperations/order/acknowledge_excess_unaccompanied_baggage_weight_risk_urlbuilder.go @@ -0,0 +1,101 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package order + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" + + "github.com/go-openapi/strfmt" +) + +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL generates an URL for the acknowledge excess unaccompanied baggage weight risk operation +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL struct { + OrderID strfmt.UUID + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) WithBasePath(bp string) *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk" + + orderID := o.OrderID.String() + if orderID != "" { + _path = strings.Replace(_path, "{orderID}", orderID, -1) + } else { + return nil, errors.New("orderId is required on AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/ghc/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *AcknowledgeExcessUnaccompaniedBaggageWeightRiskURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/pkg/handlers/ghcapi/api.go b/pkg/handlers/ghcapi/api.go index 1e6d7fcb11c..a18bee96258 100644 --- a/pkg/handlers/ghcapi/api.go +++ b/pkg/handlers/ghcapi/api.go @@ -341,6 +341,11 @@ func NewGhcAPIHandler(handlerConfig handlers.HandlerConfig) *ghcops.MymoveAPI { order.NewExcessWeightRiskManager(moveRouter), } + ghcAPI.OrderAcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler = AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler{ + handlerConfig, + order.NewExcessWeightRiskManager(moveRouter), + } + ghcAPI.MoveTaskOrderUpdateMoveTaskOrderStatusHandler = UpdateMoveTaskOrderStatusHandlerFunc{ handlerConfig, moveTaskOrderUpdater, diff --git a/pkg/handlers/ghcapi/orders.go b/pkg/handlers/ghcapi/orders.go index ff1c47a9569..670d36d1ee8 100644 --- a/pkg/handlers/ghcapi/orders.go +++ b/pkg/handlers/ghcapi/orders.go @@ -582,6 +582,59 @@ type AcknowledgeExcessWeightRiskHandler struct { excessWeightRiskManager services.ExcessWeightRiskManager } +// AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler is called when a TOO dismissed the alert to acknowledge the excess unaccompanied baggage weight risk via POST /orders/{orderId}/acknowledge-excess-unaccompanied-baggage-weight-risk +type AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler struct { + handlers.HandlerConfig + excessWeightRiskManager services.ExcessWeightRiskManager +} + +// Handles acknowledging excess unaccompanied baggage weight +func (h AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler) Handle( + params orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams, +) middleware.Responder { + return h.AuditableAppContextFromRequestWithErrors(params.HTTPRequest, + func(appCtx appcontext.AppContext) (middleware.Responder, error) { + + // handleError is a reusable function to deal with multiple errors + // when it comes to updating orders. + handleError := func(err error) (middleware.Responder, error) { + appCtx.Logger().Error("error acknowledging excess unaccompanied baggage weight risk", zap.Error(err)) + switch e := err.(type) { + case apperror.NotFoundError: + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound(), err + case apperror.InvalidInputError: + payload := payloadForValidationError(handlers.ValidationErrMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest), e.ValidationErrors) + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity().WithPayload(payload), err + case apperror.PreconditionFailedError: + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed().WithPayload(&ghcmessages.Error{Message: handlers.FmtString(err.Error())}), err + case apperror.ForbiddenError: + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskForbidden().WithPayload(&ghcmessages.Error{Message: handlers.FmtString(err.Error())}), err + default: + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError(), err + } + } + + orderID := uuid.FromStringOrNil(params.OrderID.String()) + updatedMove, err := h.excessWeightRiskManager.AcknowledgeExcessUnaccompaniedBaggageWeightRisk( + appCtx, + orderID, + params.IfMatch, + ) + if err != nil { + return handleError(err) + } + + h.triggerAcknowledgeExcessUnaccompaniedBaggageWeightRiskEvent(appCtx, updatedMove.ID, params) + + movePayload, err := payloads.Move(updatedMove, h.FileStorer()) + if err != nil { + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskInternalServerError(), err + } + + return orderop.NewAcknowledgeExcessUnaccompaniedBaggageWeightRiskOK().WithPayload(movePayload), nil + }) +} + // Handle ... updates the authorized weight func (h AcknowledgeExcessWeightRiskHandler) Handle( params orderop.AcknowledgeExcessWeightRiskParams, @@ -777,6 +830,26 @@ func (h AcknowledgeExcessWeightRiskHandler) triggerAcknowledgeExcessWeightRiskEv } } +func (h AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler) triggerAcknowledgeExcessUnaccompaniedBaggageWeightRiskEvent( + appCtx appcontext.AppContext, + moveID uuid.UUID, + params orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams, +) { + _, err := event.TriggerEvent(event.Event{ + EndpointKey: event.GhcAcknowledgeExcessUnaccompaniedBaggageWeightRiskEndpointKey, + // Endpoint that is being handled + EventKey: event.MoveTaskOrderUpdateEventKey, // Event that you want to trigger + UpdatedObjectID: moveID, // ID of the updated logical object + MtoID: moveID, // ID of the associated Move + AppContext: appCtx, + TraceID: h.GetTraceIDFromRequest(params.HTTPRequest), + }) + // If the event trigger fails, just log the error. + if err != nil { + appCtx.Logger().Error("ghcapi.acknowledgeUnaccompaniedBaggageExcessWeightRisk could not generate the event") + } +} + func PayloadForOrdersModel(order models.Order) (*ghcmessages.OrderBody, error) { payload := &ghcmessages.OrderBody{ ID: *handlers.FmtUUID(order.ID), diff --git a/pkg/handlers/ghcapi/orders_test.go b/pkg/handlers/ghcapi/orders_test.go index 93fdc901600..4e8f4606a43 100644 --- a/pkg/handlers/ghcapi/orders_test.go +++ b/pkg/handlers/ghcapi/orders_test.go @@ -2179,6 +2179,179 @@ func (suite *HandlerSuite) TestAcknowledgeExcessWeightRiskHandler() { }) } +func (suite *HandlerSuite) TestAcknowledgeUnaccompaniedBaggageExcessWeightRiskHandler() { + request := httptest.NewRequest("POST", "/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk", nil) + + suite.Run("Returns 200 when all validations pass", func() { + handlerConfig := suite.HandlerConfig() + now := time.Now() + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }, + }, nil) + order := move.Orders + + requestUser := factory.BuildOfficeUserWithRoles(nil, nil, []roles.RoleType{roles.RoleTypeTOO, roles.RoleTypeTIO, roles.RoleTypeServicesCounselor}) + request = suite.AuthenticateOfficeRequest(request, requestUser) + + params := orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams{ + HTTPRequest: request, + OrderID: strfmt.UUID(order.ID.String()), + IfMatch: etag.GenerateEtag(move.UpdatedAt), + } + + router := moverouter.NewMoveRouter() + handler := AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler{ + handlerConfig, + orderservice.NewExcessWeightRiskManager(router), + } + + // Validate incoming payload: no body to validate + + response := handler.Handle(params) + + suite.IsNotErrResponse(response) + suite.IsType(&orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK{}, response) + moveOK := response.(*orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskOK) + movePayload := moveOK.Payload + + // Validate outgoing payload + suite.NoError(movePayload.Validate(strfmt.Default)) + + suite.Equal(move.ID.String(), movePayload.ID.String()) + suite.NotNil(movePayload.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) + }) + + suite.Run("Returns 404 when updater returns NotFoundError", func() { + handlerConfig := suite.HandlerConfig() + now := time.Now() + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }, + }, nil) + order := move.Orders + + requestUser := factory.BuildOfficeUserWithRoles(nil, nil, []roles.RoleType{roles.RoleTypeTOO}) + request = suite.AuthenticateOfficeRequest(request, requestUser) + + params := orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams{ + HTTPRequest: request, + OrderID: strfmt.UUID(order.ID.String()), + IfMatch: etag.GenerateEtag(order.UpdatedAt), + } + + updater := &mocks.ExcessWeightRiskManager{} + handler := AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler{ + handlerConfig, + updater, + } + + updater.On("AcknowledgeExcessUnaccompaniedBaggageWeightRisk", mock.AnythingOfType("*appcontext.appContext"), + order.ID, params.IfMatch).Return(nil, apperror.NotFoundError{}) + + // Validate incoming payload: no body to validate + + response := handler.Handle(params) + + suite.IsType(&orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound{}, response) + payload := response.(*orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskNotFound).Payload + + // Validate outgoing payload: nil payload + suite.Nil(payload) + }) + + suite.Run("Returns 412 when eTag does not match", func() { + handlerConfig := suite.HandlerConfig() + now := time.Now() + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }, + }, nil) + order := move.Orders + + requestUser := factory.BuildOfficeUserWithRoles(nil, nil, []roles.RoleType{roles.RoleTypeTOO}) + request = suite.AuthenticateOfficeRequest(request, requestUser) + + params := orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams{ + HTTPRequest: request, + OrderID: strfmt.UUID(order.ID.String()), + IfMatch: "", + } + + updater := &mocks.ExcessWeightRiskManager{} + handler := AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler{ + handlerConfig, + updater, + } + + updater.On("AcknowledgeExcessUnaccompaniedBaggageWeightRisk", mock.AnythingOfType("*appcontext.appContext"), + order.ID, params.IfMatch).Return(nil, apperror.PreconditionFailedError{}) + + // Validate incoming payload: no body to validate + + response := handler.Handle(params) + + suite.IsType(&orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed{}, response) + payload := response.(*orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskPreconditionFailed).Payload + + // Validate outgoing payload + suite.NoError(payload.Validate(strfmt.Default)) + }) + + suite.Run("Returns 422 when updater service returns validation errors", func() { + handlerConfig := suite.HandlerConfig() + now := time.Now() + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }, + }, nil) + order := move.Orders + + requestUser := factory.BuildOfficeUserWithRoles(nil, nil, []roles.RoleType{roles.RoleTypeTOO}) + request = suite.AuthenticateOfficeRequest(request, requestUser) + + params := orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskParams{ + HTTPRequest: request, + OrderID: strfmt.UUID(order.ID.String()), + IfMatch: etag.GenerateEtag(order.UpdatedAt), + } + + updater := &mocks.ExcessWeightRiskManager{} + handler := AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler{ + handlerConfig, + updater, + } + + verrs := validate.NewErrors() + verrs.Add("some key", "some validation error") + invalidInputError := apperror.NewInvalidInputError(order.ID, nil, verrs, "") + updater.On("AcknowledgeExcessUnaccompaniedBaggageWeightRisk", mock.AnythingOfType("*appcontext.appContext"), + order.ID, params.IfMatch).Return(nil, invalidInputError) + + // Validate incoming payload: no body to validate + + response := handler.Handle(params) + + suite.IsType(&orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity{}, response) + payload := response.(*orderop.AcknowledgeExcessUnaccompaniedBaggageWeightRiskUnprocessableEntity).Payload + + // Validate outgoing payload + suite.NoError(payload.Validate(strfmt.Default)) + }) +} + // Test that an order notification got stored successfully func (suite *HandlerSuite) TestAcknowledgeExcessWeightRiskEventTrigger() { now := time.Now() diff --git a/pkg/services/event/ghc_endpoint.go b/pkg/services/event/ghc_endpoint.go index 78f3c192ab3..d24e480a02e 100644 --- a/pkg/services/event/ghc_endpoint.go +++ b/pkg/services/event/ghc_endpoint.go @@ -127,6 +127,9 @@ const GhcUpdateMaxBillableWeightAsTIOEndpointKey = "Ghc.UpdateMaxBillableWeightA // GhcAcknowledgeExcessWeightRiskEndpointKey is the key for the AcknowledgeExcessWeightRisk endpoint in ghc const GhcAcknowledgeExcessWeightRiskEndpointKey = "Ghc.AcknowledgeExcessWeightRisk" +// GhcAcknowledgeExcessUnaccompaniedBaggageWeightRiskEndpointKey is the key for the AcknowledgeExcessUnaccompaniedBaggageWeightRisk endpoint in ghc +const GhcAcknowledgeExcessUnaccompaniedBaggageWeightRiskEndpointKey = "Ghc.GhcAcknowledgeExcessUnaccompaniedBaggageWeightRiskEndpointKey" + // -------------------- ENDPOINT MAP ENTRIES -------------------- var ghcEndpoints = EndpointMapType{ GhcGetCustomerEndpointKey: { @@ -285,4 +288,8 @@ var ghcEndpoints = EndpointMapType{ APIName: GhcAPIName, OperationID: "AcknowledgeExcessWeightRisk", }, + GhcAcknowledgeExcessUnaccompaniedBaggageWeightRiskEndpointKey: { + APIName: GhcAPIName, + OperationID: "AcknowledgeExcessUnaccompaniedBaggageWeightRisk", + }, } diff --git a/pkg/services/mocks/ExcessWeightRiskManager.go b/pkg/services/mocks/ExcessWeightRiskManager.go index aad764a01cd..40f0db01a01 100644 --- a/pkg/services/mocks/ExcessWeightRiskManager.go +++ b/pkg/services/mocks/ExcessWeightRiskManager.go @@ -16,6 +16,36 @@ type ExcessWeightRiskManager struct { mock.Mock } +// AcknowledgeExcessUnaccompaniedBaggageWeightRisk provides a mock function with given fields: appCtx, moveID, eTag +func (_m *ExcessWeightRiskManager) AcknowledgeExcessUnaccompaniedBaggageWeightRisk(appCtx appcontext.AppContext, moveID uuid.UUID, eTag string) (*models.Move, error) { + ret := _m.Called(appCtx, moveID, eTag) + + if len(ret) == 0 { + panic("no return value specified for AcknowledgeExcessUnaccompaniedBaggageWeightRisk") + } + + var r0 *models.Move + var r1 error + if rf, ok := ret.Get(0).(func(appcontext.AppContext, uuid.UUID, string) (*models.Move, error)); ok { + return rf(appCtx, moveID, eTag) + } + if rf, ok := ret.Get(0).(func(appcontext.AppContext, uuid.UUID, string) *models.Move); ok { + r0 = rf(appCtx, moveID, eTag) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*models.Move) + } + } + + if rf, ok := ret.Get(1).(func(appcontext.AppContext, uuid.UUID, string) error); ok { + r1 = rf(appCtx, moveID, eTag) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // AcknowledgeExcessWeightRisk provides a mock function with given fields: appCtx, moveID, eTag func (_m *ExcessWeightRiskManager) AcknowledgeExcessWeightRisk(appCtx appcontext.AppContext, moveID uuid.UUID, eTag string) (*models.Move, error) { ret := _m.Called(appCtx, moveID, eTag) diff --git a/pkg/services/order.go b/pkg/services/order.go index 4f33f6f1a23..c1bd25d1b84 100644 --- a/pkg/services/order.go +++ b/pkg/services/order.go @@ -40,6 +40,7 @@ type OrderUpdater interface { //go:generate mockery --name ExcessWeightRiskManager type ExcessWeightRiskManager interface { AcknowledgeExcessWeightRisk(appCtx appcontext.AppContext, moveID uuid.UUID, eTag string) (*models.Move, error) + AcknowledgeExcessUnaccompaniedBaggageWeightRisk(appCtx appcontext.AppContext, moveID uuid.UUID, eTag string) (*models.Move, error) UpdateBillableWeightAsTOO(appCtx appcontext.AppContext, orderID uuid.UUID, weight *int, eTag string) (*models.Order, uuid.UUID, error) UpdateMaxBillableWeightAsTIO(appCtx appcontext.AppContext, orderID uuid.UUID, weight *int, remarks *string, eTag string) (*models.Order, uuid.UUID, error) } diff --git a/pkg/services/order/excess_weight_risk_manager.go b/pkg/services/order/excess_weight_risk_manager.go index 47a9a278edd..bbf605ad9c5 100644 --- a/pkg/services/order/excess_weight_risk_manager.go +++ b/pkg/services/order/excess_weight_risk_manager.go @@ -68,7 +68,24 @@ func (f *excessWeightRiskManager) AcknowledgeExcessWeightRisk(appCtx appcontext. return &models.Move{}, apperror.NewPreconditionFailedError(move.ID, query.StaleIdentifierError{StaleIdentifier: eTag}) } - return f.acknowledgeRiskAndApproveMove(appCtx, *order) + return f.acknowledgeRiskAndApproveMove(appCtx, *order, false) +} + +// AcknowledgeExcessUnaccompaniedBaggageWeightRisk records the date and time the TOO dismissed the excess unaccompanied baggage weight risk notification +func (f *excessWeightRiskManager) AcknowledgeExcessUnaccompaniedBaggageWeightRisk(appCtx appcontext.AppContext, orderID uuid.UUID, eTag string) (*models.Move, error) { + order, err := f.findOrder(appCtx, orderID) + if err != nil { + return &models.Move{}, err + } + + move := order.Moves[0] + + existingETag := etag.GenerateEtag(move.UpdatedAt) + if existingETag != eTag { + return &models.Move{}, apperror.NewPreconditionFailedError(move.ID, query.StaleIdentifierError{StaleIdentifier: eTag}) + } + + return f.acknowledgeRiskAndApproveMove(appCtx, *order, true) } func (f *excessWeightRiskManager) findOrder(appCtx appcontext.AppContext, orderID uuid.UUID) (*models.Order, error) { @@ -87,12 +104,12 @@ func (f *excessWeightRiskManager) findOrder(appCtx appcontext.AppContext, orderI return &order, nil } -func (f *excessWeightRiskManager) acknowledgeRiskAndApproveMove(appCtx appcontext.AppContext, order models.Order) (*models.Move, error) { +func (f *excessWeightRiskManager) acknowledgeRiskAndApproveMove(appCtx appcontext.AppContext, order models.Order, isAcknowledgingUbExcessWeightRisk bool) (*models.Move, error) { move := order.Moves[0] var returnedMove *models.Move transactionError := appCtx.NewTransaction(func(txnAppCtx appcontext.AppContext) error { - updatedMove, err := f.acknowledgeExcessWeight(txnAppCtx, move) + updatedMove, err := f.acknowledgeExcessWeight(txnAppCtx, move, isAcknowledgingUbExcessWeightRisk) if err != nil { return err } @@ -124,7 +141,10 @@ func (f *excessWeightRiskManager) updateBillableWeight(appCtx appcontext.AppCont return err } - updatedMove, err := f.acknowledgeExcessWeight(txnAppCtx, move) + // Acknowledge excess weight for the overall move + // unaccompanied baggage is never affected by billable weight updates as it is + // a separate, immutable allowance + updatedMove, err := f.acknowledgeExcessWeight(txnAppCtx, move, false) if err != nil { return err } @@ -161,7 +181,9 @@ func (f *excessWeightRiskManager) updateMaxBillableWeightWithTIORemarks(appCtx a return err } - updatedMove, err = f.acknowledgeExcessWeight(txnAppCtx, *updatedMove) + // Unaccompanied baggage is never affected by billable weight updates as it is + // a separate, immutable allowance + updatedMove, err = f.acknowledgeExcessWeight(txnAppCtx, *updatedMove, false) if err != nil { return err } @@ -199,16 +221,32 @@ func (f *excessWeightRiskManager) updateAuthorizedWeight(appCtx appcontext.AppCo return f.handleError(order.ID, verrs, err) } -func (f *excessWeightRiskManager) acknowledgeExcessWeight(appCtx appcontext.AppContext, move models.Move) (*models.Move, error) { - if !excessWeightRiskShouldBeAcknowledged(move) { - return &move, nil - } - - now := time.Now() - move.ExcessWeightAcknowledgedAt = &now - verrs, err := appCtx.DB().ValidateAndUpdate(&move) - if e := f.handleError(move.ID, verrs, err); e != nil { - return &move, e +func (f *excessWeightRiskManager) acknowledgeExcessWeight(appCtx appcontext.AppContext, move models.Move, isAcknowledgingUbExcessWeightRisk bool) (*models.Move, error) { + // Separately handle whether the excess weight being acknowledged is for the entire move allowance or just the unaccompanied baggage allowance + if isAcknowledgingUbExcessWeightRisk { + // Make sure it should be acknowledgeable + if !excessUnaccompaniedBaggageWeightRiskShouldBeAcknowledged(move) { + return &move, nil + } + // Acknowledge it + now := time.Now() + move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt = &now + verrs, err := appCtx.DB().ValidateAndUpdate(&move) + if e := f.handleError(move.ID, verrs, err); e != nil { + return &move, e + } + } else { + // Make sure it should be acknowledgeable + if !excessWeightRiskShouldBeAcknowledged(move) { + return &move, nil + } + // Acknowledge it + now := time.Now() + move.ExcessWeightAcknowledgedAt = &now + verrs, err := appCtx.DB().ValidateAndUpdate(&move) + if e := f.handleError(move.ID, verrs, err); e != nil { + return &move, e + } } return &move, nil @@ -228,3 +266,7 @@ func (f *excessWeightRiskManager) handleError(modelID uuid.UUID, verrs *validate func excessWeightRiskShouldBeAcknowledged(move models.Move) bool { return move.ExcessWeightQualifiedAt != nil && move.ExcessWeightAcknowledgedAt == nil } + +func excessUnaccompaniedBaggageWeightRiskShouldBeAcknowledged(move models.Move) bool { + return move.ExcessUnaccompaniedBaggageWeightQualifiedAt != nil && move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt == nil +} diff --git a/pkg/services/order/excess_weight_risk_manager_test.go b/pkg/services/order/excess_weight_risk_manager_test.go index ad67a0d80b5..c7c81e58f86 100644 --- a/pkg/services/order/excess_weight_risk_manager_test.go +++ b/pkg/services/order/excess_weight_risk_manager_test.go @@ -549,6 +549,34 @@ func (suite *OrderServiceSuite) TestAcknowledgeExcessWeightRisk() { suite.NotNil(moveInDB.ExcessWeightAcknowledgedAt) }) + suite.Run("Updates the ExcessUnaccompaniedBaggageWeightAcknowledgedAt field and approves the move when all fields are valid", func() { + moveRouter := moverouter.NewMoveRouter() + excessWeightRiskManager := NewExcessWeightRiskManager(moveRouter) + now := time.Now() + move := factory.BuildApprovalsRequestedMove(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + ExcessUnaccompaniedBaggageWeightQualifiedAt: &now, + }, + }, + }, nil) + order := move.Orders + eTag := etag.GenerateEtag(move.UpdatedAt) + + updatedMove, err := excessWeightRiskManager.AcknowledgeExcessUnaccompaniedBaggageWeightRisk(suite.AppContextForTest(), order.ID, eTag) + suite.NoError(err) + + var moveInDB models.Move + err = suite.DB().Find(&moveInDB, move.ID) + suite.NoError(err) + + suite.Equal(move.ID.String(), updatedMove.ID.String()) + suite.Equal(models.MoveStatusAPPROVED, moveInDB.Status) + suite.Equal(models.MoveStatusAPPROVED, updatedMove.Status) + suite.NotNil(moveInDB.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) + suite.NotNil(updatedMove.ExcessUnaccompaniedBaggageWeightAcknowledgedAt) + }) + suite.Run("Updates the ExcessWeightAcknowledgedAt field but does not approve the move if unreviewed service items exist", func() { moveRouter := moverouter.NewMoveRouter() excessWeightRiskManager := NewExcessWeightRiskManager(moveRouter) diff --git a/src/services/ghcApi.js b/src/services/ghcApi.js index d4d8f3e763a..e4c25885379 100644 --- a/src/services/ghcApi.js +++ b/src/services/ghcApi.js @@ -399,6 +399,11 @@ export async function acknowledgeExcessWeightRisk({ orderID, ifMatchETag }) { return makeGHCRequest(operationPath, { orderID, 'If-Match': ifMatchETag }); } +export async function acknowledgeExcessUnaccompaniedBaggageWeightRisk({ orderID, ifMatchETag }) { + const operationPath = 'order.acknowledgeUnaccompaniedBaggageExcessWeightRisk'; + return makeGHCRequest(operationPath, { orderID, 'If-Match': ifMatchETag }); +} + export async function createCustomerWithOktaOption({ body }) { const operationPath = 'customer.createCustomerWithOktaOption'; return makeGHCRequest(operationPath, { body }); diff --git a/swagger-def/ghc.yaml b/swagger-def/ghc.yaml index 01fb4a4a313..4fc182b3c67 100644 --- a/swagger-def/ghc.yaml +++ b/swagger-def/ghc.yaml @@ -640,6 +640,46 @@ paths: $ref: '#/responses/ServerError' x-permissions: - update.excessWeightRisk + '/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk': + parameters: + - description: ID of order to use + in: path + name: orderID + required: true + type: string + format: uuid + post: + summary: Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert + description: Saves the date and time a TOO acknowledged the excess unaccompanied baggage weight risk by dismissing the alert + operationId: acknowledgeExcessUnaccompaniedBaggageWeightRisk + tags: + - order + consumes: + - application/json + produces: + - application/json + parameters: + - in: header + name: If-Match + type: string + required: true + responses: + '200': + description: updated Move + schema: + $ref: '#/definitions/Move' + '403': + $ref: '#/responses/PermissionDenied' + '404': + $ref: '#/responses/NotFound' + '412': + $ref: '#/responses/PreconditionFailed' + '422': + $ref: '#/responses/UnprocessableEntity' + '500': + $ref: '#/responses/ServerError' + x-permissions: + - update.excessWeightRisk '/orders/{orderID}/update-billable-weight': parameters: - description: ID of order to use diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index fd684bfc42a..560677a5e8a 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -685,6 +685,50 @@ paths: $ref: '#/responses/ServerError' x-permissions: - update.excessWeightRisk + /orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk: + parameters: + - description: ID of order to use + in: path + name: orderID + required: true + type: string + format: uuid + post: + summary: >- + Saves the date and time a TOO acknowledged the excess unaccompanied + baggage weight risk by dismissing the alert + description: >- + Saves the date and time a TOO acknowledged the excess unaccompanied + baggage weight risk by dismissing the alert + operationId: acknowledgeExcessUnaccompaniedBaggageWeightRisk + tags: + - order + consumes: + - application/json + produces: + - application/json + parameters: + - in: header + name: If-Match + type: string + required: true + responses: + '200': + description: updated Move + schema: + $ref: '#/definitions/Move' + '403': + $ref: '#/responses/PermissionDenied' + '404': + $ref: '#/responses/NotFound' + '412': + $ref: '#/responses/PreconditionFailed' + '422': + $ref: '#/responses/UnprocessableEntity' + '500': + $ref: '#/responses/ServerError' + x-permissions: + - update.excessWeightRisk /orders/{orderID}/update-billable-weight: parameters: - description: ID of order to use From 0350ccfca63f2c7ce52c13cee17a415ad7040386 Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Fri, 29 Nov 2024 21:04:30 +0000 Subject: [PATCH 10/35] ui alert and functional dismissal and move update --- pkg/handlers/ghcapi/orders.go | 2 +- pkg/handlers/ghcapi/orders_test.go | 2 +- .../Office/MoveTaskOrder/MoveTaskOrder.jsx | 88 ++++++++++++++++++- .../MoveTaskOrder/MoveTaskOrder.test.jsx | 20 +++++ .../moveTaskOrderUnitTestData.js | 58 ++++++++++++ src/services/ghcApi.js | 2 +- 6 files changed, 165 insertions(+), 7 deletions(-) diff --git a/pkg/handlers/ghcapi/orders.go b/pkg/handlers/ghcapi/orders.go index 670d36d1ee8..8b4ed516579 100644 --- a/pkg/handlers/ghcapi/orders.go +++ b/pkg/handlers/ghcapi/orders.go @@ -846,7 +846,7 @@ func (h AcknowledgeExcessUnaccompaniedBaggageWeightRiskHandler) triggerAcknowled }) // If the event trigger fails, just log the error. if err != nil { - appCtx.Logger().Error("ghcapi.acknowledgeUnaccompaniedBaggageExcessWeightRisk could not generate the event") + appCtx.Logger().Error("ghcapi.acknowledgeExcessUnaccompaniedBaggageWeightRisk could not generate the event") } } diff --git a/pkg/handlers/ghcapi/orders_test.go b/pkg/handlers/ghcapi/orders_test.go index 4e8f4606a43..f62f1edaf73 100644 --- a/pkg/handlers/ghcapi/orders_test.go +++ b/pkg/handlers/ghcapi/orders_test.go @@ -2179,7 +2179,7 @@ func (suite *HandlerSuite) TestAcknowledgeExcessWeightRiskHandler() { }) } -func (suite *HandlerSuite) TestAcknowledgeUnaccompaniedBaggageExcessWeightRiskHandler() { +func (suite *HandlerSuite) TestacknowledgeExcessUnaccompaniedBaggageWeightRiskHandler() { request := httptest.NewRequest("POST", "/orders/{orderID}/acknowledge-excess-unaccompanied-baggage-weight-risk", nil) suite.Run("Returns 200 when all validations pass", func() { diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx index e02b258a4ae..253a8275de1 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx @@ -33,6 +33,7 @@ import ServiceItemContainer from 'components/Office/ServiceItemContainer/Service import { useMoveTaskOrderQueries } from 'hooks/queries'; import { acknowledgeExcessWeightRisk, + acknowledgeExcessUnaccompaniedBaggageWeightRisk, approveSITExtension, denySITExtension, patchMTOServiceItemStatus, @@ -109,6 +110,7 @@ export const MoveTaskOrder = (props) => { const [alertMessage, setAlertMessage] = useState(null); const [alertType, setAlertType] = useState('success'); const [isSuccessAlertVisible, setIsSuccessAlertVisible] = useState(false); + const [isUnaccompaniedBaggageWeightAlertVisible, setIsUnaccompaniedBaggageWeightAlertVisible] = useState(false); const [isWeightAlertVisible, setIsWeightAlertVisible] = useState(false); const [isFinancialModalVisible, setIsFinancialModalVisible] = useState(false); /* ------------------ Selected / Active Item ------------------------- */ @@ -327,6 +329,18 @@ export const MoveTaskOrder = (props) => { }, }); + /* istanbul ignore next */ + const { mutate: mutateAcknowledgeExcessUnaccompaniedBaggageWeightRisk } = useMutation({ + mutationFn: acknowledgeExcessUnaccompaniedBaggageWeightRisk, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: [MOVES, move.locator] }); + }, + onError: (error) => { + const errorMsg = error?.response?.body; + milmoveLogger.error(errorMsg); + }, + }); + /* istanbul ignore next */ const { mutate: mutateSITExtensionApproval } = useMutation({ mutationFn: approveSITExtension, @@ -462,10 +476,18 @@ export const MoveTaskOrder = (props) => { const handleAcknowledgeExcessWeightRisk = () => { mutateAcknowledgeExcessWeightRisk({ orderID: order.id, ifMatchETag: move.eTag }); }; + // Handle unaccompanied baggage excess weight acknowledgement + const handleAcknowledgeExcessUnaccompaniedBaggageWeightRisk = () => { + mutateAcknowledgeExcessUnaccompaniedBaggageWeightRisk({ orderID: order.id, ifMatchETag: move.eTag }); + }; const handleHideWeightAlert = () => { handleAcknowledgeExcessWeightRisk(); setIsWeightAlertVisible(false); }; + const handleHideUnaccompaniedBaggageWeightAlert = () => { + handleAcknowledgeExcessUnaccompaniedBaggageWeightRisk(); + setIsUnaccompaniedBaggageWeightAlertVisible(false); + }; const handleShowWeightModal = () => { handleHideWeightAlert(); @@ -842,20 +864,39 @@ export const MoveTaskOrder = (props) => { setEstimatedPPMWeightTotal(calculateEstimatedWeight(onlyPPMShipments)); let excessBillableWeightCount = 0; const riskOfExcessAcknowledged = !!move?.excess_weight_acknowledged_at; + const riskOfExcessUnaccompaniedBaggageAcknowledged = !!move?.excessUnaccompaniedBaggageWeightAcknowledgedAt; + const riskOfExcessUnaccompaniedBaggageQualifiedAt = !!move?.excessUnaccompaniedBaggageWeightQualifiedAt; + const qualifiedAfterAcknowledged = + move?.excessUnaccompaniedBaggageWeightQualifiedAt && + move?.excessUnaccompaniedBaggageWeightAcknowledgedAt && + new Date(move.excessUnaccompaniedBaggageWeightQualifiedAt) > + new Date(move.excessUnaccompaniedBaggageWeightAcknowledgedAt); if (hasRiskOfExcess(estimatedWeightTotal, order?.entitlement.totalWeight) && !riskOfExcessAcknowledged) { - excessBillableWeightCount = 1; - setExcessWeightRiskCount(1); - } else { - setExcessWeightRiskCount(0); + excessBillableWeightCount += 1; } const showWeightAlert = !riskOfExcessAcknowledged && !!excessBillableWeightCount; + // Make sure that the risk of UB is NOT acknowledged AND that it is qualified before showing the alert + // Also, if the timestamp of acknowledgement is BEFORE its qualified timestamp, then we should show the alert + const showUnaccompaniedBaggageWeightAlert = + !riskOfExcessUnaccompaniedBaggageAcknowledged && + riskOfExcessUnaccompaniedBaggageQualifiedAt && + (!riskOfExcessUnaccompaniedBaggageAcknowledged || qualifiedAfterAcknowledged); + + if (showUnaccompaniedBaggageWeightAlert) { + excessBillableWeightCount += 1; + } + + setExcessWeightRiskCount(excessBillableWeightCount); setIsWeightAlertVisible(showWeightAlert); + setIsUnaccompaniedBaggageWeightAlertVisible(showUnaccompaniedBaggageWeightAlert); }, [ estimatedWeightTotal, move?.excess_weight_acknowledged_at, + move?.excessUnaccompaniedBaggageWeightAcknowledgedAt, + move?.excessUnaccompaniedBaggageWeightQualifiedAt, nonPPMShipments, onlyPPMShipments, order?.entitlement.totalWeight, @@ -993,6 +1034,17 @@ export const MoveTaskOrder = (props) => { ); + const excessUnaccompaniedBaggageWeightAlertControl = ( + + ); return (
@@ -1070,6 +1122,34 @@ export const MoveTaskOrder = (props) => { )} + {isUnaccompaniedBaggageWeightAlertVisible && ( + + + This move is at risk for exceeding unaccompanied baggage weight allowance.{' '} + + + + + + + + + + )} {isSuccessAlertVisible && ( Your changes were saved diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx index 0f114276dc1..ed6949d4d01 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx @@ -18,6 +18,7 @@ import { sitExtensionApproved, allApprovedExternalVendorMTOQuery, riskOfExcessWeightQueryExternalShipment, + riskOfExcessWeightQueryExternalUBShipment, multiplePaymentRequests, moveHistoryTestData, actualPPMWeightQuery, @@ -285,6 +286,25 @@ describe('MoveTaskOrder', () => { expect(riskOfExcessTag).toBeInTheDocument(); }); + it('displays risk of excess unaccompanied baggage tag when a move has excess ub shipment weight', async () => { + useMoveTaskOrderQueries.mockReturnValue(riskOfExcessWeightQueryExternalUBShipment); + + render( + + + , + ); + + const acknowledgeUbExcessButton = await screen.findByTestId(/acknowledgeExcessUnaccompaniedBaggageWeightBtn/); + expect(acknowledgeUbExcessButton).toBeInTheDocument(); + }); + it('displays the estimated total weight', async () => { useMoveTaskOrderQueries.mockReturnValue(allApprovedMTOQuery); diff --git a/src/pages/Office/MoveTaskOrder/moveTaskOrderUnitTestData.js b/src/pages/Office/MoveTaskOrder/moveTaskOrderUnitTestData.js index c207dfd2ef0..0e5bca623a6 100644 --- a/src/pages/Office/MoveTaskOrder/moveTaskOrderUnitTestData.js +++ b/src/pages/Office/MoveTaskOrder/moveTaskOrderUnitTestData.js @@ -1166,6 +1166,64 @@ export const riskOfExcessWeightQuery = { ], }; +export const riskOfExcessWeightQueryExternalUBShipment = { + ...allApprovedExternalVendorMTOQuery, + orders: { + 1: { + id: '1', + originDutyLocation: { + address: { + streetAddress1: '', + city: 'Fort Knox', + state: 'KY', + postalCode: '40121', + isOconus: true, + }, + }, + destinationDutyLocation: { + address: { + streetAddress1: '', + city: 'Fort Irwin', + state: 'CA', + postalCode: '92310', + }, + }, + entitlement: { + authorizedWeight: 100, + totalWeight: 100, + unaccompaniedBaggageAllowance: 2000, + }, + }, + }, + mtoShipments: [ + { + id: '1', + moveTaskOrderID: '2', + shipmentType: SHIPMENT_OPTIONS.UNACCOMPANIED_BAGGAGE, + scheduledPickupDate: '2020-03-16', + requestedPickupDate: '2020-03-15', + pickupAddress: { + streetAddress1: '932 Baltic Avenue', + city: 'Chicago', + state: 'IL', + postalCode: '60601', + }, + destinationAddress: { + streetAddress1: '10 Park Place', + city: 'Atlantic City', + state: 'NJ', + postalCode: '08401', + }, + status: 'APPROVED', + eTag: '1234', + primeEstimatedWeight: 1850, + primeActualWeight: 1841, + sitExtensions: [], + sitStatus: SITStatusOrigin, + }, + ], +}; + export const riskOfExcessWeightQueryExternalShipment = { ...allApprovedExternalVendorMTOQuery, orders: { diff --git a/src/services/ghcApi.js b/src/services/ghcApi.js index e4c25885379..3d13f91cc0f 100644 --- a/src/services/ghcApi.js +++ b/src/services/ghcApi.js @@ -400,7 +400,7 @@ export async function acknowledgeExcessWeightRisk({ orderID, ifMatchETag }) { } export async function acknowledgeExcessUnaccompaniedBaggageWeightRisk({ orderID, ifMatchETag }) { - const operationPath = 'order.acknowledgeUnaccompaniedBaggageExcessWeightRisk'; + const operationPath = 'order.acknowledgeExcessUnaccompaniedBaggageWeightRisk'; return makeGHCRequest(operationPath, { orderID, 'If-Match': ifMatchETag }); } From 952a6c834d8ea7cb1060afec2d67798685e5d045 Mon Sep 17 00:00:00 2001 From: cameroncaci Date: Mon, 2 Dec 2024 16:16:09 +0000 Subject: [PATCH 11/35] Added move history support for excess ub weight acknowledgement by too --- ...geExcessUnaccompaniedBaggageWeightRisk.jsx | 19 ++++++++++ ...essUnaccompaniedBaggageWeightRisk.test.jsx | 37 +++++++++++++++++++ .../MoveHistory/EventTemplates/index.js | 1 + .../MoveHistory/UIDisplay/Operations.js | 1 + 4 files changed, 58 insertions(+) create mode 100644 src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.jsx create mode 100644 src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.test.jsx diff --git a/src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.jsx b/src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.jsx new file mode 100644 index 00000000000..a7da5ef2b64 --- /dev/null +++ b/src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.jsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import a from 'constants/MoveHistory/Database/Actions'; +import o from 'constants/MoveHistory/UIDisplay/Operations'; +import t from 'constants/MoveHistory/Database/Tables'; +import LabeledDetails from 'pages/Office/MoveHistory/LabeledDetails'; + +export default { + action: a.UPDATE, + eventName: o.acknowledgeExcessUnaccompaniedBaggageWeightRisk, + tableName: t.moves, + getEventNameDisplay: () => 'Updated move', + getDetails: (historyRecord) => { + if (historyRecord?.changedValues?.excess_unaccompanied_baggage_weight_acknowledged_at) { + return 'Dismissed excess unaccompanied baggage weight alert'; + } + return ; + }, +}; diff --git a/src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.test.jsx b/src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.test.jsx new file mode 100644 index 00000000000..373c801807e --- /dev/null +++ b/src/constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk.test.jsx @@ -0,0 +1,37 @@ +import { render, screen } from '@testing-library/react'; + +import getTemplate from 'constants/MoveHistory/TemplateManager'; +import e from 'constants/MoveHistory/EventTemplates/AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk'; + +describe('when given an Acknowledge excess unaccompanied baggage weight risk history record', () => { + const historyRecord = { + action: 'UPDATE', + eventName: 'acknowledgeExcessUnaccompaniedBaggageWeightRisk', + tableName: 'moves', + }; + + it('correctly matches the Acknowledge excess unaccompanied baggage weight risk template', () => { + const result = getTemplate(historyRecord); + expect(result).toMatchObject(e); + }); + it('renders the default details in the details column when excess risk key is not present ', () => { + const newHistoryRecord = { + ...historyRecord, + changedValues: { status: 'APPROVED' }, + }; + const template = getTemplate(newHistoryRecord); + render(template.getDetails(newHistoryRecord)); + expect(screen.getByText('Status')).toBeInTheDocument(); + expect(screen.getByText(': APPROVED')).toBeInTheDocument(); + }); + + it('renders the proper message in the details column when excess_unaccompanied_baggage_weight_acknowledged_at is present ', () => { + const newHistoryRecordAcknowledged = { + ...historyRecord, + changedValues: { excess_unaccompanied_baggage_weight_acknowledged_at: 'this would usually be a time value' }, + }; + const template = getTemplate(newHistoryRecordAcknowledged); + render(template.getDetails(newHistoryRecordAcknowledged)); + expect(screen.getByText('Dismissed excess unaccompanied baggage weight alert')).toBeInTheDocument(); + }); +}); diff --git a/src/constants/MoveHistory/EventTemplates/index.js b/src/constants/MoveHistory/EventTemplates/index.js index 42ac00d51c7..fca0dc83d5e 100644 --- a/src/constants/MoveHistory/EventTemplates/index.js +++ b/src/constants/MoveHistory/EventTemplates/index.js @@ -1,4 +1,5 @@ export { default as acknowledgeExcessWeightRisk } from './AcknowledgeExcessWeightRisk/acknowledgeExcessWeightRisk'; +export { default as acknowledgeExcessUnaccompaniedBaggageWeightRisk } from './AcknowledgeExcessUnaccompaniedBaggageWeightRisk/acknowledgeExcessUnaccompaniedBaggageWeightRisk'; export { default as approveShipment } from './ApproveShipment/approveShipment'; export { default as approveShipmentDiversion } from './ApproveShipmentDiversion/approveShipmentDiversion'; export { default as createBasicServiceItem } from './UpdateMoveTaskOrderStatus/createBasicServiceItem'; diff --git a/src/constants/MoveHistory/UIDisplay/Operations.js b/src/constants/MoveHistory/UIDisplay/Operations.js index 8ca4a3f5cd0..9e495ba55f5 100644 --- a/src/constants/MoveHistory/UIDisplay/Operations.js +++ b/src/constants/MoveHistory/UIDisplay/Operations.js @@ -1,5 +1,6 @@ export default { acknowledgeExcessWeightRisk: 'acknowledgeExcessWeightRisk', + acknowledgeExcessUnaccompaniedBaggageWeightRisk: 'acknowledgeExcessUnaccompaniedBaggageWeightRisk', approveShipment: 'approveShipment', // ghc.yaml approveShipmentDiversion: 'approveShipmentDiversion', counselingUpdateAllowance: 'counselingUpdateAllowance', // ghc.yaml From d0ea6eb367580f028713c0ab265bc6c8ba1aec21 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Mon, 2 Dec 2024 17:28:40 +0000 Subject: [PATCH 12/35] Fixing MTOTaskOrder Test --- src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx | 1 - src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx | 2 +- src/pages/Office/MoveTaskOrder/moveTaskOrderUnitTestData.js | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx index 253a8275de1..c1e8c1124cd 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx @@ -1136,7 +1136,6 @@ export const MoveTaskOrder = (props) => { ); From 069a97df2547b04dcea9dbf88e33c9e5b87303a2 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Tue, 3 Dec 2024 21:55:12 +0000 Subject: [PATCH 20/35] Send move to approvals requested on excess weight --- pkg/services/mto_shipment/mto_shipment_updater.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/services/mto_shipment/mto_shipment_updater.go b/pkg/services/mto_shipment/mto_shipment_updater.go index 92ca8ba58c8..457234947ac 100644 --- a/pkg/services/mto_shipment/mto_shipment_updater.go +++ b/pkg/services/mto_shipment/mto_shipment_updater.go @@ -752,7 +752,7 @@ func (f *mtoShipmentUpdater) updateShipmentRecord(appCtx appcontext.AppContext, existingMoveStatus := move.Status // if the move is in excess weight risk and the TOO has not acknowledge that, need to change move status to "Approvals Requested" // this will trigger the TOO to acknowledged the excess right, which populates ExcessWeightAcknowledgedAt - if move.ExcessWeightQualifiedAt != nil && move.ExcessWeightAcknowledgedAt == nil { + if move.ExcessWeightQualifiedAt != nil && move.ExcessWeightAcknowledgedAt == nil || move.ExcessUnaccompaniedBaggageWeightQualifiedAt != nil && move.ExcessUnaccompaniedBaggageWeightAcknowledgedAt == nil { err = f.moveRouter.SendToOfficeUser(txnAppCtx, move) if err != nil { return err From 34f3e25a72e21bb5d9763807f7405d27571554f0 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Fri, 13 Dec 2024 17:54:18 +0000 Subject: [PATCH 21/35] Adding ubshipment check --- pkg/services/move/move_weights.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pkg/services/move/move_weights.go b/pkg/services/move/move_weights.go index 92e10d4047f..28ad5ab02e1 100644 --- a/pkg/services/move/move_weights.go +++ b/pkg/services/move/move_weights.go @@ -136,12 +136,19 @@ func saveMoveExcessWeightValues(appCtx appcontext.AppContext, move *models.Move, move.ExcessWeightQualifiedAt = nil } - // Check for risk of excess of UB allowance - if (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfUbShipments) || (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumActualWeightOfUbShipments) { + var hasUbShipments bool + for _, shipment := range move.MTOShipments { + if shipment.ShipmentType == models.MTOShipmentTypeUnaccompaniedBaggage { + hasUbShipments = true + } + } + + // Check for risk of excess of UB allowance if there are UB shipments + if hasUbShipments && ((int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfUbShipments) || (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumActualWeightOfUbShipments)) { isTheMoveBeingUpdated = true excessUbWeightQualifiedAt := now move.ExcessUnaccompaniedBaggageWeightQualifiedAt = &excessUbWeightQualifiedAt - } else if move.ExcessUnaccompaniedBaggageWeightQualifiedAt != nil { + } else if !hasUbShipments || move.ExcessUnaccompaniedBaggageWeightQualifiedAt != nil { // Reset qualified at isTheMoveBeingUpdated = true move.ExcessUnaccompaniedBaggageWeightQualifiedAt = nil From af856691d72acd6ac4a1f191f297a3d15a5b4b02 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Mon, 16 Dec 2024 16:04:30 +0000 Subject: [PATCH 22/35] Refactor --- pkg/services/move/move_weights.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/services/move/move_weights.go b/pkg/services/move/move_weights.go index 28ad5ab02e1..e1fbda2e4f1 100644 --- a/pkg/services/move/move_weights.go +++ b/pkg/services/move/move_weights.go @@ -143,8 +143,11 @@ func saveMoveExcessWeightValues(appCtx appcontext.AppContext, move *models.Move, } } + threshold := int(float32(ubWeightAllowance) * RiskOfExcessThreshold) + isWeightExceedingThreshold := (threshold <= sumOfWeights.SumEstimatedWeightOfUbShipments) || (threshold <= sumOfWeights.SumActualWeightOfUbShipments) + // Check for risk of excess of UB allowance if there are UB shipments - if hasUbShipments && ((int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumEstimatedWeightOfUbShipments) || (int(float32(ubWeightAllowance)*RiskOfExcessThreshold) <= sumOfWeights.SumActualWeightOfUbShipments)) { + if hasUbShipments && isWeightExceedingThreshold { isTheMoveBeingUpdated = true excessUbWeightQualifiedAt := now move.ExcessUnaccompaniedBaggageWeightQualifiedAt = &excessUbWeightQualifiedAt From ba09ad9bb5ce1c2b603b6cc14d3224f0e84c05b4 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Mon, 16 Dec 2024 20:32:20 +0000 Subject: [PATCH 23/35] Adding UB Breakdown --- .envrc | 2 +- src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.envrc b/.envrc index 3891c5b8d85..02c400ca703 100644 --- a/.envrc +++ b/.envrc @@ -154,7 +154,7 @@ export FEATURE_FLAG_NTS=true export FEATURE_FLAG_NTSR=true export FEATURE_FLAG_BOAT=true export FEATURE_FLAG_MOBILE_HOME=true -export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=false +export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=true # Feature flag to allow AK to be entered as a state export FEATURE_FLAG_ENABLE_ALASKA=true diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx index c8c3bf41216..a1cd233549c 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx @@ -128,6 +128,7 @@ export const MoveTaskOrder = (props) => { const [estimatedNTSWeightTotal, setEstimatedNTSWeightTotal] = useState(null); const [estimatedNTSReleaseWeightTotal, setEstimatedNTSReleaseWeightTotal] = useState(null); const [estimatedPPMWeightTotal, setEstimatedPPMWeightTotal] = useState(null); + const [estimatedUBWeightTotal, setEstimatedUBWeightTotal] = useState(null); const [, setSubmittedChangeTime] = useState(Date.now()); const [breakdownVisible, setBreakdownVisible] = useState(false); @@ -861,6 +862,7 @@ export const MoveTaskOrder = (props) => { setEstimatedHHGWeightTotal(calculateEstimatedWeight(nonPPMShipments, SHIPMENT_OPTIONS.HHG)); setEstimatedNTSWeightTotal(calculateEstimatedWeight(nonPPMShipments, SHIPMENT_OPTIONS.NTS)); setEstimatedNTSReleaseWeightTotal(calculateEstimatedWeight(nonPPMShipments, SHIPMENT_OPTIONS.NTSR)); + setEstimatedUBWeightTotal(calculateEstimatedWeight(nonPPMShipments, SHIPMENT_OPTIONS.UNACCOMPANIED_BAGGAGE)); setEstimatedPPMWeightTotal(calculateEstimatedWeight(onlyPPMShipments)); let excessBillableWeightCount = 0; const riskOfExcessAcknowledged = !!move?.excess_weight_acknowledged_at; @@ -976,6 +978,10 @@ export const MoveTaskOrder = (props) => { ? formatWeight(Math.round(estimatedNTSReleaseWeightTotal * 1.1)) : '—'}
+
110% Estimated UB
+
+ {Number.isFinite(estimatedUBWeightTotal) ? formatWeight(Math.round(estimatedUBWeightTotal * 1.1)) : '—'} +
); From bd1d56d7aad26680b41be6de8079e9ecea5af51d Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Mon, 16 Dec 2024 20:40:41 +0000 Subject: [PATCH 24/35] Excess weight risk count fixed --- src/components/Office/TXOTabNav/TXOTabNav.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Office/TXOTabNav/TXOTabNav.jsx b/src/components/Office/TXOTabNav/TXOTabNav.jsx index ee7705bd391..d6e509528cd 100644 --- a/src/components/Office/TXOTabNav/TXOTabNav.jsx +++ b/src/components/Office/TXOTabNav/TXOTabNav.jsx @@ -53,7 +53,7 @@ const TXOTabNav = ({ moveTaskOrderTagCount += unapprovedServiceItemCount; } if (excessWeightRiskCount > 0) { - moveTaskOrderTagCount += 1; + moveTaskOrderTagCount += excessWeightRiskCount; } if (unapprovedSITExtensionCount > 0) { moveTaskOrderTagCount += unapprovedSITExtensionCount; From 3b8758985dd61c5bd1d3acb8a362c383fa75ffe1 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Mon, 16 Dec 2024 20:42:04 +0000 Subject: [PATCH 25/35] remove envrc change --- .envrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.envrc b/.envrc index 02c400ca703..3891c5b8d85 100644 --- a/.envrc +++ b/.envrc @@ -154,7 +154,7 @@ export FEATURE_FLAG_NTS=true export FEATURE_FLAG_NTSR=true export FEATURE_FLAG_BOAT=true export FEATURE_FLAG_MOBILE_HOME=true -export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=true +export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=false # Feature flag to allow AK to be entered as a state export FEATURE_FLAG_ENABLE_ALASKA=true From 81e8a3afe3d2248f2145d72c1b0f0ec5fff5a2a7 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Tue, 17 Dec 2024 19:29:42 +0000 Subject: [PATCH 26/35] Test added --- .../Office/MoveTaskOrder/MoveTaskOrder.jsx | 2 +- .../MoveTaskOrder/MoveTaskOrder.test.jsx | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx index a1cd233549c..24d387bdb7b 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx @@ -979,7 +979,7 @@ export const MoveTaskOrder = (props) => { : '—'}
110% Estimated UB
-
+
{Number.isFinite(estimatedUBWeightTotal) ? formatWeight(Math.round(estimatedUBWeightTotal * 1.1)) : '—'}
diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx index 41accec8f72..106aa1954c4 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx @@ -865,4 +865,38 @@ describe('MoveTaskOrder', () => { expect(screen.queryByText('Flag move for financial review')).not.toBeInTheDocument(); }); }); + + describe('estimated weight breakdown', () => { + it('should show UB estimated weight', () => { + useMoveTaskOrderQueries.mockReturnValue(riskOfExcessWeightQueryExternalUBShipment); + + render( + + + , + ); + + const breakdownToggle = screen.queryByText('Show Breakdown'); + + expect(breakdownToggle).toBeInTheDocument(); + + breakdownToggle.click(); + + expect(breakdownToggle).toHaveTextContent('Hide Breakdown'); + + expect(screen.queryByText('110% Estimated UB')).toBeInTheDocument(); + + const ubEstimatedWeightValue = screen.getByTestId('breakdownUBEstimatedWeight'); + + expect(ubEstimatedWeightValue).toBeInTheDocument(); + + expect(ubEstimatedWeightValue).toHaveTextContent('2,035 lbs'); + }); + }); }); From 834a059a67af0050fe50c426ecae32b6154d9dc3 Mon Sep 17 00:00:00 2001 From: Tevin Adams Date: Tue, 17 Dec 2024 19:40:35 +0000 Subject: [PATCH 27/35] Test refactor --- .../MoveTaskOrder/MoveTaskOrder.test.jsx | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx index 106aa1954c4..81a65bd6098 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.test.jsx @@ -29,6 +29,9 @@ import { useMoveTaskOrderQueries, useMovePaymentRequestsQueries, useGHCGetMoveHi import { MockProviders } from 'testUtils'; import { permissionTypes } from 'constants/permissions'; import SERVICE_ITEM_STATUS from 'constants/serviceItems'; +import { SITStatusOrigin } from 'components/Office/ShipmentSITDisplay/ShipmentSITDisplayTestParams'; +import { SHIPMENT_OPTIONS } from 'shared/constants'; +import { formatWeight } from 'utils/formatters'; jest.mock('hooks/queries', () => ({ useMoveTaskOrderQueries: jest.fn(), @@ -868,7 +871,37 @@ describe('MoveTaskOrder', () => { describe('estimated weight breakdown', () => { it('should show UB estimated weight', () => { - useMoveTaskOrderQueries.mockReturnValue(riskOfExcessWeightQueryExternalUBShipment); + const testShipments = [ + { + id: '1', + moveTaskOrderID: '2', + shipmentType: SHIPMENT_OPTIONS.UNACCOMPANIED_BAGGAGE, + scheduledPickupDate: '2020-03-16', + requestedPickupDate: '2020-03-15', + pickupAddress: { + streetAddress1: '932 Baltic Avenue', + city: 'Chicago', + state: 'IL', + postalCode: '60601', + }, + destinationAddress: { + streetAddress1: '10 Park Place', + city: 'Atlantic City', + state: 'NJ', + postalCode: '08401', + }, + status: 'APPROVED', + eTag: '1234', + primeEstimatedWeight: 1850, + primeActualWeight: 1841, + sitExtensions: [], + sitStatus: SITStatusOrigin, + }, + ]; + useMoveTaskOrderQueries.mockReturnValue({ + ...riskOfExcessWeightQueryExternalUBShipment, + mtoShipments: testShipments, + }); render( @@ -883,20 +916,15 @@ describe('MoveTaskOrder', () => { ); const breakdownToggle = screen.queryByText('Show Breakdown'); - expect(breakdownToggle).toBeInTheDocument(); breakdownToggle.click(); - expect(breakdownToggle).toHaveTextContent('Hide Breakdown'); - expect(screen.queryByText('110% Estimated UB')).toBeInTheDocument(); const ubEstimatedWeightValue = screen.getByTestId('breakdownUBEstimatedWeight'); - expect(ubEstimatedWeightValue).toBeInTheDocument(); - - expect(ubEstimatedWeightValue).toHaveTextContent('2,035 lbs'); + expect(ubEstimatedWeightValue).toHaveTextContent(`${formatWeight(testShipments[0].primeEstimatedWeight * 1.1)}`); }); }); }); From 061525e1f767882227e08720f1581e73a971c1c5 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 18:22:07 +0000 Subject: [PATCH 28/35] B-22133 make generic for reuse --- src/pages/Office/index.jsx | 8 +- ...eItem.jsx => PrimeUIUpdateServiceItem.jsx} | 106 +++++++++++------- .../PrimeUpdateSitServiceItem.test.jsx | 2 +- 3 files changed, 67 insertions(+), 49 deletions(-) rename src/pages/PrimeUI/UpdateServiceItems/{PrimeUIUpdateSitServiceItem.jsx => PrimeUIUpdateServiceItem.jsx} (64%) diff --git a/src/pages/Office/index.jsx b/src/pages/Office/index.jsx index 4ca83220d96..38d974c414c 100644 --- a/src/pages/Office/index.jsx +++ b/src/pages/Office/index.jsx @@ -82,9 +82,7 @@ const PrimeSimulatorUploadServiceRequestDocuments = lazy(() => import('pages/PrimeUI/UploadServiceRequestDocuments/UploadServiceRequestDocuments'), ); const PrimeSimulatorCreateServiceItem = lazy(() => import('pages/PrimeUI/CreateServiceItem/CreateServiceItem')); -const PrimeSimulatorUpdateSitServiceItem = lazy(() => - import('pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem'), -); +const PrimeSimulatorUpdateServiceItem = lazy(() => import('pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem')); const PrimeUIShipmentUpdateAddress = lazy(() => import('pages/PrimeUI/Shipment/PrimeUIShipmentUpdateAddress')); const PrimeUIShipmentUpdateReweigh = lazy(() => import('pages/PrimeUI/Shipment/PrimeUIShipmentUpdateReweigh')); const PrimeSimulatorCreateSITExtensionRequest = lazy(() => @@ -510,11 +508,11 @@ export class OfficeApp extends Component { } /> - + } /> diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx similarity index 64% rename from src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx rename to src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx index 4ff8a1a3651..923f92c8e7a 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx @@ -20,18 +20,18 @@ import { primeSimulatorRoutes } from 'constants/routes'; import { formatDateForSwagger, formatDateWithUTC } from 'shared/dates'; import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; -const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { +const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { const [errorMessage, setErrorMessage] = useState(); const navigate = useNavigate(); const { moveCodeOrID, mtoServiceItemId } = useParams(); const { moveTaskOrder, isLoading, isError } = usePrimeSimulatorGetMove(moveCodeOrID); /* istanbul ignore next */ - const { mutate: createUpdateSITServiceItemRequestMutation } = useMutation(updateMTOServiceItem, { + const { mutate: createUpdateServiceItemRequestMutation } = useMutation(updateMTOServiceItem, { onSuccess: () => { setFlashMessage( - `UPDATE_SIT_SERVICE_ITEM_REQUEST_SUCCESS${moveCodeOrID}`, + `UPDATE_SERVICE_ITEM_REQUEST_SUCCESS${moveCodeOrID}`, 'success', - 'Successfully updated SIT service item', + 'Successfully updated service item', '', true, ); @@ -68,10 +68,12 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { if (isError) return ; const serviceItem = moveTaskOrder?.mtoServiceItems.find((s) => s?.id === mtoServiceItemId); - const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); const { modelType } = serviceItem; + let initialValues; + let onSubmit; let port; if (modelType === 'MTOServiceItemInternationalFuelSurcharge') { + const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); if (mtoShipment.portOfEmbarkation) { port = mtoShipment.portOfEmbarkation; } else if (mtoShipment.portOfDebarkation) { @@ -79,46 +81,64 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { } else { port = null; } - } - - const initialValues = { - sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', - sitRequestedDelivery: formatDateWithUTC(serviceItem.sitRequestedDelivery, 'YYYY-MM-DD', 'DD MMM YYYY') || '', - sitCustomerContacted: formatDateWithUTC(serviceItem.sitCustomerContacted, 'YYYY-MM-DD', 'DD MMM YYYY') || '', - mtoServiceItemID: serviceItem.id, - reServiceCode: serviceItem.reServiceCode, - eTag: serviceItem.eTag, - portCode: port?.portCode, - }; - - // sending the data submitted in the form to the API - // if any of the dates are skipped or not filled with values, we'll just make them null - const onSubmit = (values) => { - const { - sitCustomerContacted, - sitDepartureDate, - sitRequestedDelivery, - updateReason, - mtoServiceItemID, - reServiceCode, - eTag, - } = values; - - const body = { - sitDepartureDate: sitDepartureDate === 'Invalid date' ? null : formatDateForSwagger(sitDepartureDate), - sitRequestedDelivery: sitRequestedDelivery === 'Invalid date' ? null : formatDateForSwagger(sitRequestedDelivery), - sitCustomerContacted: sitCustomerContacted === 'Invalid date' ? null : formatDateForSwagger(sitCustomerContacted), - reServiceCode, - modelType: 'UpdateMTOServiceItemSIT', + initialValues = { + mtoServiceItemID: serviceItem.id, + reServiceCode: serviceItem.reServiceCode, + eTag: serviceItem.eTag, + portCode: port?.portCode, }; - if (serviceItem?.status === SERVICE_ITEM_STATUSES.REJECTED) { - body.requestApprovalsRequestedStatus = true; - body.updateReason = updateReason; - } + onSubmit = (values) => { + const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; + + const body = { + portCode, + reServiceCode, + modelType: 'UpdateMTOServiceItemInternationalPortFSC', + }; + + createUpdateServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); + }; + } else if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { + initialValues = { + sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', + sitRequestedDelivery: formatDateWithUTC(serviceItem.sitRequestedDelivery, 'YYYY-MM-DD', 'DD MMM YYYY') || '', + sitCustomerContacted: formatDateWithUTC(serviceItem.sitCustomerContacted, 'YYYY-MM-DD', 'DD MMM YYYY') || '', + mtoServiceItemID: serviceItem.id, + reServiceCode: serviceItem.reServiceCode, + eTag: serviceItem.eTag, + }; + // sending the data submitted in the form to the API + // if any of the dates are skipped or not filled with values, we'll just make them null + onSubmit = (values) => { + const { + sitCustomerContacted, + sitDepartureDate, + sitRequestedDelivery, + updateReason, + mtoServiceItemID, + reServiceCode, + eTag, + } = values; + + const body = { + sitDepartureDate: sitDepartureDate === 'Invalid date' ? null : formatDateForSwagger(sitDepartureDate), + sitRequestedDelivery: + sitRequestedDelivery === 'Invalid date' ? null : formatDateForSwagger(sitRequestedDelivery), + sitCustomerContacted: + sitCustomerContacted === 'Invalid date' ? null : formatDateForSwagger(sitCustomerContacted), + reServiceCode, + modelType: 'UpdateMTOServiceItemSIT', + }; + + if (serviceItem?.status === SERVICE_ITEM_STATUSES.REJECTED) { + body.requestApprovalsRequestedStatus = true; + body.updateReason = updateReason; + } - createUpdateSITServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); - }; + createUpdateServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); + }; + } return (
@@ -169,4 +189,4 @@ const mapDispatchToProps = { setFlashMessage: setFlashMessageAction, }; -export default connect(() => ({}), mapDispatchToProps)(PrimeUIUpdateSitServiceItem); +export default connect(() => ({}), mapDispatchToProps)(PrimeUIUpdateServiceItem); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx index 1f397cb700f..e7f21f94309 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import PrimeUIUpdateSitServiceItem from './PrimeUIUpdateSitServiceItem'; +import PrimeUIUpdateSitServiceItem from './PrimeUIUpdateServiceItem'; import { MockProviders, ReactQueryWrapper } from 'testUtils'; import { primeSimulatorRoutes } from 'constants/routes'; From c76ea0130351453a1d41ec17b625f86656909cf1 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 21:04:59 +0000 Subject: [PATCH 29/35] B-22133 jest stuff --- ...UIUpdateInternationalFuelSurchargeForm.jsx | 33 ++++++---- ...ateInternationalFuelSurchargeForm.test.jsx | 60 +++++++++++++++---- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index 5092ae351a6..92ff9925869 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { Formik } from 'formik'; +import * as Yup from 'yup'; import { useNavigate, useParams, generatePath } from 'react-router-dom'; import { FormGroup } from '@trussworks/react-uswds'; import classnames from 'classnames'; @@ -24,7 +25,16 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, }; return ( - + {({ handleSubmit }) => (
@@ -71,17 +81,16 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit,
- {serviceItem.status === SERVICE_ITEM_STATUSES.APPROVED && ( - - )} + ({ })); describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { - it('renders the address change request form', async () => { + it('renders the international fuel surcharge form', async () => { renderWithProviders( { const onSubmitMock = jest.fn(); renderWithProviders( , ); - + const portCodeInput = screen.getByLabelText(/Port Code/); + await userEvent.type(portCodeInput, 'SEA'); const saveButton = await screen.findByRole('button', { name: 'Save' }); await userEvent.click(saveButton); @@ -82,10 +82,48 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { expect(onSubmitMock).toHaveBeenCalled(); }); + it('does not fire off onSubmit function when save button is clicked and port code is empty', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + const portCodeInput = screen.getByLabelText(/Port Code/); + await userEvent.clear(portCodeInput, ''); + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).not.toHaveBeenCalled(); + }); + + it('does not fire off onSubmit function when save button is clicked and port code is fewer than 3 characters', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + const portCodeInput = screen.getByLabelText(/Port Code/); + await userEvent.clear(portCodeInput, '12'); + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).not.toHaveBeenCalled(); + }); + it('directs the user back to the move page when cancel button is clicked', async () => { renderWithProviders( Date: Thu, 2 Jan 2025 21:43:18 +0000 Subject: [PATCH 30/35] B-22133 move port stuff out of common area --- ...UIUpdateInternationalFuelSurchargeForm.jsx | 31 +++++++- ...ateInternationalFuelSurchargeForm.test.jsx | 79 ++++++++++--------- .../PrimeUIUpdateServiceItem.jsx | 37 +-------- 3 files changed, 75 insertions(+), 72 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index 92ff9925869..5b31672c1c3 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -16,7 +16,7 @@ import descriptionListStyles from 'styles/descriptionList.module.scss'; import { primeSimulatorRoutes } from 'constants/routes'; import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; -const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, serviceItem, port }) => { +const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, moveTaskOrder, mtoServiceItemId }) => { const { moveCodeOrID } = useParams(); const navigate = useNavigate(); @@ -24,6 +24,35 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); }; + const serviceItem = moveTaskOrder?.mtoServiceItems.find((s) => s?.id === mtoServiceItemId); + const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); + let port; + if (mtoShipment.portOfEmbarkation) { + port = mtoShipment.portOfEmbarkation; + } else if (mtoShipment.portOfDebarkation) { + port = mtoShipment.portOfDebarkation; + } else { + port = null; + } + const initialValues = { + mtoServiceItemID: serviceItem.id, + reServiceCode: serviceItem.reServiceCode, + eTag: serviceItem.eTag, + portCode: port?.portCode, + }; + + const onSubmit = (values) => { + const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; + + const body = { + portCode, + reServiceCode, + modelType: 'UpdateMTOServiceItemInternationalPortFSC', + }; + + onUpdateServiceItem({ mtoServiceItemID, eTag, body }); + }; + return ( ({ @@ -43,10 +54,9 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { it('renders the international fuel surcharge form', async () => { renderWithProviders( , ); @@ -63,14 +73,12 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { expect(screen.getByRole('button', { name: 'Cancel' })).toBeEnabled(); }); - it('fires off onSubmit function when save button is clicked', async () => { - const onSubmitMock = jest.fn(); + it('fires off onUpdateServiceItemMock function when save button is clicked', async () => { renderWithProviders( , ); const portCodeInput = screen.getByLabelText(/Port Code/); @@ -79,54 +87,49 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { await userEvent.click(saveButton); - expect(onSubmitMock).toHaveBeenCalled(); + expect(onUpdateServiceItemMock).toHaveBeenCalled(); }); - it('does not fire off onSubmit function when save button is clicked and port code is empty', async () => { - const onSubmitMock = jest.fn(); + it('does not fire off onUpdateServiceItemMock function when save button is clicked and port code is empty', async () => { renderWithProviders( , ); const portCodeInput = screen.getByLabelText(/Port Code/); await userEvent.clear(portCodeInput, ''); const saveButton = await screen.findByRole('button', { name: 'Save' }); + onUpdateServiceItemMock.mockClear(); await userEvent.click(saveButton); - - expect(onSubmitMock).not.toHaveBeenCalled(); + expect(onUpdateServiceItemMock).not.toHaveBeenCalled(); }); - it('does not fire off onSubmit function when save button is clicked and port code is fewer than 3 characters', async () => { - const onSubmitMock = jest.fn(); + it('does not fire off onUpdateServiceItemMock function when save button is clicked and port code is fewer than 3 characters', async () => { renderWithProviders( , ); const portCodeInput = screen.getByLabelText(/Port Code/); await userEvent.clear(portCodeInput, '12'); const saveButton = await screen.findByRole('button', { name: 'Save' }); + onUpdateServiceItemMock.mockClear(); await userEvent.click(saveButton); - - expect(onSubmitMock).not.toHaveBeenCalled(); + expect(onUpdateServiceItemMock).not.toHaveBeenCalled(); }); it('directs the user back to the move page when cancel button is clicked', async () => { renderWithProviders( , ); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx index 923f92c8e7a..387981922c4 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx @@ -71,35 +71,7 @@ const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { const { modelType } = serviceItem; let initialValues; let onSubmit; - let port; - if (modelType === 'MTOServiceItemInternationalFuelSurcharge') { - const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); - if (mtoShipment.portOfEmbarkation) { - port = mtoShipment.portOfEmbarkation; - } else if (mtoShipment.portOfDebarkation) { - port = mtoShipment.portOfDebarkation; - } else { - port = null; - } - initialValues = { - mtoServiceItemID: serviceItem.id, - reServiceCode: serviceItem.reServiceCode, - eTag: serviceItem.eTag, - portCode: port?.portCode, - }; - - onSubmit = (values) => { - const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; - - const body = { - portCode, - reServiceCode, - modelType: 'UpdateMTOServiceItemInternationalPortFSC', - }; - - createUpdateServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); - }; - } else if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { + if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { initialValues = { sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', sitRequestedDelivery: formatDateWithUTC(serviceItem.sitRequestedDelivery, 'YYYY-MM-DD', 'DD MMM YYYY') || '', @@ -171,10 +143,9 @@ const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { ) : null} {modelType === 'MTOServiceItemInternationalFuelSurcharge' ? ( ) : null} From b8e5a42a4b1e12e679a37fcd543aee0acb04f3f1 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 22:51:52 +0000 Subject: [PATCH 31/35] B-22133 don't show random comma --- .../PrimeUIUpdateInternationalFuelSurchargeForm.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index 5b31672c1c3..a68f99f71dd 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -106,7 +106,8 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move
Port Location:
- {port && port.city}, {port && port.state} {port && port.zip} + {port && port.city} + {port && port.city && ','} {port && port.state} {port && port.zip}
From f6a9c0c5f4e27b44846155079060ccc5c05a634b Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Fri, 3 Jan 2025 21:29:46 +0000 Subject: [PATCH 32/35] B-22133 provide flexibility for input --- .../PrimeUIUpdateInternationalFuelSurchargeForm.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index a68f99f71dd..ea6e8ea5ea1 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -45,7 +45,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; const body = { - portCode, + portCode: portCode.toUpperCase(), reServiceCode, modelType: 'UpdateMTOServiceItemInternationalPortFSC', }; From 0c48d41a9e10453be8af1dedaec651c5bdce468f Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Fri, 3 Jan 2025 21:43:46 +0000 Subject: [PATCH 33/35] B-22133 formik way of doing things --- .../PrimeUIUpdateInternationalFuelSurchargeForm.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index ea6e8ea5ea1..dc02c9c2423 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -45,7 +45,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; const body = { - portCode: portCode.toUpperCase(), + portCode, reServiceCode, modelType: 'UpdateMTOServiceItemInternationalPortFSC', }; @@ -64,7 +64,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move .max(4, 'Port Code must be 3-4 characters.'), })} > - {({ handleSubmit }) => ( + {({ handleSubmit, setFieldValue }) => (
@@ -120,6 +120,9 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move labelHint="Required" maxLength="4" isDisabled={serviceItem.status !== SERVICE_ITEM_STATUSES.APPROVED} + onBlur={(e) => { + setFieldValue('portCode', e.target.value.toUpperCase()); + }} /> Date: Fri, 3 Jan 2025 22:15:20 +0000 Subject: [PATCH 34/35] B-22133 test uppercase --- ...meUIUpdateInternationalFuelSurchargeForm.jsx | 2 +- ...pdateInternationalFuelSurchargeForm.test.jsx | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index dc02c9c2423..63014e86300 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -120,7 +120,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move labelHint="Required" maxLength="4" isDisabled={serviceItem.status !== SERVICE_ITEM_STATUSES.APPROVED} - onBlur={(e) => { + onChange={(e) => { setFieldValue('portCode', e.target.value.toUpperCase()); }} /> diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx index d76306cf7b1..78461a6e840 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { screen } from '@testing-library/react'; +import { screen, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; @@ -90,6 +90,21 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { expect(onUpdateServiceItemMock).toHaveBeenCalled(); }); + it('port code value is set to uppercase when user types in a value', async () => { + renderWithProviders( + , + ); + const portCodeInput = screen.getByLabelText(/Port Code/); + expect(portCodeInput).toHaveValue('SEA'); + fireEvent.change(portCodeInput, { target: { value: 'pdx' } }); + + expect(portCodeInput).toHaveValue('PDX'); + }); + it('does not fire off onUpdateServiceItemMock function when save button is clicked and port code is empty', async () => { renderWithProviders( Date: Mon, 13 Jan 2025 14:08:28 +0000 Subject: [PATCH 35/35] Revert "Adding data-test id" This reverts commit 94b150489f4158ae8c25f0f04e3664f5d49e1906. --- src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx index 24d387bdb7b..a1fe5abec1c 100644 --- a/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx +++ b/src/pages/Office/MoveTaskOrder/MoveTaskOrder.jsx @@ -1142,7 +1142,6 @@ export const MoveTaskOrder = (props) => {