From b9d4e5fef2c507801c2d412fabe92ab1ae36171e Mon Sep 17 00:00:00 2001 From: Alex Lusk Date: Fri, 2 Aug 2024 17:24:17 +0000 Subject: [PATCH 01/19] fix queue csv export for HQ role when viewing GBLOCs other than default --- src/components/Table/TableCSVExportButton.jsx | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/components/Table/TableCSVExportButton.jsx b/src/components/Table/TableCSVExportButton.jsx index 813f5b7a50d..9b5937c3642 100644 --- a/src/components/Table/TableCSVExportButton.jsx +++ b/src/components/Table/TableCSVExportButton.jsx @@ -1,10 +1,12 @@ -import React, { useState, useRef } from 'react'; +import React, { useState, useRef, useContext } from 'react'; import { CSVLink } from 'react-csv'; -import { Link } from '@trussworks/react-uswds'; +import { Button } from '@trussworks/react-uswds'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import moment from 'moment'; import PropTypes from 'prop-types'; +import SelectedGblocContext from 'components/Office/GblocSwitcher/SelectedGblocContext'; + const TableCSVExportButton = ({ labelText, filePrefix, @@ -22,6 +24,9 @@ const TableCSVExportButton = ({ const csvLinkRef = useRef(null); const { id: sortColumn, desc: sortOrder } = paramSort.length ? paramSort[0] : {}; + const gblocContext = useContext(SelectedGblocContext); + const { selectedGbloc } = gblocContext || { selectedGbloc: undefined }; + const formatDataForExport = (data, columns = tableColumns) => { const formattedData = []; data.forEach((row) => { @@ -50,6 +55,7 @@ const TableCSVExportButton = ({ order: sortOrder ? 'desc' : 'asc', filters: paramFilters, currentPageSize: totalCount, + viewAsGBLOC: selectedGbloc, }); const formattedData = formatDataForExport(response[queueFetcherKey]); @@ -61,15 +67,23 @@ const TableCSVExportButton = ({ return (

- + From 44907d71794eadd3136611b5717ff809b84ff63c Mon Sep 17 00:00:00 2001 From: Alex Lusk Date: Fri, 2 Aug 2024 17:25:22 +0000 Subject: [PATCH 02/19] test for disabling CSV export when there is nothing to export --- .../Table/TableCSVExportButton.test.jsx | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/components/Table/TableCSVExportButton.test.jsx b/src/components/Table/TableCSVExportButton.test.jsx index a3847752000..da8b2102f13 100644 --- a/src/components/Table/TableCSVExportButton.test.jsx +++ b/src/components/Table/TableCSVExportButton.test.jsx @@ -55,6 +55,11 @@ const paymentRequestsResponse = { ], }; +const paymentRequestsNoResultsResponse = { + page: 1, + perPage: 10, +}; + const paymentRequestColumns = [ { Header: ' ', @@ -129,6 +134,9 @@ const paymentRequestColumns = [ jest.mock('services/ghcApi', () => ({ getPaymentRequestsQueue: jest.fn().mockImplementation(() => Promise.resolve(paymentRequestsResponse)), + getPaymentRequestsNoResultsQueue: jest + .fn() + .mockImplementation(() => Promise.resolve(paymentRequestsNoResultsResponse)), })); describe('TableCSVExportButton', () => { @@ -155,4 +163,22 @@ describe('TableCSVExportButton', () => { expect(getPaymentRequestsQueue).toBeCalled(); }); + + const noResultsProps = { + tableColumns: paymentRequestColumns, + queueFetcher: () => Promise.resolve(paymentRequestsNoResultsResponse), + queueFetcherKey: 'queuePaymentRequests', + totalCount: 0, + }; + + it('is diabled when there is nothing to export', () => { + act(() => { + const wrapper = mount(); + const exportButton = wrapper.find('span[data-test-id="csv-export-btn-text"]'); + exportButton.simulate('click'); + wrapper.update(); + }); + + expect(getPaymentRequestsQueue).toBeCalled(); + }); }); From 6cab2b50ddcd364145e04a65e1bed8a350cb92d5 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Thu, 22 Aug 2024 14:46:48 +0000 Subject: [PATCH 03/19] B-20441 --- migrations/app/migrations_manifest.txt | 1 + ...ng_locked_price_cents_for_ms_and_cs.up.sql | 4 ++ pkg/handlers/ghcapi/mto_service_items.go | 6 +-- pkg/services/ghc_rate_engine.go | 4 +- .../counseling_services_pricer.go | 37 +++++++++++-------- .../counseling_services_pricer_test.go | 10 ++++- .../management_services_pricer.go | 35 ++++++++++-------- .../management_services_pricer_test.go | 4 +- .../mocks/CounselingServicesPricer.go | 24 ++++++------ .../mocks/ManagementServicesPricer.go | 24 ++++++------ 10 files changed, 82 insertions(+), 67 deletions(-) create mode 100644 migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 5f6577ab2fd..bb5958dd21a 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -979,3 +979,4 @@ 20240807140736_add_locked_price_cents_to_mto_service_items.up.sql 20240814144527_remove_allow_pptas_client.up.sql 20240820125856_allow_pptas_migration.up.sql +20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql diff --git a/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql b/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql new file mode 100644 index 00000000000..08b89a8baf8 --- /dev/null +++ b/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql @@ -0,0 +1,4 @@ +UPDATE mto_service_items AS ms +SET locked_price_cents = pricing_estimate +FROM re_services AS r +WHERE ms.re_service_id = r.id AND r.code = 'MS' OR r.code = 'CS' \ No newline at end of file diff --git a/pkg/handlers/ghcapi/mto_service_items.go b/pkg/handlers/ghcapi/mto_service_items.go index 160f96db12b..910df4569ee 100644 --- a/pkg/handlers/ghcapi/mto_service_items.go +++ b/pkg/handlers/ghcapi/mto_service_items.go @@ -17,7 +17,6 @@ import ( "github.com/transcom/mymove/pkg/handlers" "github.com/transcom/mymove/pkg/handlers/ghcapi/internal/payloads" "github.com/transcom/mymove/pkg/models" - serviceparamlookups "github.com/transcom/mymove/pkg/payment_request/service_param_value_lookups" "github.com/transcom/mymove/pkg/services" "github.com/transcom/mymove/pkg/services/audit" "github.com/transcom/mymove/pkg/services/event" @@ -384,7 +383,6 @@ func (h ListMTOServiceItemsHandler) Handle(params mtoserviceitemop.ListMTOServic } if len(indices) > 0 { - contract, err := serviceparamlookups.FetchContract(appCtx, *moveTaskOrder.AvailableToPrimeAt) if err != nil { return mtoserviceitemop.NewListMTOServiceItemsInternalServerError(), err } @@ -394,9 +392,9 @@ func (h ListMTOServiceItemsHandler) Handle(params mtoserviceitemop.ListMTOServic var displayParams services.PricingDisplayParams var err error if serviceItems[index].ReService.Code == "CS" { - price, displayParams, err = h.counselingPricer.Price(appCtx, contract.Code, *moveTaskOrder.AvailableToPrimeAt) + price, displayParams, err = h.counselingPricer.Price(appCtx, serviceItems[index]) } else if serviceItems[index].ReService.Code == "MS" { - price, displayParams, err = h.moveManagementPricer.Price(appCtx, contract.Code, *moveTaskOrder.AvailableToPrimeAt) + price, displayParams, err = h.moveManagementPricer.Price(appCtx, serviceItems[index]) } for _, param := range displayParams { diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 51bd1d29d5e..5d9d2737bba 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -33,7 +33,7 @@ type ParamsPricer interface { // //go:generate mockery --name ManagementServicesPricer type ManagementServicesPricer interface { - Price(appCtx appcontext.AppContext, contractCode string, mtoAvailableToPrimeAt time.Time) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, PricingDisplayParams, error) ParamsPricer } @@ -41,7 +41,7 @@ type ManagementServicesPricer interface { // //go:generate mockery --name CounselingServicesPricer type CounselingServicesPricer interface { - Price(appCtx appcontext.AppContext, contractCode string, mtoAvailableToPrimeAt time.Time) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/counseling_services_pricer.go b/pkg/services/ghcrateengine/counseling_services_pricer.go index e2c3869474f..4ab2a67cbc1 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer.go @@ -2,7 +2,8 @@ package ghcrateengine import ( "fmt" - "time" + + "github.com/gofrs/uuid" "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" @@ -19,32 +20,36 @@ func NewCounselingServicesPricer() services.CounselingServicesPricer { } // Price determines the price for a counseling service -func (p counselingServicesPricer) Price(appCtx appcontext.AppContext, contractCode string, mtoAvailableToPrimeAt time.Time) (unit.Cents, services.PricingDisplayParams, error) { - taskOrderFee, err := fetchTaskOrderFee(appCtx, contractCode, models.ReServiceCodeCS, mtoAvailableToPrimeAt) - if err != nil { - return unit.Cents(0), nil, fmt.Errorf("could not fetch task order fee: %w", err) +func (p managementServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { + + if serviceItem.LockedPriceCents == nil { + return unit.Cents(0), nil, fmt.Errorf("could not find locked price cents: %s", serviceItem.ID) } - displayPriceParams := services.PricingDisplayParams{ + params := services.PricingDisplayParams{ { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(taskOrderFee.PriceCents), + Value: FormatCents(*serviceItem.LockedPriceCents), }, } - return taskOrderFee.PriceCents, displayPriceParams, nil + + return *serviceItem.LockedPriceCents, params, nil } // PriceUsingParams determines the price for a counseling service given PaymentServiceItemParams -func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { - contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) - if err != nil { - return unit.Cents(0), nil, err +func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + + var serviceItem models.MTOServiceItem + for _, param := range params { + if param.PaymentServiceItem.MTOServiceItem.LockedPriceCents != nil { + serviceItem = param.PaymentServiceItem.MTOServiceItem + break + } } - mtoAvailableToPrimeAt, err := getParamTime(params, models.ServiceItemParamNameMTOAvailableToPrimeAt) - if err != nil { - return unit.Cents(0), nil, err + if serviceItem.ID == uuid.Nil { + return unit.Cents(0), nil, fmt.Errorf("could not find id for shipment") } - return p.Price(appCtx, contractCode, mtoAvailableToPrimeAt) + return p.Price(appCtx, serviceItem) } diff --git a/pkg/services/ghcrateengine/counseling_services_pricer_test.go b/pkg/services/ghcrateengine/counseling_services_pricer_test.go index e59368337ac..c0098764a82 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer_test.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer_test.go @@ -16,6 +16,12 @@ const ( var csAvailableToPrimeAt = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) +var lockedPriceCents = unit.Cents(8327) + +var mtoServiceItem = models.MTOServiceItem{ + LockedPriceCents: &lockedPriceCents, +} + func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { counselingServicesPricer := NewCounselingServicesPricer() @@ -37,7 +43,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { suite.Run("success without PaymentServiceItemParams", func() { suite.setupTaskOrderFeeData(models.ReServiceCodeCS, csPriceCents) - priceCents, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, csAvailableToPrimeAt) + priceCents, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) suite.NoError(err) suite.Equal(csPriceCents, priceCents) }) @@ -50,7 +56,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { }) suite.Run("not finding a rate record", func() { - _, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), "BOGUS", csAvailableToPrimeAt) + _, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) suite.Error(err) }) } diff --git a/pkg/services/ghcrateengine/management_services_pricer.go b/pkg/services/ghcrateengine/management_services_pricer.go index f01c990a1de..d6cd107fb0f 100644 --- a/pkg/services/ghcrateengine/management_services_pricer.go +++ b/pkg/services/ghcrateengine/management_services_pricer.go @@ -2,7 +2,8 @@ package ghcrateengine import ( "fmt" - "time" + + "github.com/gofrs/uuid" "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" @@ -19,32 +20,36 @@ func NewManagementServicesPricer() services.ManagementServicesPricer { } // Price determines the price for a management service -func (p managementServicesPricer) Price(appCtx appcontext.AppContext, contractCode string, mtoAvailableToPrimeAt time.Time) (unit.Cents, services.PricingDisplayParams, error) { - taskOrderFee, err := fetchTaskOrderFee(appCtx, contractCode, models.ReServiceCodeMS, mtoAvailableToPrimeAt) - if err != nil { - return unit.Cents(0), nil, fmt.Errorf("could not fetch task order fee: %w", err) +func (p counselingServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { + + if serviceItem.LockedPriceCents == nil { + return unit.Cents(0), nil, fmt.Errorf("could not find locked price cents: %s", serviceItem.ID) } + params := services.PricingDisplayParams{ { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(taskOrderFee.PriceCents), + Value: FormatCents(*serviceItem.LockedPriceCents), }, } - return taskOrderFee.PriceCents, params, nil + return *serviceItem.LockedPriceCents, params, nil } // PriceUsingParams determines the price for a management service given PaymentServiceItemParams -func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { - contractCode, err := getParamString(params, models.ServiceItemParamNameContractCode) - if err != nil { - return unit.Cents(0), nil, err +func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { + + var serviceItem models.MTOServiceItem + for _, param := range params { + if param.PaymentServiceItem.MTOServiceItem.LockedPriceCents != nil { + serviceItem = param.PaymentServiceItem.MTOServiceItem + break + } } - mtoAvailableToPrimeAt, err := getParamTime(params, models.ServiceItemParamNameMTOAvailableToPrimeAt) - if err != nil { - return unit.Cents(0), nil, err + if serviceItem.ID == uuid.Nil { + return unit.Cents(0), nil, fmt.Errorf("could not find id for shipment") } - return p.Price(appCtx, contractCode, mtoAvailableToPrimeAt) + return p.Price(appCtx, serviceItem) } diff --git a/pkg/services/ghcrateengine/management_services_pricer_test.go b/pkg/services/ghcrateengine/management_services_pricer_test.go index 52355a2695b..05abcfcb2de 100644 --- a/pkg/services/ghcrateengine/management_services_pricer_test.go +++ b/pkg/services/ghcrateengine/management_services_pricer_test.go @@ -37,7 +37,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) managementServicesPricer := NewManagementServicesPricer() - priceCents, _, err := managementServicesPricer.Price(suite.AppContextForTest(), testdatagen.DefaultContractCode, msAvailableToPrimeAt) + priceCents, _, err := managementServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) suite.NoError(err) suite.Equal(msPriceCents, priceCents) }) @@ -54,7 +54,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) managementServicesPricer := NewManagementServicesPricer() - _, _, err := managementServicesPricer.Price(suite.AppContextForTest(), "BOGUS", msAvailableToPrimeAt) + _, _, err := managementServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) suite.Error(err) }) } diff --git a/pkg/services/mocks/CounselingServicesPricer.go b/pkg/services/mocks/CounselingServicesPricer.go index 561fcec66c7..2f6cc2cf375 100644 --- a/pkg/services/mocks/CounselingServicesPricer.go +++ b/pkg/services/mocks/CounselingServicesPricer.go @@ -10,8 +10,6 @@ import ( services "github.com/transcom/mymove/pkg/services" - time "time" - unit "github.com/transcom/mymove/pkg/unit" ) @@ -20,32 +18,32 @@ type CounselingServicesPricer struct { mock.Mock } -// Price provides a mock function with given fields: appCtx, contractCode, mtoAvailableToPrimeAt -func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, contractCode string, mtoAvailableToPrimeAt time.Time) (unit.Cents, services.PricingDisplayParams, error) { - ret := _m.Called(appCtx, contractCode, mtoAvailableToPrimeAt) +// Price provides a mock function with given fields: appCtx, serviceItem +func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, serviceItem) var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time) (unit.Cents, services.PricingDisplayParams, error)); ok { - return rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, serviceItem) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time) unit.Cents); ok { - r0 = rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) unit.Cents); ok { + r0 = rf(appCtx, serviceItem) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time) services.PricingDisplayParams); ok { - r1 = rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.MTOServiceItem) services.PricingDisplayParams); ok { + r1 = rf(appCtx, serviceItem) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(services.PricingDisplayParams) } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time) error); ok { - r2 = rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.MTOServiceItem) error); ok { + r2 = rf(appCtx, serviceItem) } else { r2 = ret.Error(2) } diff --git a/pkg/services/mocks/ManagementServicesPricer.go b/pkg/services/mocks/ManagementServicesPricer.go index 97df59714cd..51dfab7071f 100644 --- a/pkg/services/mocks/ManagementServicesPricer.go +++ b/pkg/services/mocks/ManagementServicesPricer.go @@ -10,8 +10,6 @@ import ( services "github.com/transcom/mymove/pkg/services" - time "time" - unit "github.com/transcom/mymove/pkg/unit" ) @@ -20,32 +18,32 @@ type ManagementServicesPricer struct { mock.Mock } -// Price provides a mock function with given fields: appCtx, contractCode, mtoAvailableToPrimeAt -func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, contractCode string, mtoAvailableToPrimeAt time.Time) (unit.Cents, services.PricingDisplayParams, error) { - ret := _m.Called(appCtx, contractCode, mtoAvailableToPrimeAt) +// Price provides a mock function with given fields: appCtx, serviceItem +func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, serviceItem) var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time) (unit.Cents, services.PricingDisplayParams, error)); ok { - return rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, serviceItem) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, string, time.Time) unit.Cents); ok { - r0 = rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) unit.Cents); ok { + r0 = rf(appCtx, serviceItem) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, string, time.Time) services.PricingDisplayParams); ok { - r1 = rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.MTOServiceItem) services.PricingDisplayParams); ok { + r1 = rf(appCtx, serviceItem) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(services.PricingDisplayParams) } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, string, time.Time) error); ok { - r2 = rf(appCtx, contractCode, mtoAvailableToPrimeAt) + if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.MTOServiceItem) error); ok { + r2 = rf(appCtx, serviceItem) } else { r2 = ret.Error(2) } From b45b5d03b025e2957094a6ca270172b83eb688c3 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Thu, 22 Aug 2024 15:11:58 +0000 Subject: [PATCH 04/19] Updating tests --- pkg/services/ghcrateengine/counseling_services_pricer.go | 6 ++---- pkg/services/ghcrateengine/management_services_pricer.go | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/services/ghcrateengine/counseling_services_pricer.go b/pkg/services/ghcrateengine/counseling_services_pricer.go index 4ab2a67cbc1..2337cf56c20 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer.go @@ -3,8 +3,6 @@ package ghcrateengine import ( "fmt" - "github.com/gofrs/uuid" - "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" @@ -47,8 +45,8 @@ func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, } } - if serviceItem.ID == uuid.Nil { - return unit.Cents(0), nil, fmt.Errorf("could not find id for shipment") + if serviceItem.LockedPriceCents == nil { + return unit.Cents(0), nil, fmt.Errorf("Service item did not contain value for locked price cents") } return p.Price(appCtx, serviceItem) diff --git a/pkg/services/ghcrateengine/management_services_pricer.go b/pkg/services/ghcrateengine/management_services_pricer.go index d6cd107fb0f..43aa68086d9 100644 --- a/pkg/services/ghcrateengine/management_services_pricer.go +++ b/pkg/services/ghcrateengine/management_services_pricer.go @@ -3,8 +3,6 @@ package ghcrateengine import ( "fmt" - "github.com/gofrs/uuid" - "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" @@ -47,8 +45,8 @@ func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, } } - if serviceItem.ID == uuid.Nil { - return unit.Cents(0), nil, fmt.Errorf("could not find id for shipment") + if serviceItem.LockedPriceCents == nil { + return unit.Cents(0), nil, fmt.Errorf("Service item did not contain value for locked price cents") } return p.Price(appCtx, serviceItem) From fa82b8ad3e24df9c7995bf876eda2eeb4c4e314c Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Thu, 22 Aug 2024 16:54:27 +0000 Subject: [PATCH 05/19] Adding lockedPriceCents to mtoServiceItem test gen --- pkg/factory/mto_service_item_factory.go | 4 ++++ .../ghcrateengine/counseling_services_pricer.go | 2 +- .../counseling_services_pricer_test.go | 14 ++++++++------ .../ghcrateengine/management_services_pricer.go | 2 +- .../management_services_pricer_test.go | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pkg/factory/mto_service_item_factory.go b/pkg/factory/mto_service_item_factory.go index 2ec6548b02b..d1cb056ed34 100644 --- a/pkg/factory/mto_service_item_factory.go +++ b/pkg/factory/mto_service_item_factory.go @@ -9,6 +9,7 @@ import ( "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/testdatagen" + "github.com/transcom/mymove/pkg/unit" ) type mtoServiceItemBuildType byte @@ -56,6 +57,8 @@ func buildMTOServiceItemWithBuildType(db *pop.Connection, customs []Customizatio requestedApprovalsRequestedStatus := false + var lockedPriceCents = unit.Cents(12303) + // Create default MTOServiceItem mtoServiceItem := models.MTOServiceItem{ MoveTaskOrder: move, @@ -67,6 +70,7 @@ func buildMTOServiceItemWithBuildType(db *pop.Connection, customs []Customizatio Status: models.MTOServiceItemStatusSubmitted, RequestedApprovalsRequestedStatus: &requestedApprovalsRequestedStatus, CustomerExpense: isCustomerExpense, + LockedPriceCents: &lockedPriceCents, } // only set SITOriginHHGOriginalAddress if a customization is provided diff --git a/pkg/services/ghcrateengine/counseling_services_pricer.go b/pkg/services/ghcrateengine/counseling_services_pricer.go index 2337cf56c20..c6260224c3f 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer.go @@ -46,7 +46,7 @@ func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, } if serviceItem.LockedPriceCents == nil { - return unit.Cents(0), nil, fmt.Errorf("Service item did not contain value for locked price cents") + return unit.Cents(0), nil, fmt.Errorf("service item did not contain value for locked price cents") } return p.Price(appCtx, serviceItem) diff --git a/pkg/services/ghcrateengine/counseling_services_pricer_test.go b/pkg/services/ghcrateengine/counseling_services_pricer_test.go index c0098764a82..a55b5355e58 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer_test.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer_test.go @@ -11,27 +11,29 @@ import ( ) const ( - csPriceCents = unit.Cents(8327) + csPriceCents = unit.Cents(12303) ) var csAvailableToPrimeAt = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) -var lockedPriceCents = unit.Cents(8327) - +var lockedPriceCents = unit.Cents(12303) var mtoServiceItem = models.MTOServiceItem{ LockedPriceCents: &lockedPriceCents, } +var failedMtoServiceItem = models.MTOServiceItem{ + LockedPriceCents: nil, +} + func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { counselingServicesPricer := NewCounselingServicesPricer() suite.Run("success using PaymentServiceItemParams", func() { - suite.setupTaskOrderFeeData(models.ReServiceCodeCS, csPriceCents) paymentServiceItem := suite.setupCounselingServicesItem() priceCents, displayParams, err := counselingServicesPricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) suite.NoError(err) - suite.Equal(csPriceCents, priceCents) + suite.Equal(lockedPriceCents, priceCents) // Check that PricingDisplayParams have been set and are returned expectedParams := services.PricingDisplayParams{ @@ -56,7 +58,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { }) suite.Run("not finding a rate record", func() { - _, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) + _, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), failedMtoServiceItem) suite.Error(err) }) } diff --git a/pkg/services/ghcrateengine/management_services_pricer.go b/pkg/services/ghcrateengine/management_services_pricer.go index 43aa68086d9..dc41a9e3e87 100644 --- a/pkg/services/ghcrateengine/management_services_pricer.go +++ b/pkg/services/ghcrateengine/management_services_pricer.go @@ -46,7 +46,7 @@ func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, } if serviceItem.LockedPriceCents == nil { - return unit.Cents(0), nil, fmt.Errorf("Service item did not contain value for locked price cents") + return unit.Cents(0), nil, fmt.Errorf("service item did not contain value for locked price cents") } return p.Price(appCtx, serviceItem) diff --git a/pkg/services/ghcrateengine/management_services_pricer_test.go b/pkg/services/ghcrateengine/management_services_pricer_test.go index 05abcfcb2de..784445d610c 100644 --- a/pkg/services/ghcrateengine/management_services_pricer_test.go +++ b/pkg/services/ghcrateengine/management_services_pricer_test.go @@ -54,7 +54,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) managementServicesPricer := NewManagementServicesPricer() - _, _, err := managementServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) + _, _, err := managementServicesPricer.Price(suite.AppContextForTest(), failedMtoServiceItem) suite.Error(err) }) } From f3b052642528899cf5abbf029dbc0482a473d949 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Thu, 22 Aug 2024 17:15:56 +0000 Subject: [PATCH 06/19] Updating recalculation test --- .../payment_request_recalculator_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/services/payment_request/payment_request_recalculator_test.go b/pkg/services/payment_request/payment_request_recalculator_test.go index 82da8ed74c2..924c1f02170 100644 --- a/pkg/services/payment_request/payment_request_recalculator_test.go +++ b/pkg/services/payment_request/payment_request_recalculator_test.go @@ -23,8 +23,8 @@ import ( const ( recalculateTestPickupZip = "30907" recalculateTestDestinationZip = "78234" - recalculateTestMSFee = unit.Cents(25513) - recalculateTestCSFee = unit.Cents(22399) + recalculateTestMSFee = unit.Cents(12303) + recalculateTestCSFee = unit.Cents(12303) recalculateTestDLHPrice = unit.Millicents(6000) recalculateTestFSCPrice = unit.Millicents(277600) recalculateTestDomOtherPrice = unit.Cents(2159) @@ -154,12 +154,12 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() { paymentRequest: &oldPaymentRequest, serviceCode: models.ReServiceCodeMS, - priceCents: unit.Cents(25513), + priceCents: unit.Cents(12303), }, { paymentRequest: &oldPaymentRequest, serviceCode: models.ReServiceCodeCS, - priceCents: unit.Cents(22399), + priceCents: unit.Cents(12303), }, { paymentRequest: &oldPaymentRequest, @@ -196,13 +196,13 @@ func (suite *PaymentRequestServiceSuite) TestRecalculatePaymentRequestSuccess() isNewPaymentRequest: true, paymentRequest: newPaymentRequest, serviceCode: models.ReServiceCodeMS, - priceCents: unit.Cents(25513), + priceCents: unit.Cents(12303), }, { isNewPaymentRequest: true, paymentRequest: newPaymentRequest, serviceCode: models.ReServiceCodeCS, - priceCents: unit.Cents(22399), + priceCents: unit.Cents(12303), }, { isNewPaymentRequest: true, From eb01f3f397941696ea7d7ce5cbcc17af7ff612c7 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Fri, 23 Aug 2024 14:39:38 +0000 Subject: [PATCH 07/19] Updating how ms and cs service itemsare priced --- migrations/app/migrations_manifest.txt | 1 + ...ng_locked_price_cents_for_ms_and_cs.up.sql | 5 +++ ...ng_locked_price_cents_service_param.up.sql | 14 ++++++++ pkg/factory/mto_service_item_factory.go | 12 +++++-- pkg/gen/ghcapi/embedded_spec.go | 6 ++-- .../ghcmessages/service_item_param_name.go | 5 ++- pkg/gen/primeapi/embedded_spec.go | 6 ++-- .../primemessages/service_item_param_name.go | 5 ++- pkg/gen/primev2api/embedded_spec.go | 6 ++-- .../service_item_param_name.go | 5 ++- pkg/gen/primev3api/embedded_spec.go | 6 ++-- .../service_item_param_name.go | 5 ++- pkg/handlers/ghcapi/mto_service_items.go | 4 +-- pkg/models/service_item_param_key.go | 4 +++ .../locked_price_cents_lookup.go | 21 ++++++++++++ .../service_param_value_lookups.go | 5 +++ pkg/services/ghc_rate_engine.go | 4 +-- .../counseling_services_pricer.go | 29 +++++------------ .../counseling_services_pricer_test.go | 32 +++---------------- .../management_services_pricer.go | 29 +++++------------ .../management_services_pricer_test.go | 24 ++------------ .../ghcrateengine/service_item_pricer_test.go | 9 ++---- .../mocks/CounselingServicesPricer.go | 22 ++++++------- .../mocks/ManagementServicesPricer.go | 22 ++++++------- .../definitions/ServiceItemParamName.yaml | 1 + swagger/ghc.yaml | 1 + swagger/prime.yaml | 1 + swagger/prime_v2.yaml | 1 + swagger/prime_v3.yaml | 1 + 29 files changed, 148 insertions(+), 138 deletions(-) create mode 100644 migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql create mode 100644 pkg/payment_request/service_param_value_lookups/locked_price_cents_lookup.go diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index bb5958dd21a..5ac95f73208 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -980,3 +980,4 @@ 20240814144527_remove_allow_pptas_client.up.sql 20240820125856_allow_pptas_migration.up.sql 20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql +20240822180409_adding_locked_price_cents_service_param.up.sql diff --git a/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql b/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql index 08b89a8baf8..e4f686802a2 100644 --- a/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql +++ b/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql @@ -1,3 +1,8 @@ +-- Customer directed that the current pricing_estimate should be saved as the locked_price for MS and CS +SET statement_timeout = 300000; +SET lock_timeout = 300000; +SET idle_in_transaction_session_timeout = 300000; + UPDATE mto_service_items AS ms SET locked_price_cents = pricing_estimate FROM re_services AS r diff --git a/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql b/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql new file mode 100644 index 00000000000..648d8be964f --- /dev/null +++ b/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql @@ -0,0 +1,14 @@ +INSERT INTO service_item_param_keys +(id,key,description,type,origin,created_at,updated_at) +VALUES +('7ec5cf87-a446-4dd6-89d3-50bbc0d2c206','LockedPriceCents', 'Locked price when move was made available to prime', 'INTEGER', 'SYSTEM', now(), now()); + +INSERT INTO service_params +(id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) +VALUES +('22056106-bbde-4ae7-b5bd-e7d2f103ab7d',(SELECT id FROM re_services WHERE code='MS'),(SELECT id FROM service_item_param_keys where key='LockedPriceCents'), now(), now(), 'false'); + +INSERT INTO service_params +(id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) +VALUES +('86f8c20c-071e-4715-b0c1-608f540b3be3',(SELECT id FROM re_services WHERE code='CS'),(SELECT id FROM service_item_param_keys where key='LockedPriceCents'), now(), now(), 'false'); \ No newline at end of file diff --git a/pkg/factory/mto_service_item_factory.go b/pkg/factory/mto_service_item_factory.go index d1cb056ed34..bbe328ed60e 100644 --- a/pkg/factory/mto_service_item_factory.go +++ b/pkg/factory/mto_service_item_factory.go @@ -345,15 +345,23 @@ var ( Type: models.ServiceItemParamTypeString, Origin: models.ServiceItemParamOriginPrime, } + paramLockedPriceCents = models.ServiceItemParamKey{ + Key: models.ServiceItemParamNameLockedPriceCents, + Description: "locked price cents", + Type: models.ServiceItemParamTypeTimestamp, + Origin: models.ServiceItemParamOriginSystem, + } fixtureServiceItemParamsMap = map[models.ReServiceCode]models.ServiceItemParamKeys{ models.ReServiceCodeCS: { - paramContractCode, paramMTOAvailableAToPrimeAt, + paramContractCode, + paramLockedPriceCents, paramPriceRateOrFactor, }, models.ReServiceCodeMS: { - paramContractCode, paramMTOAvailableAToPrimeAt, + paramContractCode, + paramLockedPriceCents, paramPriceRateOrFactor, }, models.ReServiceCodeDLH: { diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 9d9d4e674bd..1f89a09afcd 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -11959,7 +11959,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { @@ -27032,7 +27033,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { diff --git a/pkg/gen/ghcmessages/service_item_param_name.go b/pkg/gen/ghcmessages/service_item_param_name.go index dd10c8003cd..eff0f3d2734 100644 --- a/pkg/gen/ghcmessages/service_item_param_name.go +++ b/pkg/gen/ghcmessages/service_item_param_name.go @@ -236,6 +236,9 @@ const ( // ServiceItemParamNameUncappedRequestTotal captures enum value "UncappedRequestTotal" ServiceItemParamNameUncappedRequestTotal ServiceItemParamName = "UncappedRequestTotal" + + // ServiceItemParamNameLockedPriceCents captures enum value "LockedPriceCents" + ServiceItemParamNameLockedPriceCents ServiceItemParamName = "LockedPriceCents" ) // for schema @@ -243,7 +246,7 @@ var serviceItemParamNameEnum []interface{} func init() { var res []ServiceItemParamName - if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal","LockedPriceCents"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index 7a8b33c22c2..91649679893 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -3877,7 +3877,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { @@ -8994,7 +8995,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { diff --git a/pkg/gen/primemessages/service_item_param_name.go b/pkg/gen/primemessages/service_item_param_name.go index 7f8e128b151..d43a63a69f7 100644 --- a/pkg/gen/primemessages/service_item_param_name.go +++ b/pkg/gen/primemessages/service_item_param_name.go @@ -236,6 +236,9 @@ const ( // ServiceItemParamNameUncappedRequestTotal captures enum value "UncappedRequestTotal" ServiceItemParamNameUncappedRequestTotal ServiceItemParamName = "UncappedRequestTotal" + + // ServiceItemParamNameLockedPriceCents captures enum value "LockedPriceCents" + ServiceItemParamNameLockedPriceCents ServiceItemParamName = "LockedPriceCents" ) // for schema @@ -243,7 +246,7 @@ var serviceItemParamNameEnum []interface{} func init() { var res []ServiceItemParamName - if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal","LockedPriceCents"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primev2api/embedded_spec.go b/pkg/gen/primev2api/embedded_spec.go index 6faf8bd65f4..40a2b4dd594 100644 --- a/pkg/gen/primev2api/embedded_spec.go +++ b/pkg/gen/primev2api/embedded_spec.go @@ -2610,7 +2610,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { @@ -6054,7 +6055,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { diff --git a/pkg/gen/primev2messages/service_item_param_name.go b/pkg/gen/primev2messages/service_item_param_name.go index a6939ad00f4..fb2d4097030 100644 --- a/pkg/gen/primev2messages/service_item_param_name.go +++ b/pkg/gen/primev2messages/service_item_param_name.go @@ -236,6 +236,9 @@ const ( // ServiceItemParamNameUncappedRequestTotal captures enum value "UncappedRequestTotal" ServiceItemParamNameUncappedRequestTotal ServiceItemParamName = "UncappedRequestTotal" + + // ServiceItemParamNameLockedPriceCents captures enum value "LockedPriceCents" + ServiceItemParamNameLockedPriceCents ServiceItemParamName = "LockedPriceCents" ) // for schema @@ -243,7 +246,7 @@ var serviceItemParamNameEnum []interface{} func init() { var res []ServiceItemParamName - if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal","LockedPriceCents"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index ec5ecd2374b..f1475093cda 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -2658,7 +2658,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { @@ -6194,7 +6195,8 @@ func init() { "ZipSITOriginHHGOriginalAddress", "StandaloneCrate", "StandaloneCrateCap", - "UncappedRequestTotal" + "UncappedRequestTotal", + "LockedPriceCents" ] }, "ServiceItemParamOrigin": { diff --git a/pkg/gen/primev3messages/service_item_param_name.go b/pkg/gen/primev3messages/service_item_param_name.go index ab53b71f111..a7e2fdf7ea3 100644 --- a/pkg/gen/primev3messages/service_item_param_name.go +++ b/pkg/gen/primev3messages/service_item_param_name.go @@ -236,6 +236,9 @@ const ( // ServiceItemParamNameUncappedRequestTotal captures enum value "UncappedRequestTotal" ServiceItemParamNameUncappedRequestTotal ServiceItemParamName = "UncappedRequestTotal" + + // ServiceItemParamNameLockedPriceCents captures enum value "LockedPriceCents" + ServiceItemParamNameLockedPriceCents ServiceItemParamName = "LockedPriceCents" ) // for schema @@ -243,7 +246,7 @@ var serviceItemParamNameEnum []interface{} func init() { var res []ServiceItemParamName - if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["ActualPickupDate","ContractCode","ContractYearName","CubicFeetBilled","CubicFeetCrating","DimensionHeight","DimensionLength","DimensionWidth","DistanceZip","DistanceZipSITDest","DistanceZipSITOrigin","EIAFuelPrice","EscalationCompounded","FSCMultiplier","FSCPriceDifferenceInCents","FSCWeightBasedDistanceMultiplier","IsPeak","MarketDest","MarketOrigin","MTOAvailableToPrimeAt","NTSPackingFactor","NumberDaysSIT","PriceAreaDest","PriceAreaIntlDest","PriceAreaIntlOrigin","PriceAreaOrigin","PriceRateOrFactor","PSI_LinehaulDom","PSI_LinehaulDomPrice","PSI_LinehaulShort","PSI_LinehaulShortPrice","PSI_PriceDomDest","PSI_PriceDomDestPrice","PSI_PriceDomOrigin","PSI_PriceDomOriginPrice","PSI_ShippingLinehaulIntlCO","PSI_ShippingLinehaulIntlCOPrice","PSI_ShippingLinehaulIntlOC","PSI_ShippingLinehaulIntlOCPrice","PSI_ShippingLinehaulIntlOO","PSI_ShippingLinehaulIntlOOPrice","RateAreaNonStdDest","RateAreaNonStdOrigin","ReferenceDate","RequestedPickupDate","ServiceAreaDest","ServiceAreaOrigin","ServicesScheduleDest","ServicesScheduleOrigin","SITPaymentRequestEnd","SITPaymentRequestStart","SITScheduleDest","SITScheduleOrigin","SITServiceAreaDest","SITServiceAreaOrigin","WeightAdjusted","WeightBilled","WeightEstimated","WeightOriginal","WeightReweigh","ZipDestAddress","ZipPickupAddress","ZipSITDestHHGFinalAddress","ZipSITDestHHGOriginalAddress","ZipSITOriginHHGActualAddress","ZipSITOriginHHGOriginalAddress","StandaloneCrate","StandaloneCrateCap","UncappedRequestTotal","LockedPriceCents"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/pkg/handlers/ghcapi/mto_service_items.go b/pkg/handlers/ghcapi/mto_service_items.go index 910df4569ee..4a89afdc426 100644 --- a/pkg/handlers/ghcapi/mto_service_items.go +++ b/pkg/handlers/ghcapi/mto_service_items.go @@ -392,9 +392,9 @@ func (h ListMTOServiceItemsHandler) Handle(params mtoserviceitemop.ListMTOServic var displayParams services.PricingDisplayParams var err error if serviceItems[index].ReService.Code == "CS" { - price, displayParams, err = h.counselingPricer.Price(appCtx, serviceItems[index]) + price, displayParams, err = h.counselingPricer.Price(appCtx, *serviceItems[index].LockedPriceCents) } else if serviceItems[index].ReService.Code == "MS" { - price, displayParams, err = h.moveManagementPricer.Price(appCtx, serviceItems[index]) + price, displayParams, err = h.moveManagementPricer.Price(appCtx, *serviceItems[index].LockedPriceCents) } for _, param := range displayParams { diff --git a/pkg/models/service_item_param_key.go b/pkg/models/service_item_param_key.go index 6a708cb8f94..3bfd789dcc4 100644 --- a/pkg/models/service_item_param_key.go +++ b/pkg/models/service_item_param_key.go @@ -155,6 +155,8 @@ const ( ServiceItemParamNameStandaloneCrateCap ServiceItemParamName = "StandaloneCrateCap" // ServiceItemParamNameUncappedRequestTotal is the param key name UncappedRequestTotal ServiceItemParamNameUncappedRequestTotal ServiceItemParamName = "UncappedRequestTotal" + // ServiceItemParamNameLockedPriceCents is the param key name LockedPriceCents + ServiceItemParamNameLockedPriceCents ServiceItemParamName = "LockedPriceCents" ) // ServiceItemParamType is a type of service item parameter @@ -272,6 +274,7 @@ var ValidServiceItemParamNames = []ServiceItemParamName{ ServiceItemParamNameStandaloneCrate, ServiceItemParamNameStandaloneCrateCap, ServiceItemParamNameUncappedRequestTotal, + ServiceItemParamNameLockedPriceCents, } // ValidServiceItemParamNameStrings lists all valid service item param key names @@ -345,6 +348,7 @@ var ValidServiceItemParamNameStrings = []string{ string(ServiceItemParamNameStandaloneCrate), string(ServiceItemParamNameStandaloneCrateCap), string(ServiceItemParamNameUncappedRequestTotal), + string(ServiceItemParamNameLockedPriceCents), } // ValidServiceItemParamTypes lists all valid service item param types diff --git a/pkg/payment_request/service_param_value_lookups/locked_price_cents_lookup.go b/pkg/payment_request/service_param_value_lookups/locked_price_cents_lookup.go new file mode 100644 index 00000000000..f0a5dc62c49 --- /dev/null +++ b/pkg/payment_request/service_param_value_lookups/locked_price_cents_lookup.go @@ -0,0 +1,21 @@ +package serviceparamvaluelookups + +import ( + "github.com/transcom/mymove/pkg/appcontext" + "github.com/transcom/mymove/pkg/apperror" + "github.com/transcom/mymove/pkg/models" +) + +// LockedPriceCents does lookup on serviceItem +type LockedPriceCentsLookup struct { + ServiceItem models.MTOServiceItem +} + +func (r LockedPriceCentsLookup) lookup(appCtx appcontext.AppContext, _ *ServiceItemParamKeyData) (string, error) { + lockedPriceCents := r.ServiceItem.LockedPriceCents + if lockedPriceCents == nil { + return "0", apperror.NewConflictError(r.ServiceItem.ID, "unable to find locked price cents") + } + + return lockedPriceCents.ToMillicents().ToCents().String(), nil +} diff --git a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go index ca8d76e8881..d901bdf58cd 100644 --- a/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go +++ b/pkg/payment_request/service_param_value_lookups/service_param_value_lookups.go @@ -84,6 +84,7 @@ var ServiceItemParamsWithLookups = []models.ServiceItemParamName{ models.ServiceItemParamNameDimensionWidth, models.ServiceItemParamNameStandaloneCrate, models.ServiceItemParamNameStandaloneCrateCap, + models.ServiceItemParamNameLockedPriceCents, } // ServiceParamLookupInitialize initializes service parameter lookup @@ -425,6 +426,10 @@ func InitializeLookups(appCtx appcontext.AppContext, shipment models.MTOShipment ServiceItem: serviceItem, } + lookups[models.ServiceItemParamNameLockedPriceCents] = LockedPriceCentsLookup{ + ServiceItem: serviceItem, + } + return lookups } diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 5d9d2737bba..8393d6d1750 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -33,7 +33,7 @@ type ParamsPricer interface { // //go:generate mockery --name ManagementServicesPricer type ManagementServicesPricer interface { - Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, PricingDisplayParams, error) ParamsPricer } @@ -41,7 +41,7 @@ type ManagementServicesPricer interface { // //go:generate mockery --name CounselingServicesPricer type CounselingServicesPricer interface { - Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/counseling_services_pricer.go b/pkg/services/ghcrateengine/counseling_services_pricer.go index c6260224c3f..6ec7de65a14 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer.go @@ -1,8 +1,6 @@ package ghcrateengine import ( - "fmt" - "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" @@ -18,36 +16,25 @@ func NewCounselingServicesPricer() services.CounselingServicesPricer { } // Price determines the price for a counseling service -func (p managementServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { - - if serviceItem.LockedPriceCents == nil { - return unit.Cents(0), nil, fmt.Errorf("could not find locked price cents: %s", serviceItem.ID) - } +func (p counselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { params := services.PricingDisplayParams{ { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(*serviceItem.LockedPriceCents), + Value: FormatCents(lockedPriceCents), }, } - return *serviceItem.LockedPriceCents, params, nil + return lockedPriceCents, params, nil } // PriceUsingParams determines the price for a counseling service given PaymentServiceItemParams -func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { - - var serviceItem models.MTOServiceItem - for _, param := range params { - if param.PaymentServiceItem.MTOServiceItem.LockedPriceCents != nil { - serviceItem = param.PaymentServiceItem.MTOServiceItem - break - } - } +func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { - if serviceItem.LockedPriceCents == nil { - return unit.Cents(0), nil, fmt.Errorf("service item did not contain value for locked price cents") + lockedPriceCents, err := getParamInt(params, models.ServiceItemParamNameLockedPriceCents) + if err != nil { + return unit.Cents(0), nil, err } - return p.Price(appCtx, serviceItem) + return p.Price(appCtx, unit.Cents(lockedPriceCents)) } diff --git a/pkg/services/ghcrateengine/counseling_services_pricer_test.go b/pkg/services/ghcrateengine/counseling_services_pricer_test.go index a55b5355e58..644540c0450 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer_test.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer_test.go @@ -1,12 +1,9 @@ package ghcrateengine import ( - "time" - "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" - "github.com/transcom/mymove/pkg/testdatagen" "github.com/transcom/mymove/pkg/unit" ) @@ -14,17 +11,6 @@ const ( csPriceCents = unit.Cents(12303) ) -var csAvailableToPrimeAt = time.Date(testdatagen.TestYear, time.June, 5, 7, 33, 11, 456, time.UTC) - -var lockedPriceCents = unit.Cents(12303) -var mtoServiceItem = models.MTOServiceItem{ - LockedPriceCents: &lockedPriceCents, -} - -var failedMtoServiceItem = models.MTOServiceItem{ - LockedPriceCents: nil, -} - func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { counselingServicesPricer := NewCounselingServicesPricer() @@ -33,7 +19,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { priceCents, displayParams, err := counselingServicesPricer.PriceUsingParams(suite.AppContextForTest(), paymentServiceItem.PaymentServiceItemParams) suite.NoError(err) - suite.Equal(lockedPriceCents, priceCents) + suite.Equal(csPriceCents, priceCents) // Check that PricingDisplayParams have been set and are returned expectedParams := services.PricingDisplayParams{ @@ -45,7 +31,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { suite.Run("success without PaymentServiceItemParams", func() { suite.setupTaskOrderFeeData(models.ReServiceCodeCS, csPriceCents) - priceCents, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) + priceCents, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), csPriceCents) suite.NoError(err) suite.Equal(csPriceCents, priceCents) }) @@ -56,11 +42,6 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { _, _, err := counselingServicesPricer.PriceUsingParams(suite.AppContextForTest(), models.PaymentServiceItemParams{}) suite.Error(err) }) - - suite.Run("not finding a rate record", func() { - _, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), failedMtoServiceItem) - suite.Error(err) - }) } func (suite *GHCRateEngineServiceSuite) setupCounselingServicesItem() models.PaymentServiceItem { @@ -69,14 +50,9 @@ func (suite *GHCRateEngineServiceSuite) setupCounselingServicesItem() models.Pay models.ReServiceCodeCS, []factory.CreatePaymentServiceItemParams{ { - Key: models.ServiceItemParamNameContractCode, + Key: models.ServiceItemParamNameLockedPriceCents, KeyType: models.ServiceItemParamTypeString, - Value: factory.DefaultContractCode, - }, - { - Key: models.ServiceItemParamNameMTOAvailableToPrimeAt, - KeyType: models.ServiceItemParamTypeTimestamp, - Value: csAvailableToPrimeAt.Format(TimestampParamFormat), + Value: csPriceCents.ToMillicents().ToCents().String(), }, }, nil, nil, ) diff --git a/pkg/services/ghcrateengine/management_services_pricer.go b/pkg/services/ghcrateengine/management_services_pricer.go index dc41a9e3e87..31a23729e94 100644 --- a/pkg/services/ghcrateengine/management_services_pricer.go +++ b/pkg/services/ghcrateengine/management_services_pricer.go @@ -1,8 +1,6 @@ package ghcrateengine import ( - "fmt" - "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" @@ -18,36 +16,25 @@ func NewManagementServicesPricer() services.ManagementServicesPricer { } // Price determines the price for a management service -func (p counselingServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { - - if serviceItem.LockedPriceCents == nil { - return unit.Cents(0), nil, fmt.Errorf("could not find locked price cents: %s", serviceItem.ID) - } +func (p managementServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { params := services.PricingDisplayParams{ { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(*serviceItem.LockedPriceCents), + Value: FormatCents(lockedPriceCents), }, } - return *serviceItem.LockedPriceCents, params, nil + return lockedPriceCents, params, nil } // PriceUsingParams determines the price for a management service given PaymentServiceItemParams -func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { - - var serviceItem models.MTOServiceItem - for _, param := range params { - if param.PaymentServiceItem.MTOServiceItem.LockedPriceCents != nil { - serviceItem = param.PaymentServiceItem.MTOServiceItem - break - } - } +func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, params models.PaymentServiceItemParams) (unit.Cents, services.PricingDisplayParams, error) { - if serviceItem.LockedPriceCents == nil { - return unit.Cents(0), nil, fmt.Errorf("service item did not contain value for locked price cents") + lockedPriceCents, err := getParamInt(params, models.ServiceItemParamNameLockedPriceCents) + if err != nil { + return unit.Cents(0), nil, err } - return p.Price(appCtx, serviceItem) + return p.Price(appCtx, unit.Cents(lockedPriceCents)) } diff --git a/pkg/services/ghcrateengine/management_services_pricer_test.go b/pkg/services/ghcrateengine/management_services_pricer_test.go index 784445d610c..389aac4639e 100644 --- a/pkg/services/ghcrateengine/management_services_pricer_test.go +++ b/pkg/services/ghcrateengine/management_services_pricer_test.go @@ -1,12 +1,9 @@ package ghcrateengine import ( - "time" - "github.com/transcom/mymove/pkg/factory" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" - "github.com/transcom/mymove/pkg/testdatagen" "github.com/transcom/mymove/pkg/unit" ) @@ -14,8 +11,6 @@ const ( msPriceCents = unit.Cents(12303) ) -var msAvailableToPrimeAt = time.Date(testdatagen.TestYear, time.June, 3, 12, 57, 33, 123, time.UTC) - func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { suite.Run("success using PaymentServiceItemParams", func() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) @@ -37,7 +32,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) managementServicesPricer := NewManagementServicesPricer() - priceCents, _, err := managementServicesPricer.Price(suite.AppContextForTest(), mtoServiceItem) + priceCents, _, err := managementServicesPricer.Price(suite.AppContextForTest(), msPriceCents) suite.NoError(err) suite.Equal(msPriceCents, priceCents) }) @@ -49,14 +44,6 @@ func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { _, _, err := managementServicesPricer.PriceUsingParams(suite.AppContextForTest(), models.PaymentServiceItemParams{}) suite.Error(err) }) - - suite.Run("not finding a rate record", func() { - suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) - managementServicesPricer := NewManagementServicesPricer() - - _, _, err := managementServicesPricer.Price(suite.AppContextForTest(), failedMtoServiceItem) - suite.Error(err) - }) } func (suite *GHCRateEngineServiceSuite) setupManagementServicesItem() models.PaymentServiceItem { @@ -65,14 +52,9 @@ func (suite *GHCRateEngineServiceSuite) setupManagementServicesItem() models.Pay models.ReServiceCodeMS, []factory.CreatePaymentServiceItemParams{ { - Key: models.ServiceItemParamNameContractCode, + Key: models.ServiceItemParamNameLockedPriceCents, KeyType: models.ServiceItemParamTypeString, - Value: factory.DefaultContractCode, - }, - { - Key: models.ServiceItemParamNameMTOAvailableToPrimeAt, - KeyType: models.ServiceItemParamTypeTimestamp, - Value: msAvailableToPrimeAt.Format(TimestampParamFormat), + Value: msPriceCents.ToMillicents().ToCents().String(), }, }, nil, nil, ) diff --git a/pkg/services/ghcrateengine/service_item_pricer_test.go b/pkg/services/ghcrateengine/service_item_pricer_test.go index ca9ae0cb724..29fd281cf48 100644 --- a/pkg/services/ghcrateengine/service_item_pricer_test.go +++ b/pkg/services/ghcrateengine/service_item_pricer_test.go @@ -115,14 +115,9 @@ func (suite *GHCRateEngineServiceSuite) setupPriceServiceItem() models.PaymentSe models.ReServiceCodeMS, []factory.CreatePaymentServiceItemParams{ { - Key: models.ServiceItemParamNameContractCode, + Key: models.ServiceItemParamNameLockedPriceCents, KeyType: models.ServiceItemParamTypeString, - Value: factory.DefaultContractCode, - }, - { - Key: models.ServiceItemParamNameMTOAvailableToPrimeAt, - KeyType: models.ServiceItemParamTypeTimestamp, - Value: msAvailableToPrimeAt.Format(TimestampParamFormat), + Value: msPriceCents.ToMillicents().ToCents().String(), }, }, nil, nil, ) diff --git a/pkg/services/mocks/CounselingServicesPricer.go b/pkg/services/mocks/CounselingServicesPricer.go index 2f6cc2cf375..51d2964ac42 100644 --- a/pkg/services/mocks/CounselingServicesPricer.go +++ b/pkg/services/mocks/CounselingServicesPricer.go @@ -18,32 +18,32 @@ type CounselingServicesPricer struct { mock.Mock } -// Price provides a mock function with given fields: appCtx, serviceItem -func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { - ret := _m.Called(appCtx, serviceItem) +// Price provides a mock function with given fields: appCtx, lockedPriceCents +func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, lockedPriceCents) var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error)); ok { - return rf(appCtx, serviceItem) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, lockedPriceCents) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) unit.Cents); ok { - r0 = rf(appCtx, serviceItem) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) unit.Cents); ok { + r0 = rf(appCtx, lockedPriceCents) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.MTOServiceItem) services.PricingDisplayParams); ok { - r1 = rf(appCtx, serviceItem) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, unit.Cents) services.PricingDisplayParams); ok { + r1 = rf(appCtx, lockedPriceCents) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(services.PricingDisplayParams) } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.MTOServiceItem) error); ok { - r2 = rf(appCtx, serviceItem) + if rf, ok := ret.Get(2).(func(appcontext.AppContext, unit.Cents) error); ok { + r2 = rf(appCtx, lockedPriceCents) } else { r2 = ret.Error(2) } diff --git a/pkg/services/mocks/ManagementServicesPricer.go b/pkg/services/mocks/ManagementServicesPricer.go index 51dfab7071f..e361159de6e 100644 --- a/pkg/services/mocks/ManagementServicesPricer.go +++ b/pkg/services/mocks/ManagementServicesPricer.go @@ -18,32 +18,32 @@ type ManagementServicesPricer struct { mock.Mock } -// Price provides a mock function with given fields: appCtx, serviceItem -func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, serviceItem models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error) { - ret := _m.Called(appCtx, serviceItem) +// Price provides a mock function with given fields: appCtx, lockedPriceCents +func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { + ret := _m.Called(appCtx, lockedPriceCents) var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) (unit.Cents, services.PricingDisplayParams, error)); ok { - return rf(appCtx, serviceItem) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) (unit.Cents, services.PricingDisplayParams, error)); ok { + return rf(appCtx, lockedPriceCents) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, models.MTOServiceItem) unit.Cents); ok { - r0 = rf(appCtx, serviceItem) + if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) unit.Cents); ok { + r0 = rf(appCtx, lockedPriceCents) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, models.MTOServiceItem) services.PricingDisplayParams); ok { - r1 = rf(appCtx, serviceItem) + if rf, ok := ret.Get(1).(func(appcontext.AppContext, unit.Cents) services.PricingDisplayParams); ok { + r1 = rf(appCtx, lockedPriceCents) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(services.PricingDisplayParams) } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, models.MTOServiceItem) error); ok { - r2 = rf(appCtx, serviceItem) + if rf, ok := ret.Get(2).(func(appcontext.AppContext, unit.Cents) error); ok { + r2 = rf(appCtx, lockedPriceCents) } else { r2 = ret.Error(2) } diff --git a/swagger-def/definitions/ServiceItemParamName.yaml b/swagger-def/definitions/ServiceItemParamName.yaml index 066dd32d45e..c3361653fbe 100644 --- a/swagger-def/definitions/ServiceItemParamName.yaml +++ b/swagger-def/definitions/ServiceItemParamName.yaml @@ -69,3 +69,4 @@ enum: - StandaloneCrate - StandaloneCrateCap - UncappedRequestTotal + - LockedPriceCents diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index 860cea19349..7aa82ce8fe4 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -9924,6 +9924,7 @@ definitions: - StandaloneCrate - StandaloneCrateCap - UncappedRequestTotal + - LockedPriceCents ServiceItemParamType: type: string enum: diff --git a/swagger/prime.yaml b/swagger/prime.yaml index 9ece3012fa8..2fe5ba8f7ec 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -3430,6 +3430,7 @@ definitions: - StandaloneCrate - StandaloneCrateCap - UncappedRequestTotal + - LockedPriceCents ServiceItemParamType: type: string enum: diff --git a/swagger/prime_v2.yaml b/swagger/prime_v2.yaml index 28c98b3c65e..939993ca806 100644 --- a/swagger/prime_v2.yaml +++ b/swagger/prime_v2.yaml @@ -1730,6 +1730,7 @@ definitions: - StandaloneCrate - StandaloneCrateCap - UncappedRequestTotal + - LockedPriceCents ServiceItemParamType: type: string enum: diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index 889f0808ad6..fc9f69ecd7a 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -1754,6 +1754,7 @@ definitions: - StandaloneCrate - StandaloneCrateCap - UncappedRequestTotal + - LockedPriceCents ServiceItemParamType: type: string enum: From 8f66f074cddffabaea976470f412b7e7557bd8cb Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Fri, 23 Aug 2024 17:00:38 +0000 Subject: [PATCH 08/19] Fixing management services pricer tests --- .../counseling_services_pricer_test.go | 2 +- .../management_services_pricer_test.go | 2 +- .../ghcrateengine/service_item_pricer_test.go | 2 +- .../payment_request_recalculator_test.go | 18 ------------------ 4 files changed, 3 insertions(+), 21 deletions(-) diff --git a/pkg/services/ghcrateengine/counseling_services_pricer_test.go b/pkg/services/ghcrateengine/counseling_services_pricer_test.go index 644540c0450..1ca6de8b660 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer_test.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer_test.go @@ -51,7 +51,7 @@ func (suite *GHCRateEngineServiceSuite) setupCounselingServicesItem() models.Pay []factory.CreatePaymentServiceItemParams{ { Key: models.ServiceItemParamNameLockedPriceCents, - KeyType: models.ServiceItemParamTypeString, + KeyType: models.ServiceItemParamTypeInteger, Value: csPriceCents.ToMillicents().ToCents().String(), }, }, nil, nil, diff --git a/pkg/services/ghcrateengine/management_services_pricer_test.go b/pkg/services/ghcrateengine/management_services_pricer_test.go index 389aac4639e..be068473c20 100644 --- a/pkg/services/ghcrateengine/management_services_pricer_test.go +++ b/pkg/services/ghcrateengine/management_services_pricer_test.go @@ -53,7 +53,7 @@ func (suite *GHCRateEngineServiceSuite) setupManagementServicesItem() models.Pay []factory.CreatePaymentServiceItemParams{ { Key: models.ServiceItemParamNameLockedPriceCents, - KeyType: models.ServiceItemParamTypeString, + KeyType: models.ServiceItemParamTypeInteger, Value: msPriceCents.ToMillicents().ToCents().String(), }, }, nil, nil, diff --git a/pkg/services/ghcrateengine/service_item_pricer_test.go b/pkg/services/ghcrateengine/service_item_pricer_test.go index 29fd281cf48..6ebfec34a29 100644 --- a/pkg/services/ghcrateengine/service_item_pricer_test.go +++ b/pkg/services/ghcrateengine/service_item_pricer_test.go @@ -116,7 +116,7 @@ func (suite *GHCRateEngineServiceSuite) setupPriceServiceItem() models.PaymentSe []factory.CreatePaymentServiceItemParams{ { Key: models.ServiceItemParamNameLockedPriceCents, - KeyType: models.ServiceItemParamTypeString, + KeyType: models.ServiceItemParamTypeInteger, Value: msPriceCents.ToMillicents().ToCents().String(), }, }, nil, nil, diff --git a/pkg/services/payment_request/payment_request_recalculator_test.go b/pkg/services/payment_request/payment_request_recalculator_test.go index 924c1f02170..55b4a2ec47c 100644 --- a/pkg/services/payment_request/payment_request_recalculator_test.go +++ b/pkg/services/payment_request/payment_request_recalculator_test.go @@ -407,24 +407,6 @@ func (suite *PaymentRequestServiceSuite) setupRecalculateData1() (models.Move, m }, }) - // MS price data - msService := factory.BuildReServiceByCode(suite.DB(), models.ReServiceCodeMS) - msTaskOrderFee := models.ReTaskOrderFee{ - ContractYearID: contractYear.ID, - ServiceID: msService.ID, - PriceCents: recalculateTestMSFee, - } - suite.MustSave(&msTaskOrderFee) - - // CS price data - csService := factory.BuildReServiceByCode(suite.DB(), models.ReServiceCodeCS) - csTaskOrderFee := models.ReTaskOrderFee{ - ContractYearID: contractYear.ID, - ServiceID: csService.ID, - PriceCents: recalculateTestCSFee, - } - suite.MustSave(&csTaskOrderFee) - // DLH price data testdatagen.MakeReDomesticLinehaulPrice(suite.DB(), testdatagen.Assertions{ ReDomesticLinehaulPrice: models.ReDomesticLinehaulPrice{ From f76ac5d456c7cb71b32f3c9e360559565501b900 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Fri, 23 Aug 2024 17:52:32 +0000 Subject: [PATCH 09/19] Fixing lockedPriceCents gen type --- pkg/factory/mto_service_item_factory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/factory/mto_service_item_factory.go b/pkg/factory/mto_service_item_factory.go index bbe328ed60e..c39d7680d4b 100644 --- a/pkg/factory/mto_service_item_factory.go +++ b/pkg/factory/mto_service_item_factory.go @@ -348,7 +348,7 @@ var ( paramLockedPriceCents = models.ServiceItemParamKey{ Key: models.ServiceItemParamNameLockedPriceCents, Description: "locked price cents", - Type: models.ServiceItemParamTypeTimestamp, + Type: models.ServiceItemParamTypeInteger, Origin: models.ServiceItemParamOriginSystem, } fixtureServiceItemParamsMap = map[models.ReServiceCode]models.ServiceItemParamKeys{ From 057d32b5f56dfcc926b4288e9ee50c65150b7efd Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Thu, 5 Sep 2024 20:52:02 +0000 Subject: [PATCH 10/19] fixing issue with unpopulated price_estimates on older moves --- migrations/app/migrations_manifest.txt | 1 + ...ces_to_unpriced_cs_ms_service_items.up.sql | 28 +++++++++++++++++++ pkg/handlers/ghcapi/mto_service_items.go | 4 +-- pkg/services/ghc_rate_engine.go | 4 +-- .../counseling_services_pricer.go | 15 +++++++--- .../counseling_services_pricer_test.go | 3 +- .../management_services_pricer.go | 15 +++++++--- .../management_services_pricer_test.go | 3 +- .../mocks/CounselingServicesPricer.go | 10 +++---- .../mocks/ManagementServicesPricer.go | 10 +++---- 10 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 5ac95f73208..7bdf1dce58a 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -981,3 +981,4 @@ 20240820125856_allow_pptas_migration.up.sql 20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql 20240822180409_adding_locked_price_cents_service_param.up.sql +20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql diff --git a/migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql b/migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql new file mode 100644 index 00000000000..a3172cc10c5 --- /dev/null +++ b/migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql @@ -0,0 +1,28 @@ +-- Filling in pricing_estimates for unprices services code MS and CS service items. Service items should not be able to reach this state +-- but some older data exists where unpriced MS and CS items exist +SET statement_timeout = 300000; +SET lock_timeout = 300000; +SET idle_in_transaction_session_timeout = 300000; + +UPDATE mto_service_items AS ms +SET locked_price_cents = + CASE + when price_cents > 0 then price_cents + when price_cents <= 0 then 0 + END, + pricing_estimate = + CASE + when price_cents > 0 then price_cents + when price_cents <= 0 then 0 + END +FROM re_task_order_fees AS tf +JOIN re_contract_years AS cy +ON tf.contract_year_id = cy.id +JOIN re_contracts AS c +ON cy.contract_id = c.id +JOIN re_services AS s +ON tf.service_id = s.id +WHERE ms.locked_price_cents = null + AND ms.pricing_estimate = null + AND re_service_id = s.id + AND s.code = 'MS' OR s.code = 'CS' \ No newline at end of file diff --git a/pkg/handlers/ghcapi/mto_service_items.go b/pkg/handlers/ghcapi/mto_service_items.go index 4a89afdc426..33b34ae1373 100644 --- a/pkg/handlers/ghcapi/mto_service_items.go +++ b/pkg/handlers/ghcapi/mto_service_items.go @@ -392,9 +392,9 @@ func (h ListMTOServiceItemsHandler) Handle(params mtoserviceitemop.ListMTOServic var displayParams services.PricingDisplayParams var err error if serviceItems[index].ReService.Code == "CS" { - price, displayParams, err = h.counselingPricer.Price(appCtx, *serviceItems[index].LockedPriceCents) + price, displayParams, err = h.counselingPricer.Price(appCtx, serviceItems[index].LockedPriceCents) } else if serviceItems[index].ReService.Code == "MS" { - price, displayParams, err = h.moveManagementPricer.Price(appCtx, *serviceItems[index].LockedPriceCents) + price, displayParams, err = h.moveManagementPricer.Price(appCtx, serviceItems[index].LockedPriceCents) } for _, param := range displayParams { diff --git a/pkg/services/ghc_rate_engine.go b/pkg/services/ghc_rate_engine.go index 8393d6d1750..5d17e0388ce 100644 --- a/pkg/services/ghc_rate_engine.go +++ b/pkg/services/ghc_rate_engine.go @@ -33,7 +33,7 @@ type ParamsPricer interface { // //go:generate mockery --name ManagementServicesPricer type ManagementServicesPricer interface { - Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, lockedPriceCents *unit.Cents) (unit.Cents, PricingDisplayParams, error) ParamsPricer } @@ -41,7 +41,7 @@ type ManagementServicesPricer interface { // //go:generate mockery --name CounselingServicesPricer type CounselingServicesPricer interface { - Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, PricingDisplayParams, error) + Price(appCtx appcontext.AppContext, lockedPriceCents *unit.Cents) (unit.Cents, PricingDisplayParams, error) ParamsPricer } diff --git a/pkg/services/ghcrateengine/counseling_services_pricer.go b/pkg/services/ghcrateengine/counseling_services_pricer.go index 6ec7de65a14..f695e9753c3 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer.go @@ -1,6 +1,8 @@ package ghcrateengine import ( + "fmt" + "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" @@ -16,16 +18,20 @@ func NewCounselingServicesPricer() services.CounselingServicesPricer { } // Price determines the price for a counseling service -func (p counselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { +func (p counselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents *unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { + + if lockedPriceCents == nil { + return 0, nil, fmt.Errorf("invalid value for locked_price_cents") + } params := services.PricingDisplayParams{ { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(lockedPriceCents), + Value: FormatCents(*lockedPriceCents), }, } - return lockedPriceCents, params, nil + return *lockedPriceCents, params, nil } // PriceUsingParams determines the price for a counseling service given PaymentServiceItemParams @@ -36,5 +42,6 @@ func (p counselingServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, return unit.Cents(0), nil, err } - return p.Price(appCtx, unit.Cents(lockedPriceCents)) + lockedPrice := unit.Cents(lockedPriceCents) + return p.Price(appCtx, &lockedPrice) } diff --git a/pkg/services/ghcrateengine/counseling_services_pricer_test.go b/pkg/services/ghcrateengine/counseling_services_pricer_test.go index 1ca6de8b660..258ee8ce40a 100644 --- a/pkg/services/ghcrateengine/counseling_services_pricer_test.go +++ b/pkg/services/ghcrateengine/counseling_services_pricer_test.go @@ -12,6 +12,7 @@ const ( ) func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { + lockedPrice := csPriceCents counselingServicesPricer := NewCounselingServicesPricer() suite.Run("success using PaymentServiceItemParams", func() { @@ -31,7 +32,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceCounselingServices() { suite.Run("success without PaymentServiceItemParams", func() { suite.setupTaskOrderFeeData(models.ReServiceCodeCS, csPriceCents) - priceCents, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), csPriceCents) + priceCents, _, err := counselingServicesPricer.Price(suite.AppContextForTest(), &lockedPrice) suite.NoError(err) suite.Equal(csPriceCents, priceCents) }) diff --git a/pkg/services/ghcrateengine/management_services_pricer.go b/pkg/services/ghcrateengine/management_services_pricer.go index 31a23729e94..995003c196b 100644 --- a/pkg/services/ghcrateengine/management_services_pricer.go +++ b/pkg/services/ghcrateengine/management_services_pricer.go @@ -1,6 +1,8 @@ package ghcrateengine import ( + "fmt" + "github.com/transcom/mymove/pkg/appcontext" "github.com/transcom/mymove/pkg/models" "github.com/transcom/mymove/pkg/services" @@ -16,16 +18,20 @@ func NewManagementServicesPricer() services.ManagementServicesPricer { } // Price determines the price for a management service -func (p managementServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { +func (p managementServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents *unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { + + if lockedPriceCents == nil { + return 0, nil, fmt.Errorf("invalid value for locked_price_cents") + } params := services.PricingDisplayParams{ { Key: models.ServiceItemParamNamePriceRateOrFactor, - Value: FormatCents(lockedPriceCents), + Value: FormatCents(*lockedPriceCents), }, } - return lockedPriceCents, params, nil + return *lockedPriceCents, params, nil } // PriceUsingParams determines the price for a management service given PaymentServiceItemParams @@ -36,5 +42,6 @@ func (p managementServicesPricer) PriceUsingParams(appCtx appcontext.AppContext, return unit.Cents(0), nil, err } - return p.Price(appCtx, unit.Cents(lockedPriceCents)) + lockedPrice := unit.Cents(lockedPriceCents) + return p.Price(appCtx, &lockedPrice) } diff --git a/pkg/services/ghcrateengine/management_services_pricer_test.go b/pkg/services/ghcrateengine/management_services_pricer_test.go index be068473c20..01452e741c4 100644 --- a/pkg/services/ghcrateengine/management_services_pricer_test.go +++ b/pkg/services/ghcrateengine/management_services_pricer_test.go @@ -12,6 +12,7 @@ const ( ) func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { + lockedPrice := csPriceCents suite.Run("success using PaymentServiceItemParams", func() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) paymentServiceItem := suite.setupManagementServicesItem() @@ -32,7 +33,7 @@ func (suite *GHCRateEngineServiceSuite) TestPriceManagementServices() { suite.setupTaskOrderFeeData(models.ReServiceCodeMS, msPriceCents) managementServicesPricer := NewManagementServicesPricer() - priceCents, _, err := managementServicesPricer.Price(suite.AppContextForTest(), msPriceCents) + priceCents, _, err := managementServicesPricer.Price(suite.AppContextForTest(), &lockedPrice) suite.NoError(err) suite.Equal(msPriceCents, priceCents) }) diff --git a/pkg/services/mocks/CounselingServicesPricer.go b/pkg/services/mocks/CounselingServicesPricer.go index 51d2964ac42..1b6400c5a1b 100644 --- a/pkg/services/mocks/CounselingServicesPricer.go +++ b/pkg/services/mocks/CounselingServicesPricer.go @@ -19,22 +19,22 @@ type CounselingServicesPricer struct { } // Price provides a mock function with given fields: appCtx, lockedPriceCents -func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { +func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents *unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { ret := _m.Called(appCtx, lockedPriceCents) var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) (unit.Cents, services.PricingDisplayParams, error)); ok { + if rf, ok := ret.Get(0).(func(appcontext.AppContext, *unit.Cents) (unit.Cents, services.PricingDisplayParams, error)); ok { return rf(appCtx, lockedPriceCents) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) unit.Cents); ok { + if rf, ok := ret.Get(0).(func(appcontext.AppContext, *unit.Cents) unit.Cents); ok { r0 = rf(appCtx, lockedPriceCents) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, unit.Cents) services.PricingDisplayParams); ok { + if rf, ok := ret.Get(1).(func(appcontext.AppContext, *unit.Cents) services.PricingDisplayParams); ok { r1 = rf(appCtx, lockedPriceCents) } else { if ret.Get(1) != nil { @@ -42,7 +42,7 @@ func (_m *CounselingServicesPricer) Price(appCtx appcontext.AppContext, lockedPr } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, unit.Cents) error); ok { + if rf, ok := ret.Get(2).(func(appcontext.AppContext, *unit.Cents) error); ok { r2 = rf(appCtx, lockedPriceCents) } else { r2 = ret.Error(2) diff --git a/pkg/services/mocks/ManagementServicesPricer.go b/pkg/services/mocks/ManagementServicesPricer.go index e361159de6e..4a832d51602 100644 --- a/pkg/services/mocks/ManagementServicesPricer.go +++ b/pkg/services/mocks/ManagementServicesPricer.go @@ -19,22 +19,22 @@ type ManagementServicesPricer struct { } // Price provides a mock function with given fields: appCtx, lockedPriceCents -func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { +func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, lockedPriceCents *unit.Cents) (unit.Cents, services.PricingDisplayParams, error) { ret := _m.Called(appCtx, lockedPriceCents) var r0 unit.Cents var r1 services.PricingDisplayParams var r2 error - if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) (unit.Cents, services.PricingDisplayParams, error)); ok { + if rf, ok := ret.Get(0).(func(appcontext.AppContext, *unit.Cents) (unit.Cents, services.PricingDisplayParams, error)); ok { return rf(appCtx, lockedPriceCents) } - if rf, ok := ret.Get(0).(func(appcontext.AppContext, unit.Cents) unit.Cents); ok { + if rf, ok := ret.Get(0).(func(appcontext.AppContext, *unit.Cents) unit.Cents); ok { r0 = rf(appCtx, lockedPriceCents) } else { r0 = ret.Get(0).(unit.Cents) } - if rf, ok := ret.Get(1).(func(appcontext.AppContext, unit.Cents) services.PricingDisplayParams); ok { + if rf, ok := ret.Get(1).(func(appcontext.AppContext, *unit.Cents) services.PricingDisplayParams); ok { r1 = rf(appCtx, lockedPriceCents) } else { if ret.Get(1) != nil { @@ -42,7 +42,7 @@ func (_m *ManagementServicesPricer) Price(appCtx appcontext.AppContext, lockedPr } } - if rf, ok := ret.Get(2).(func(appcontext.AppContext, unit.Cents) error); ok { + if rf, ok := ret.Get(2).(func(appcontext.AppContext, *unit.Cents) error); ok { r2 = rf(appCtx, lockedPriceCents) } else { r2 = ret.Error(2) From b1714abd696417e79c241ea5d5188d125a3b148e Mon Sep 17 00:00:00 2001 From: Alex Lusk Date: Fri, 6 Sep 2024 16:47:00 +0000 Subject: [PATCH 11/19] improve handling of switching gblocs when user switches roles --- src/components/Table/TableCSVExportButton.jsx | 6 +++++- src/components/Table/TableQueue.jsx | 7 ++++++- src/pages/Office/HeadquartersQueues/HeadquartersQueues.jsx | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/Table/TableCSVExportButton.jsx b/src/components/Table/TableCSVExportButton.jsx index 9b5937c3642..5d3180ede70 100644 --- a/src/components/Table/TableCSVExportButton.jsx +++ b/src/components/Table/TableCSVExportButton.jsx @@ -18,6 +18,7 @@ const TableCSVExportButton = ({ paramSort, paramFilters, className, + isHeadquartersUser, }) => { const [isLoading, setIsLoading] = useState(false); const [csvRows, setCsvRows] = useState([]); @@ -25,7 +26,7 @@ const TableCSVExportButton = ({ const { id: sortColumn, desc: sortOrder } = paramSort.length ? paramSort[0] : {}; const gblocContext = useContext(SelectedGblocContext); - const { selectedGbloc } = gblocContext || { selectedGbloc: undefined }; + const { selectedGbloc } = isHeadquartersUser && gblocContext ? gblocContext : { selectedGbloc: undefined }; const formatDataForExport = (data, columns = tableColumns) => { const formattedData = []; @@ -110,6 +111,8 @@ TableCSVExportButton.propTypes = { paramSort: PropTypes.array, // paramSort is the filter columns and values currently applied to the queue paramFilters: PropTypes.array, + // isHeadquartersUser identifies if the active role is a headquarters user to allow switching GBLOCs + isHeadquartersUser: PropTypes.bool, }; TableCSVExportButton.defaultProps = { @@ -118,6 +121,7 @@ TableCSVExportButton.defaultProps = { hiddenColumns: [], paramSort: [], paramFilters: [], + isHeadquartersUser: false, }; export default TableCSVExportButton; diff --git a/src/components/Table/TableQueue.jsx b/src/components/Table/TableQueue.jsx index 5182fed428d..d09605914c4 100644 --- a/src/components/Table/TableQueue.jsx +++ b/src/components/Table/TableQueue.jsx @@ -48,6 +48,7 @@ const TableQueue = ({ csvExportQueueFetcher, csvExportQueueFetcherKey, sessionStorageKey, + isHeadquartersUser, }) => { const [isPageReload, setIsPageReload] = useState(true); useEffect(() => { @@ -87,7 +88,7 @@ const TableQueue = ({ const { id, desc } = paramSort.length ? paramSort[0] : {}; const gblocContext = useContext(SelectedGblocContext); - const { selectedGbloc } = gblocContext || { selectedGbloc: undefined }; + const { selectedGbloc } = isHeadquartersUser && gblocContext ? gblocContext : { selectedGbloc: undefined }; const multiSelectValueDelimiter = ','; @@ -312,6 +313,7 @@ const TableQueue = ({ totalCount={totalCount} paramSort={paramSort} paramFilters={paramFilters} + isHeadquartersUser={isHeadquartersUser} /> )} @@ -381,6 +383,8 @@ TableQueue.propTypes = { csvExportQueueFetcherKey: PropTypes.string, // session storage key to store search filters sessionStorageKey: PropTypes.string, + // isHeadquartersUser identifies if the active role is a headquarters user to allow switching GBLOCs + isHeadquartersUser: PropTypes.bool, }; TableQueue.defaultProps = { @@ -399,5 +403,6 @@ TableQueue.defaultProps = { csvExportQueueFetcher: null, csvExportQueueFetcherKey: null, sessionStorageKey: 'default', + isHeadquartersUser: false, }; export default TableQueue; diff --git a/src/pages/Office/HeadquartersQueues/HeadquartersQueues.jsx b/src/pages/Office/HeadquartersQueues/HeadquartersQueues.jsx index 9c6f613cc7e..8ba085fc464 100644 --- a/src/pages/Office/HeadquartersQueues/HeadquartersQueues.jsx +++ b/src/pages/Office/HeadquartersQueues/HeadquartersQueues.jsx @@ -247,6 +247,7 @@ const HeadquartersQueue = () => { csvExportQueueFetcher={getMovesQueue} csvExportQueueFetcherKey="queueMoves" sessionStorageKey={queueType} + isHeadquartersUser /> ); @@ -273,6 +274,7 @@ const HeadquartersQueue = () => { csvExportQueueFetcher={getPaymentRequestsQueue} csvExportQueueFetcherKey="queuePaymentRequests" sessionStorageKey={queueType} + isHeadquartersUser /> ); @@ -299,6 +301,7 @@ const HeadquartersQueue = () => { csvExportQueueFetcher={getServicesCounselingPPMQueue} csvExportQueueFetcherKey="queueMoves" sessionStorageKey={queueType} + isHeadquartersUser /> ); @@ -326,6 +329,7 @@ const HeadquartersQueue = () => { csvExportQueueFetcher={getServicesCounselingQueue} csvExportQueueFetcherKey="queueMoves" sessionStorageKey={queueType} + isHeadquartersUser /> ); From 3d336766b2201c9af36455781c93edc86db4e24f Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Mon, 9 Sep 2024 20:02:38 +0000 Subject: [PATCH 12/19] replacing bad migration --- migrations/app/migrations_manifest.txt | 2 +- ...ces_to_unpriced_cs_ms_service_items.up.sql | 28 ------------------- ...ricing_unpriced_ms_cs_service_items.up.sql | 19 +++++++++++++ 3 files changed, 20 insertions(+), 29 deletions(-) delete mode 100644 migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql create mode 100644 migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 7bdf1dce58a..7f3791c05d2 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -981,4 +981,4 @@ 20240820125856_allow_pptas_migration.up.sql 20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql 20240822180409_adding_locked_price_cents_service_param.up.sql -20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql +20240909194514_pricing_unpriced_ms_cs_service_items.up.sql diff --git a/migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql b/migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql deleted file mode 100644 index a3172cc10c5..00000000000 --- a/migrations/app/schema/20240905192913_adding_prices_to_unpriced_cs_ms_service_items.up.sql +++ /dev/null @@ -1,28 +0,0 @@ --- Filling in pricing_estimates for unprices services code MS and CS service items. Service items should not be able to reach this state --- but some older data exists where unpriced MS and CS items exist -SET statement_timeout = 300000; -SET lock_timeout = 300000; -SET idle_in_transaction_session_timeout = 300000; - -UPDATE mto_service_items AS ms -SET locked_price_cents = - CASE - when price_cents > 0 then price_cents - when price_cents <= 0 then 0 - END, - pricing_estimate = - CASE - when price_cents > 0 then price_cents - when price_cents <= 0 then 0 - END -FROM re_task_order_fees AS tf -JOIN re_contract_years AS cy -ON tf.contract_year_id = cy.id -JOIN re_contracts AS c -ON cy.contract_id = c.id -JOIN re_services AS s -ON tf.service_id = s.id -WHERE ms.locked_price_cents = null - AND ms.pricing_estimate = null - AND re_service_id = s.id - AND s.code = 'MS' OR s.code = 'CS' \ No newline at end of file diff --git a/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql b/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql new file mode 100644 index 00000000000..d90ca544085 --- /dev/null +++ b/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql @@ -0,0 +1,19 @@ +UPDATE mto_service_items AS ms +SET locked_price_cents = + CASE + when price_cents > 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then price_cents + when price_cents = 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then 0 + END, + pricing_estimate = + CASE + when price_cents > 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then price_cents + when price_cents = 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then 0 + END +FROM re_task_order_fees AS tf +JOIN re_services AS s +ON tf.service_id = s.id +JOIN re_contract_years AS cy +ON tf.contract_year_id = cy.id +JOIN re_contracts AS c +ON cy.contract_id = c.id +WHERE (s.code = 'MS' OR s.code = 'CS') AND ms.re_service_id = s.id AND ms.locked_price_cents is null AND ms.pricing_estimate is null; \ No newline at end of file From b145dd244b7858c101c19ae87e3b9d1fe63003a0 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Mon, 9 Sep 2024 20:31:27 +0000 Subject: [PATCH 13/19] Replacing bad migration --- migrations/app/migrations_manifest.txt | 2 +- ...ating_locked_price_cents_for_ms_and_cs_service_items.up.sql} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename migrations/app/schema/{20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql => 20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql} (82%) diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 7f3791c05d2..936b8fdf45d 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -979,6 +979,6 @@ 20240807140736_add_locked_price_cents_to_mto_service_items.up.sql 20240814144527_remove_allow_pptas_client.up.sql 20240820125856_allow_pptas_migration.up.sql -20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql 20240822180409_adding_locked_price_cents_service_param.up.sql 20240909194514_pricing_unpriced_ms_cs_service_items.up.sql +20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql diff --git a/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql b/migrations/app/schema/20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql similarity index 82% rename from migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql rename to migrations/app/schema/20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql index e4f686802a2..bf154feebe5 100644 --- a/migrations/app/schema/20240821180447_populating_locked_price_cents_for_ms_and_cs.up.sql +++ b/migrations/app/schema/20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql @@ -6,4 +6,4 @@ SET idle_in_transaction_session_timeout = 300000; UPDATE mto_service_items AS ms SET locked_price_cents = pricing_estimate FROM re_services AS r -WHERE ms.re_service_id = r.id AND r.code = 'MS' OR r.code = 'CS' \ No newline at end of file +WHERE ms.re_service_id = r.id AND (r.code = 'MS' OR r.code = 'CS') \ No newline at end of file From bbf942282aa73229f1341af78ba60f40a94a7743 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Tue, 10 Sep 2024 02:09:50 +0000 Subject: [PATCH 14/19] Updating new migration --- ...pricing_unpriced_ms_cs_service_items.up.sql | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql b/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql index d90ca544085..e8645f9adcc 100644 --- a/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql +++ b/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql @@ -1,19 +1,23 @@ UPDATE mto_service_items AS ms SET locked_price_cents = CASE - when price_cents > 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then price_cents - when price_cents = 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then 0 + when price_cents > 0 AND (s.code = 'MS' OR s.code = 'CS') AND ms.re_service_id = s.id then price_cents + when price_cents = 0 AND (s.code = 'MS' OR s.code = 'CS') AND ms.re_service_id = s.id then 0 END, pricing_estimate = CASE - when price_cents > 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then price_cents - when price_cents = 0 AND (s.code = 'MS' OR s.code = 'CS') AND re_service_id = s.id then 0 + when price_cents > 0 AND (s.code = 'MS' OR s.code = 'CS') AND ms.re_service_id = s.id then price_cents + when price_cents = 0 AND (s.code = 'MS' OR s.code = 'CS') AND ms.re_service_id = s.id then 0 END FROM re_task_order_fees AS tf JOIN re_services AS s ON tf.service_id = s.id JOIN re_contract_years AS cy ON tf.contract_year_id = cy.id -JOIN re_contracts AS c -ON cy.contract_id = c.id -WHERE (s.code = 'MS' OR s.code = 'CS') AND ms.re_service_id = s.id AND ms.locked_price_cents is null AND ms.pricing_estimate is null; \ No newline at end of file +JOIN re_contracts AS ct +ON cy.contract_id = ct.id +JOIN mto_service_items AS msi +ON s.id = msi.re_service_id +JOIN moves AS mo +ON mo.id = msi.move_id +WHERE (s.code = 'MS' OR s.code = 'CS') AND (mo.available_to_prime_at BETWEEN cy.start_date AND cy.end_date) AND ms.re_service_id = s.id AND ms.locked_price_cents is null AND ms.pricing_estimate is null; \ No newline at end of file From 30f00b049dd68429802cb835383b3bd74e7a4770 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Tue, 10 Sep 2024 02:17:17 +0000 Subject: [PATCH 15/19] Replacing bad migration --- migrations/app/migrations_manifest.txt | 2 +- ...ts_from_pricing_estimate_for_ms_and_cs_service_items.up.sql} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename migrations/app/schema/{20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql => 20240910021542_populating_locked_price_cents_from_pricing_estimate_for_ms_and_cs_service_items.up.sql} (100%) diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 936b8fdf45d..dca81608d11 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -981,4 +981,4 @@ 20240820125856_allow_pptas_migration.up.sql 20240822180409_adding_locked_price_cents_service_param.up.sql 20240909194514_pricing_unpriced_ms_cs_service_items.up.sql -20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql +20240910021542_populating_locked_price_cents_from_pricing_estimate_for_ms_and_cs_service_items.up.sql diff --git a/migrations/app/schema/20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql b/migrations/app/schema/20240910021542_populating_locked_price_cents_from_pricing_estimate_for_ms_and_cs_service_items.up.sql similarity index 100% rename from migrations/app/schema/20240909202158_populating_locked_price_cents_for_ms_and_cs_service_items.up.sql rename to migrations/app/schema/20240910021542_populating_locked_price_cents_from_pricing_estimate_for_ms_and_cs_service_items.up.sql From 828e3b62ec80d1caa2d63b49ef695928b608a0e8 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Tue, 10 Sep 2024 02:50:03 +0000 Subject: [PATCH 16/19] Increasing lockout for migration --- ...240909194514_pricing_unpriced_ms_cs_service_items.up.sql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql b/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql index e8645f9adcc..de31bcc645c 100644 --- a/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql +++ b/migrations/app/schema/20240909194514_pricing_unpriced_ms_cs_service_items.up.sql @@ -1,3 +1,9 @@ +-- Filling in pricing_estimates for unprices services code MS and CS service items. Service items should not be able to reach this state +-- but some older data exists where unpriced MS and CS items exist +SET statement_timeout = 300000; +SET lock_timeout = 300000; +SET idle_in_transaction_session_timeout = 300000; + UPDATE mto_service_items AS ms SET locked_price_cents = CASE From 710e5a2b22254078242214f189dcb67ced71cc22 Mon Sep 17 00:00:00 2001 From: AaronW Date: Fri, 13 Sep 2024 22:13:11 +0000 Subject: [PATCH 17/19] Commits from PR 13578 --- pkg/gen/internalapi/embedded_spec.go | 12 ++-- .../create_service_member_payload.go | 4 +- .../patch_service_member_payload.go | 4 +- .../service_member_payload.go | 4 +- pkg/handlers/internalapi/service_members.go | 5 +- src/pages/MyMove/Profile/EditContactInfo.jsx | 4 +- .../CustomerOnboarding/CreateCustomerForm.jsx | 14 ++++- .../CreateCustomerForm.test.jsx | 60 +++++++++++++++++++ swagger-def/internal.yaml | 6 +- swagger/internal.yaml | 6 +- 10 files changed, 94 insertions(+), 25 deletions(-) diff --git a/pkg/gen/internalapi/embedded_spec.go b/pkg/gen/internalapi/embedded_spec.go index 794f7f59f10..3ba15e834fa 100644 --- a/pkg/gen/internalapi/embedded_spec.go +++ b/pkg/gen/internalapi/embedded_spec.go @@ -3987,7 +3987,7 @@ func init() { "type": "string", "format": "telephone", "title": "Alternate phone", - "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$", + "pattern": "^([2-9]\\d{2}-\\d{3}-\\d{4})?$", "x-nullable": true, "example": "212-555-5555" }, @@ -6429,7 +6429,7 @@ func init() { "type": "string", "format": "telephone", "title": "Alternate Phone", - "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$", + "pattern": "^([2-9]\\d{2}-\\d{3}-\\d{4})?$", "x-nullable": true, "example": "212-555-5555" }, @@ -6905,7 +6905,7 @@ func init() { "type": "string", "format": "telephone", "title": "Secondary Phone", - "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$", + "pattern": "^([2-9]\\d{2}-\\d{3}-\\d{4})?$", "x-nullable": true, "example": "212-555-5555" }, @@ -12588,7 +12588,7 @@ func init() { "type": "string", "format": "telephone", "title": "Alternate phone", - "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$", + "pattern": "^([2-9]\\d{2}-\\d{3}-\\d{4})?$", "x-nullable": true, "example": "212-555-5555" }, @@ -15034,7 +15034,7 @@ func init() { "type": "string", "format": "telephone", "title": "Alternate Phone", - "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$", + "pattern": "^([2-9]\\d{2}-\\d{3}-\\d{4})?$", "x-nullable": true, "example": "212-555-5555" }, @@ -15512,7 +15512,7 @@ func init() { "type": "string", "format": "telephone", "title": "Secondary Phone", - "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$", + "pattern": "^([2-9]\\d{2}-\\d{3}-\\d{4})?$", "x-nullable": true, "example": "212-555-5555" }, diff --git a/pkg/gen/internalmessages/create_service_member_payload.go b/pkg/gen/internalmessages/create_service_member_payload.go index a2b48dce311..737d5a0a897 100644 --- a/pkg/gen/internalmessages/create_service_member_payload.go +++ b/pkg/gen/internalmessages/create_service_member_payload.go @@ -68,7 +68,7 @@ type CreateServiceMemberPayload struct { // Alternate phone // Example: 212-555-5555 - // Pattern: ^[2-9]\d{2}-\d{3}-\d{4}$ + // Pattern: ^([2-9]\d{2}-\d{3}-\d{4})?$ SecondaryTelephone *string `json:"secondary_telephone,omitempty"` // Suffix @@ -261,7 +261,7 @@ func (m *CreateServiceMemberPayload) validateSecondaryTelephone(formats strfmt.R return nil } - if err := validate.Pattern("secondary_telephone", "body", *m.SecondaryTelephone, `^[2-9]\d{2}-\d{3}-\d{4}$`); err != nil { + if err := validate.Pattern("secondary_telephone", "body", *m.SecondaryTelephone, `^([2-9]\d{2}-\d{3}-\d{4})?$`); err != nil { return err } diff --git a/pkg/gen/internalmessages/patch_service_member_payload.go b/pkg/gen/internalmessages/patch_service_member_payload.go index ec9b127dcda..a85374ad1eb 100644 --- a/pkg/gen/internalmessages/patch_service_member_payload.go +++ b/pkg/gen/internalmessages/patch_service_member_payload.go @@ -72,7 +72,7 @@ type PatchServiceMemberPayload struct { // Alternate Phone // Example: 212-555-5555 - // Pattern: ^[2-9]\d{2}-\d{3}-\d{4}$ + // Pattern: ^([2-9]\d{2}-\d{3}-\d{4})?$ SecondaryTelephone *string `json:"secondary_telephone,omitempty"` // Suffix @@ -266,7 +266,7 @@ func (m *PatchServiceMemberPayload) validateSecondaryTelephone(formats strfmt.Re return nil } - if err := validate.Pattern("secondary_telephone", "body", *m.SecondaryTelephone, `^[2-9]\d{2}-\d{3}-\d{4}$`); err != nil { + if err := validate.Pattern("secondary_telephone", "body", *m.SecondaryTelephone, `^([2-9]\d{2}-\d{3}-\d{4})?$`); err != nil { return err } diff --git a/pkg/gen/internalmessages/service_member_payload.go b/pkg/gen/internalmessages/service_member_payload.go index 463243292ff..a288cfba291 100644 --- a/pkg/gen/internalmessages/service_member_payload.go +++ b/pkg/gen/internalmessages/service_member_payload.go @@ -95,7 +95,7 @@ type ServiceMemberPayload struct { // Secondary Phone // Example: 212-555-5555 - // Pattern: ^[2-9]\d{2}-\d{3}-\d{4}$ + // Pattern: ^([2-9]\d{2}-\d{3}-\d{4})?$ SecondaryTelephone *string `json:"secondary_telephone,omitempty"` // Suffix @@ -411,7 +411,7 @@ func (m *ServiceMemberPayload) validateSecondaryTelephone(formats strfmt.Registr return nil } - if err := validate.Pattern("secondary_telephone", "body", *m.SecondaryTelephone, `^[2-9]\d{2}-\d{3}-\d{4}$`); err != nil { + if err := validate.Pattern("secondary_telephone", "body", *m.SecondaryTelephone, `^([2-9]\d{2}-\d{3}-\d{4})?$`); err != nil { return err } diff --git a/pkg/handlers/internalapi/service_members.go b/pkg/handlers/internalapi/service_members.go index cd257025cef..bd91b21f4fc 100644 --- a/pkg/handlers/internalapi/service_members.go +++ b/pkg/handlers/internalapi/service_members.go @@ -235,9 +235,8 @@ func (h PatchServiceMemberHandler) patchServiceMemberWithPayload(serviceMember * if payload.Telephone != nil { serviceMember.Telephone = payload.Telephone } - if payload.SecondaryTelephone != nil { - serviceMember.SecondaryTelephone = payload.SecondaryTelephone - } + // Need to be able to accept a nil value for this optional field + serviceMember.SecondaryTelephone = payload.SecondaryTelephone if payload.PersonalEmail != nil { serviceMember.PersonalEmail = payload.PersonalEmail } diff --git a/src/pages/MyMove/Profile/EditContactInfo.jsx b/src/pages/MyMove/Profile/EditContactInfo.jsx index aa27b30eae0..898031e46b8 100644 --- a/src/pages/MyMove/Profile/EditContactInfo.jsx +++ b/src/pages/MyMove/Profile/EditContactInfo.jsx @@ -73,9 +73,7 @@ export const EditContactInfo = ({ backup_mailing_address: values[backupAddressName.toString()], }; - if (values?.secondary_telephone) { - serviceMemberPayload.secondary_telephone = values?.secondary_telephone; - } + serviceMemberPayload.secondary_telephone = values?.secondary_telephone; const backupContactPayload = { id: currentBackupContacts[0].id, diff --git a/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx b/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx index b8a6ed6a6fa..0bb4255d3e6 100644 --- a/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx +++ b/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx @@ -41,6 +41,7 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { const backupContactName = 'backup_contact'; const [isSafetyMoveFF, setSafetyMoveFF] = useState(false); + const [secondaryTelephoneNum, setSecondaryTelephoneNum] = useState(''); useEffect(() => { isBooleanFlagEnabled('safety_move')?.then((enabled) => { @@ -189,6 +190,16 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { {({ isValid, handleSubmit, setValues, values, handleChange }) => { + const handleSubmitNext = () => { + setValues({ + ...values, + secondary_telephone: secondaryTelephoneNum, + }); + handleSubmit(); + }; + const handlePhoneNumChange = (value) => { + setSecondaryTelephoneNum(value); + }; const handleIsSafetyMove = (e) => { const { value } = e.target; if (value === 'true') { @@ -305,6 +316,7 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { type="tel" minimum="12" mask="000{-}000{-}0000" + onChange={handlePhoneNumChange} /> @@ -479,7 +491,7 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { editMode onCancelClick={handleBack} disableNext={!isValid} - onNextClick={handleSubmit} + onNextClick={handleSubmitNext} /> diff --git a/src/pages/Office/CustomerOnboarding/CreateCustomerForm.test.jsx b/src/pages/Office/CustomerOnboarding/CreateCustomerForm.test.jsx index 7167c40da84..cf97cda4d5d 100644 --- a/src/pages/Office/CustomerOnboarding/CreateCustomerForm.test.jsx +++ b/src/pages/Office/CustomerOnboarding/CreateCustomerForm.test.jsx @@ -215,6 +215,66 @@ describe('CreateCustomerForm', () => { expect(screen.getByText('EMPLID')).toBeInTheDocument(); }); + it('payload can have an empty secondary phone number', async () => { + createCustomerWithOktaOption.mockImplementation(() => Promise.resolve(fakeResponse)); + + const { getByLabelText, getByTestId, getByRole } = render( + + + , + ); + + const user = userEvent.setup(); + + const saveBtn = await screen.findByRole('button', { name: 'Save' }); + expect(saveBtn).toBeInTheDocument(); + + await user.selectOptions(getByLabelText('Branch of service'), [fakePayload.affiliation]); + + await user.type(getByLabelText('First name'), fakePayload.first_name); + await user.type(getByLabelText('Last name'), fakePayload.last_name); + + await user.type(getByLabelText('Best contact phone'), fakePayload.telephone); + await user.type(getByLabelText('Personal email'), fakePayload.personal_email); + + await user.type(getByTestId('res-add-street1'), fakePayload.residential_address.streetAddress1); + await user.type(getByTestId('res-add-city'), fakePayload.residential_address.city); + await user.selectOptions(getByTestId('res-add-state'), [fakePayload.residential_address.state]); + await user.type(getByTestId('res-add-zip'), fakePayload.residential_address.postalCode); + + await user.type(getByTestId('backup-add-street1'), fakePayload.backup_mailing_address.streetAddress1); + await user.type(getByTestId('backup-add-city'), fakePayload.backup_mailing_address.city); + await user.selectOptions(getByTestId('backup-add-state'), [fakePayload.backup_mailing_address.state]); + await user.type(getByTestId('backup-add-zip'), fakePayload.backup_mailing_address.postalCode); + + await user.type(getByLabelText('Name'), fakePayload.backup_contact.name); + await user.type(getByRole('textbox', { name: 'Email' }), fakePayload.backup_contact.email); + await user.type(getByRole('textbox', { name: 'Phone' }), fakePayload.backup_contact.telephone); + + await userEvent.type(getByTestId('create-okta-account-yes'), fakePayload.create_okta_account); + + await userEvent.type(getByTestId('cac-user-no'), fakePayload.cac_user); + + await waitFor(() => { + expect(saveBtn).toBeEnabled(); + }); + + const waiter = waitFor(() => { + expect(createCustomerWithOktaOption).toHaveBeenCalled(); + expect(mockNavigate).toHaveBeenCalledWith(ordersPath, { + state: { + isSafetyMoveSelected: false, + }, + }); + }); + + await user.click(saveBtn); + await waiter; + expect(mockNavigate).toHaveBeenCalled(); + + expect(createCustomerWithOktaOption.mock.calls[0][0]).not.toHaveProperty('secondary_number'); + }, 10000); + it('navigates the user on cancel click', async () => { const { getByText } = render( diff --git a/swagger-def/internal.yaml b/swagger-def/internal.yaml index 679236a358b..134d05f587a 100644 --- a/swagger-def/internal.yaml +++ b/swagger-def/internal.yaml @@ -705,7 +705,7 @@ definitions: secondary_telephone: type: string format: telephone - pattern: '^[2-9]\d{2}-\d{3}-\d{4}$' + pattern: '^([2-9]\d{2}-\d{3}-\d{4})?$' example: 212-555-5555 x-nullable: true title: Secondary Phone @@ -799,7 +799,7 @@ definitions: secondary_telephone: type: string format: telephone - pattern: '^[2-9]\d{2}-\d{3}-\d{4}$' + pattern: '^([2-9]\d{2}-\d{3}-\d{4})?$' example: 212-555-5555 x-nullable: true title: Alternate phone @@ -883,7 +883,7 @@ definitions: secondary_telephone: type: string format: telephone - pattern: '^[2-9]\d{2}-\d{3}-\d{4}$' + pattern: '^([2-9]\d{2}-\d{3}-\d{4})?$' example: 212-555-5555 x-nullable: true title: Alternate Phone diff --git a/swagger/internal.yaml b/swagger/internal.yaml index 2ddb5861003..ca80ccc7816 100644 --- a/swagger/internal.yaml +++ b/swagger/internal.yaml @@ -726,7 +726,7 @@ definitions: secondary_telephone: type: string format: telephone - pattern: ^[2-9]\d{2}-\d{3}-\d{4}$ + pattern: ^([2-9]\d{2}-\d{3}-\d{4})?$ example: 212-555-5555 x-nullable: true title: Secondary Phone @@ -820,7 +820,7 @@ definitions: secondary_telephone: type: string format: telephone - pattern: ^[2-9]\d{2}-\d{3}-\d{4}$ + pattern: ^([2-9]\d{2}-\d{3}-\d{4})?$ example: 212-555-5555 x-nullable: true title: Alternate phone @@ -904,7 +904,7 @@ definitions: secondary_telephone: type: string format: telephone - pattern: ^[2-9]\d{2}-\d{3}-\d{4}$ + pattern: ^([2-9]\d{2}-\d{3}-\d{4})?$ example: 212-555-5555 x-nullable: true title: Alternate Phone From 0ceb94d02d9bbaf497e8047552aec616ba36b702 Mon Sep 17 00:00:00 2001 From: AaronW Date: Fri, 13 Sep 2024 22:16:12 +0000 Subject: [PATCH 18/19] Commits from PR 13616 --- pkg/handlers/internalapi/service_members.go | 5 +++-- src/pages/MyMove/Profile/ContactInfo.jsx | 6 +++--- .../CustomerOnboarding/CreateCustomerForm.jsx | 14 +------------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/pkg/handlers/internalapi/service_members.go b/pkg/handlers/internalapi/service_members.go index bd91b21f4fc..cd257025cef 100644 --- a/pkg/handlers/internalapi/service_members.go +++ b/pkg/handlers/internalapi/service_members.go @@ -235,8 +235,9 @@ func (h PatchServiceMemberHandler) patchServiceMemberWithPayload(serviceMember * if payload.Telephone != nil { serviceMember.Telephone = payload.Telephone } - // Need to be able to accept a nil value for this optional field - serviceMember.SecondaryTelephone = payload.SecondaryTelephone + if payload.SecondaryTelephone != nil { + serviceMember.SecondaryTelephone = payload.SecondaryTelephone + } if payload.PersonalEmail != nil { serviceMember.PersonalEmail = payload.PersonalEmail } diff --git a/src/pages/MyMove/Profile/ContactInfo.jsx b/src/pages/MyMove/Profile/ContactInfo.jsx index 2b25f520797..298789034a0 100644 --- a/src/pages/MyMove/Profile/ContactInfo.jsx +++ b/src/pages/MyMove/Profile/ContactInfo.jsx @@ -37,13 +37,13 @@ export const ContactInfo = ({ serviceMember, updateServiceMember, userEmail }) = const payload = { id: serviceMember.id, telephone: values?.telephone, - secondary_telephone: values?.secondary_telephone, + secondary_telephone: values?.secondary_telephone || '', personal_email: values?.personal_email, phone_is_preferred: values?.phone_is_preferred, email_is_preferred: values?.email_is_preferred, }; - if (!payload.secondary_telephone) { - delete payload.secondary_telephone; + if (!payload.secondary_telephone || payload.secondary_telephone === '') { + payload.secondary_telephone = ''; } return patchServiceMember(payload) diff --git a/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx b/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx index 0bb4255d3e6..b8a6ed6a6fa 100644 --- a/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx +++ b/src/pages/Office/CustomerOnboarding/CreateCustomerForm.jsx @@ -41,7 +41,6 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { const backupContactName = 'backup_contact'; const [isSafetyMoveFF, setSafetyMoveFF] = useState(false); - const [secondaryTelephoneNum, setSecondaryTelephoneNum] = useState(''); useEffect(() => { isBooleanFlagEnabled('safety_move')?.then((enabled) => { @@ -190,16 +189,6 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { {({ isValid, handleSubmit, setValues, values, handleChange }) => { - const handleSubmitNext = () => { - setValues({ - ...values, - secondary_telephone: secondaryTelephoneNum, - }); - handleSubmit(); - }; - const handlePhoneNumChange = (value) => { - setSecondaryTelephoneNum(value); - }; const handleIsSafetyMove = (e) => { const { value } = e.target; if (value === 'true') { @@ -316,7 +305,6 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { type="tel" minimum="12" mask="000{-}000{-}0000" - onChange={handlePhoneNumChange} /> @@ -491,7 +479,7 @@ export const CreateCustomerForm = ({ userPrivileges, setFlashMessage }) => { editMode onCancelClick={handleBack} disableNext={!isValid} - onNextClick={handleSubmitNext} + onNextClick={handleSubmit} /> From b1cbf436eb7855037174026529ac017b83ea3082 Mon Sep 17 00:00:00 2001 From: Cory Kleinjan Date: Wed, 18 Sep 2024 19:53:29 +0000 Subject: [PATCH 19/19] Adding where not exists to inserts for lockedpricecents service params --- ...ng_locked_price_cents_service_param.up.sql | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql b/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql index 648d8be964f..baa1337fac5 100644 --- a/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql +++ b/migrations/app/schema/20240822180409_adding_locked_price_cents_service_param.up.sql @@ -1,14 +1,26 @@ INSERT INTO service_item_param_keys (id,key,description,type,origin,created_at,updated_at) -VALUES -('7ec5cf87-a446-4dd6-89d3-50bbc0d2c206','LockedPriceCents', 'Locked price when move was made available to prime', 'INTEGER', 'SYSTEM', now(), now()); +SELECT '7ec5cf87-a446-4dd6-89d3-50bbc0d2c206','LockedPriceCents', 'Locked price when move was made available to prime', 'INTEGER', 'SYSTEM', now(), now() +WHERE NOT EXISTS + (SELECT 1 + FROM service_item_param_keys s + WHERE s.id = '7ec5cf87-a446-4dd6-89d3-50bbc0d2c206' + ); INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) -VALUES -('22056106-bbde-4ae7-b5bd-e7d2f103ab7d',(SELECT id FROM re_services WHERE code='MS'),(SELECT id FROM service_item_param_keys where key='LockedPriceCents'), now(), now(), 'false'); +SELECT '22056106-bbde-4ae7-b5bd-e7d2f103ab7d',(SELECT id FROM re_services WHERE code='MS'),(SELECT id FROM service_item_param_keys where key='LockedPriceCents'), now(), now(), 'false' +WHERE NOT EXISTS + ( SELECT 1 + FROM service_params s + WHERE s.id = '22056106-bbde-4ae7-b5bd-e7d2f103ab7d' + ); INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) -VALUES -('86f8c20c-071e-4715-b0c1-608f540b3be3',(SELECT id FROM re_services WHERE code='CS'),(SELECT id FROM service_item_param_keys where key='LockedPriceCents'), now(), now(), 'false'); \ No newline at end of file +SELECT '86f8c20c-071e-4715-b0c1-608f540b3be3',(SELECT id FROM re_services WHERE code='CS'),(SELECT id FROM service_item_param_keys where key='LockedPriceCents'), now(), now(), 'false' +WHERE NOT EXISTS + ( SELECT 1 + FROM service_params s + WHERE s.id = '86f8c20c-071e-4715-b0c1-608f540b3be3' + ); \ No newline at end of file