Skip to content

Commit

Permalink
seem to have most of it working, need to refine and add tests, figure…
Browse files Browse the repository at this point in the history
… out UI display for iPPMs
  • Loading branch information
danieljordan-caci committed Jan 17, 2025
1 parent 9e80db2 commit 2d64f35
Show file tree
Hide file tree
Showing 18 changed files with 713 additions and 153 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
-- inserting params for IDFSIT
INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES
('fb7925e7-ebfe-49d9-9cf4-7219e68ec686'::uuid,'bd6064ca-e780-4ab4-a37b-0ae98eebb244','597bb77e-0ce7-4ba2-9624-24300962625f','2024-01-17 15:55:50.041957','2024-01-17 15:55:50.041957',false); -- PerUnitCents

-- IDASIT
INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES
('51393ee1-f505-4f7b-96c4-135f771af814'::uuid,'806c6d59-57ff-4a3f-9518-ebf29ba9cb10','597bb77e-0ce7-4ba2-9624-24300962625f','2024-01-17 15:55:50.041957','2024-01-17 15:55:50.041957',false); -- PerUnitCents

-- IOFSIT
INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES
('7518ec84-0c40-4c17-86dd-3ce04e2fe701'::uuid,'b488bf85-ea5e-49c8-ba5c-e2fa278ac806','597bb77e-0ce7-4ba2-9624-24300962625f','2024-01-17 15:55:50.041957','2024-01-17 15:55:50.041957',false); -- PerUnitCents

-- IOASIT
INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES
('cff34123-e2a5-40ed-9cf3-451701850a26'::uuid,'bd424e45-397b-4766-9712-de4ae3a2da36','597bb77e-0ce7-4ba2-9624-24300962625f','2024-01-17 15:55:50.041957','2024-01-17 15:55:50.041957',false); -- PerUnitCents

-- inserting params for FSC
INSERT INTO service_params (id,service_id,service_item_param_key_id,created_at,updated_at,is_optional) VALUES
('bb53e034-80c2-420e-8492-f54d2018fff1'::uuid,'4780b30c-e846-437a-b39a-c499a6b09872','d9ad3878-4b94-4722-bbaf-d4b8080f339d','2024-01-17 15:55:50.041957','2024-01-17 15:55:50.041957',true); -- PortZip

-- remove PriceAreaIntlOrigin, we don't need it
DELETE FROM service_params
WHERE service_item_param_key_id = '6d44624c-b91b-4226-8fcd-98046e2f433d';

-- remove PriceAreaIntlDest, we don't need it
DELETE FROM service_params
WHERE service_item_param_key_id = '4736f489-dfda-4df1-a303-8c434a120d5d';

-- func to fetch a service id from re_services by providing the service code
CREATE OR REPLACE FUNCTION get_service_id(service_code TEXT) RETURNS UUID AS $$
DECLARE
service_id UUID;
BEGIN
SELECT rs.id INTO service_id FROM re_services rs WHERE rs.code = service_code;
IF service_id IS NULL THEN
RAISE EXCEPTION 'Service code % not found in re_services', service_code;
END IF;
RETURN service_id;
END;
$$ LANGUAGE plpgsql;


-- db proc that will calculate a PPM's incentive
-- this is used for estimated/final/max incentives
CREATE OR REPLACE FUNCTION calculate_ppm_incentive(
ppm_id UUID,
pickup_address_id UUID,
Expand Down Expand Up @@ -32,7 +76,7 @@ BEGIN
RAISE EXCEPTION 'is_estimated, is_actual, and is_max cannot all be FALSE. No update will be performed.';
END IF;

-- Validating it's a real PPM
-- validating it's a real PPM
SELECT ppms.id INTO ppm FROM ppm_shipments ppms WHERE ppms.id = ppm_id;
IF ppm IS NULL THEN
RAISE EXCEPTION 'PPM with ID % not found', ppm_id;
Expand All @@ -54,7 +98,7 @@ BEGIN
END IF;

-- ISLH calculation
SELECT rs.id INTO service_id FROM re_services rs WHERE rs.code = 'ISLH';
service_id := get_service_id('ISLH');
price_islh := ROUND(
calculate_escalated_price(
o_rate_area_id,
Expand All @@ -67,7 +111,7 @@ BEGIN
);

-- IHPK calculation
SELECT rs.id INTO service_id FROM re_services rs WHERE rs.code = 'IHPK';
service_id := get_service_id('IHPK');
price_ihpk := ROUND(
calculate_escalated_price(
o_rate_area_id,
Expand All @@ -80,7 +124,7 @@ BEGIN
);

-- IHUPK calculation
SELECT rs.id INTO service_id FROM re_services rs WHERE rs.code = 'IHUPK';
service_id := get_service_id('IHUPK');
price_ihupk := ROUND(
calculate_escalated_price(
NULL,
Expand All @@ -99,17 +143,95 @@ BEGIN
cents_above_baseline := mileage * estimated_fsc_multiplier;
price_fsc := ROUND((cents_above_baseline * price_difference) * 100);

-- Total incentive
total_incentive := price_islh + price_ihpk + price_ihupk + price_fsc;

-- Update the PPM incentive values
UPDATE ppm_shipments
SET estimated_incentive = CASE WHEN is_estimated THEN total_incentive ELSE estimated_incentive END,
final_incentive = CASE WHEN is_actual THEN total_incentive ELSE final_incentive END,
max_incentive = CASE WHEN is_max THEN total_incentive ELSE max_incentive END
WHERE id = ppm_id;

-- Return all values
-- returning a table so we can use this data in the breakdown for the service member
RETURN QUERY SELECT total_incentive, price_islh, price_ihpk, price_ihupk, price_fsc;
END;
$$ LANGUAGE plpgsql;


-- db proc that will calculate a PPM's SIT cost
-- returns a table with total cost and the cost of each first day/add'l day SIT service item
CREATE OR REPLACE FUNCTION calculate_ppm_sit_cost(
ppm_id UUID,
address_id UUID,
is_origin BOOLEAN,
move_date DATE,
weight INT,
sit_days INT
) RETURNS TABLE (
total_cost INT,
price_first_day INT,
price_addl_day INT
) AS
$$
DECLARE
ppm RECORD;
contract_id UUID;
sit_rate_area_id UUID;
service_id UUID;
BEGIN
-- Validate SIT days
IF sit_days IS NULL OR sit_days < 0 THEN
RAISE EXCEPTION 'SIT days must be a positive integer. Provided value: %', sit_days;
END IF;

-- Validate PPM existence
SELECT ppms.id INTO ppm FROM ppm_shipments ppms WHERE ppms.id = ppm_id;
IF ppm IS NULL THEN
RAISE EXCEPTION 'PPM with ID % not found', ppm_id;
END IF;

-- Get contract ID
contract_id := get_contract_id(move_date);
IF contract_id IS NULL THEN
RAISE EXCEPTION 'Contract not found for date: %', move_date;
END IF;

-- Get rate area
sit_rate_area_id := get_rate_area_id(address_id, NULL, contract_id);
IF sit_rate_area_id IS NULL THEN
RAISE EXCEPTION 'Rate area is NULL for address ID % and contract ID %', address_id, contract_id;
END IF;

-- Calculate first day SIT cost
service_id := get_service_id(CASE WHEN is_origin THEN 'IOFSIT' ELSE 'IDFSIT' END);
price_first_day := (
calculate_escalated_price(
CASE WHEN is_origin THEN sit_rate_area_id ELSE NULL END,
CASE WHEN NOT is_origin THEN sit_rate_area_id ELSE NULL END,
service_id,
contract_id,
CASE WHEN is_origin THEN 'IOFSIT' ELSE 'IDFSIT' END,
move_date
) * (weight / 100)::NUMERIC * 100
)::INT;

-- Calculate additional day SIT cost
service_id := get_service_id(CASE WHEN is_origin THEN 'IOASIT' ELSE 'IDASIT' END);
price_addl_day := (
calculate_escalated_price(
CASE WHEN is_origin THEN sit_rate_area_id ELSE NULL END,
CASE WHEN NOT is_origin THEN sit_rate_area_id ELSE NULL END,
service_id,
contract_id,
CASE WHEN is_origin THEN 'IOASIT' ELSE 'IDASIT' END,
move_date
) * (weight / 100)::NUMERIC * 100 * sit_days
)::INT;

-- Calculate total SIT cost
total_cost := price_first_day + price_addl_day;

-- Return the breakdown for SIT costs
RETURN QUERY SELECT total_cost, price_first_day, price_addl_day;
END;
$$ LANGUAGE plpgsql;

42 changes: 42 additions & 0 deletions pkg/gen/ghcapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions pkg/gen/ghcmessages/p_p_m_closeout.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pkg/handlers/ghcapi/internal/payloads/model_to_payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,9 @@ func PPMCloseout(ppmCloseout *models.PPMCloseout) *ghcmessages.PPMCloseout {
Ddp: handlers.FmtCost(ppmCloseout.DDP),
PackPrice: handlers.FmtCost(ppmCloseout.PackPrice),
UnpackPrice: handlers.FmtCost(ppmCloseout.UnpackPrice),
IntlPackPrice: handlers.FmtCost((ppmCloseout.IntlPackPrice)),
IntlUnpackPrice: handlers.FmtCost((ppmCloseout.IntlUnpackPrice)),
IntlLinehaulPrice: handlers.FmtCost((ppmCloseout.IntlLinehaulPrice)),
SITReimbursement: handlers.FmtCost(ppmCloseout.SITReimbursement),
}

Expand Down
29 changes: 23 additions & 6 deletions pkg/models/ppm_shipment.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ type PPMCloseout struct {
DDP *unit.Cents
PackPrice *unit.Cents
UnpackPrice *unit.Cents
IHPKPrice *unit.Cents
IHUPKPrice *unit.Cents
ISLHPrice *unit.Cents
FSCPrice *unit.Cents
IntlPackPrice *unit.Cents
IntlUnpackPrice *unit.Cents
IntlLinehaulPrice *unit.Cents
SITReimbursement *unit.Cents
}

Expand Down Expand Up @@ -333,12 +332,11 @@ type PPMIncentive struct {
PriceFSC int `db:"price_fsc"`
}

// a db stored proc that will handle updating the estimated_incentive value
// a db function that will handle updating the estimated_incentive value
// this simulates pricing of a basic iHHG shipment with ISLH, IHPK, IHUPK, and the CONUS portion for a FSC
func CalculatePPMIncentive(db *pop.Connection, ppmID uuid.UUID, pickupAddressID uuid.UUID, destAddressID uuid.UUID, moveDate time.Time, mileage int, weight int, isEstimated bool, isActual bool, isMax bool) (*PPMIncentive, error) {
var incentive PPMIncentive

// Run the stored procedure and scan the results into the struct
err := db.RawQuery("SELECT * FROM calculate_ppm_incentive($1, $2, $3, $4, $5, $6, $7, $8, $9)", ppmID, pickupAddressID, destAddressID, moveDate, mileage, weight, isEstimated, isActual, isMax).
First(&incentive)
if err != nil {
Expand All @@ -347,3 +345,22 @@ func CalculatePPMIncentive(db *pop.Connection, ppmID uuid.UUID, pickupAddressID

return &incentive, nil
}

type PPMSITCosts struct {
TotalSITCost int `db:"total_cost"`
PriceFirstDaySIT int `db:"price_first_day"`
PriceAddlDaySIT int `db:"price_addl_day"`
}

// a db function that will handle calculating and returning the SIT costs related to a PPM shipment
func CalculatePPMSITCost(db *pop.Connection, ppmID uuid.UUID, addressID uuid.UUID, isOrigin bool, moveDate time.Time, weight int, sitDays int) (*PPMSITCosts, error) {
var costs PPMSITCosts

err := db.RawQuery("SELECT * FROM calculate_ppm_SIT_cost($1, $2, $3, $4, $5, $6)", ppmID, addressID, isOrigin, moveDate, weight, sitDays).
First(&costs)
if err != nil {
return nil, fmt.Errorf("error calculating PPM SIT costs for PPM ID %s: %w", ppmID, err)
}

return &costs, nil
}
12 changes: 12 additions & 0 deletions pkg/models/re_service_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package models
import (
"time"

"github.com/gobuffalo/pop/v6"
"github.com/gofrs/uuid"

"github.com/transcom/mymove/pkg/apperror"
)

type ReServiceItem struct {
Expand All @@ -24,3 +27,12 @@ func (r ReServiceItem) TableName() string {

// ReServiceItems is a slice of ReServiceItem
type ReServiceItems []ReServiceItem

func FetchReServiceByCode(db *pop.Connection, code ReServiceCode) (*ReService, error) {
reService := ReService{}
err := db.Where("code = ?", code).First(&reService)
if err != nil {
return nil, apperror.NewQueryError("ReService", err, "")
}
return &reService, err
}
Loading

0 comments on commit 2d64f35

Please sign in to comment.