Skip to content

Commit

Permalink
Merge pull request #13600 from transcom/B-20939-SSW-Prep-Dates
Browse files Browse the repository at this point in the history
B 20939 ssw prep dates
  • Loading branch information
r-mettler authored Aug 29, 2024
2 parents 4854a38 + 1fc6c5d commit 43aa0ba
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 89 deletions.
2 changes: 1 addition & 1 deletion cmd/generate-shipment-summary/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func main() {
log.Fatal(err.Error())
}

page1Data, page2Data := ppmComputer.FormatValuesShipmentSummaryWorksheet(*ssfd, false)
page1Data, page2Data, err := ppmComputer.FormatValuesShipmentSummaryWorksheet(*ssfd, false)
noErr(err)
ppmGenerator, err := shipmentsummaryworksheet.NewSSWPPMGenerator(generator)
noErr(err)
Expand Down
Binary file modified pkg/assets/paperwork/formtemplates/SSWPDFTemplate.pdf
Binary file not shown.
13 changes: 10 additions & 3 deletions pkg/services/mocks/SSWPPMComputer.go

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

5 changes: 4 additions & 1 deletion pkg/services/ppmshipment/aoa_packet_creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ func (a *aoaPacketCreator) CreateAOAPacket(appCtx appcontext.AppContext, ppmShip
return nil, fmt.Errorf("%s: %w", errMsgPrefix, err)
}

page1Data, page2Data := a.SSWPPMComputer.FormatValuesShipmentSummaryWorksheet(*ssfd, isPaymentPacket)
page1Data, page2Data, err := a.SSWPPMComputer.FormatValuesShipmentSummaryWorksheet(*ssfd, isPaymentPacket)
if err != nil {
return nil, fmt.Errorf("%s: %w", errMsgPrefix, err)
}

SSWPPMWorksheet, SSWPDFInfo, err := a.SSWPPMGenerator.FillSSWPDFForm(page1Data, page2Data)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/services/shipment_summary_worksheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type Page1Values struct {
SITEntryDates string
SITEndDates string
SITDaysInStorage string
PreparationDate string
PreparationDate1 string
MaxObligationGCC100 string
TotalWeightAllotmentRepeat string
MaxObligationGCC95 string
Expand All @@ -64,7 +64,7 @@ type Page1Values struct {
// Page2Values is an object representing a Shipment Summary Worksheet
type Page2Values struct {
CUIBanner string
PreparationDate string
PreparationDate2 string
TAC string
SAC string
ContractedExpenseMemberPaid string
Expand Down Expand Up @@ -181,7 +181,7 @@ type SSWMaxWeightEntitlement struct {
type SSWPPMComputer interface {
FetchDataShipmentSummaryWorksheetFormData(appCtx appcontext.AppContext, _ *auth.Session, ppmShipmentID uuid.UUID) (*ShipmentSummaryFormData, error)
ComputeObligations(_ appcontext.AppContext, _ ShipmentSummaryFormData, _ route.Planner) (Obligations, error)
FormatValuesShipmentSummaryWorksheet(shipmentSummaryFormData ShipmentSummaryFormData, isPaymentPacket bool) (Page1Values, Page2Values)
FormatValuesShipmentSummaryWorksheet(shipmentSummaryFormData ShipmentSummaryFormData, isPaymentPacket bool) (Page1Values, Page2Values, error)
}

//go:generate mockery --name SSWPPMGenerator
Expand Down
159 changes: 101 additions & 58 deletions pkg/services/shipment_summary_worksheet/shipment_summary_worksheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,17 @@ func NewSSWPPMGenerator(pdfGenerator *paperwork.Generator) (services.SSWPPMGener
}

// FormatValuesShipmentSummaryWorksheet returns the formatted pages for the Shipment Summary Worksheet
func (SSWPPMComputer *SSWPPMComputer) FormatValuesShipmentSummaryWorksheet(shipmentSummaryFormData services.ShipmentSummaryFormData, isPaymentPacket bool) (services.Page1Values, services.Page2Values) {
page1 := FormatValuesShipmentSummaryWorksheetFormPage1(shipmentSummaryFormData, isPaymentPacket)
page2 := FormatValuesShipmentSummaryWorksheetFormPage2(shipmentSummaryFormData, isPaymentPacket)
func (SSWPPMComputer *SSWPPMComputer) FormatValuesShipmentSummaryWorksheet(shipmentSummaryFormData services.ShipmentSummaryFormData, isPaymentPacket bool) (services.Page1Values, services.Page2Values, error) {
page1, err := FormatValuesShipmentSummaryWorksheetFormPage1(shipmentSummaryFormData, isPaymentPacket)
if err != nil {
return page1, services.Page2Values{}, errors.WithStack(err)
}
page2, err := FormatValuesShipmentSummaryWorksheetFormPage2(shipmentSummaryFormData, isPaymentPacket)
if err != nil {
return page1, page2, errors.WithStack(err)
}

return page1, page2
return page1, page2, nil
}

// textField represents a text field within a form.
Expand Down Expand Up @@ -202,13 +208,13 @@ const (
)

// FormatValuesShipmentSummaryWorksheetFormPage1 formats the data for page 1 of the Shipment Summary Worksheet
func FormatValuesShipmentSummaryWorksheetFormPage1(data services.ShipmentSummaryFormData, isPaymentPacket bool) services.Page1Values {
func FormatValuesShipmentSummaryWorksheetFormPage1(data services.ShipmentSummaryFormData, isPaymentPacket bool) (services.Page1Values, error) {
var err error
page1 := services.Page1Values{}
page1.CUIBanner = controlledUnclassifiedInformationText
page1.MaxSITStorageEntitlement = fmt.Sprintf("%02d Days in SIT", data.MaxSITStorageEntitlement)
// We don't currently know what allows POV to be authorized, so we are hardcoding it to "No" to start
page1.POVAuthorized = "No"
page1.PreparationDate = FormatDate(data.PreparationDate)

sm := data.ServiceMember
page1.ServiceMemberName = FormatServiceMemberFullName(sm)
Expand Down Expand Up @@ -247,9 +253,14 @@ func FormatValuesShipmentSummaryWorksheetFormPage1(data services.ShipmentSummary
finalPPMWeight := FormatPPMWeightFinal(data.PPMShipmentFinalWeight)
page1.ShipmentWeights = finalPPMWeight
page1.ActualObligationGCC100 = finalPPMWeight + "; " + formattedShipment.FinalIncentive
page1.PreparationDate1, err = formatSSWDate(data.SignedCertifications, data.PPMShipment.ID)
if err != nil {
return page1, err
}
} else {
page1.ShipmentWeights = formattedShipments.ShipmentWeights
page1.ActualObligationGCC100 = formattedShipments.ShipmentWeightForObligation + " - Estimated lbs; " + formattedShipment.FinalIncentive
page1.PreparationDate1 = formatAOADate(data.SignedCertifications, data.PPMShipment.ID)
}
page1.MaxObligationGCC100 = FormatWeights(data.WeightAllotment.TotalWeight) + " lbs; " + formattedShipment.EstimatedIncentive
page1.MaxObligationGCCMaxAdvance = formattedShipment.MaxAdvance
Expand All @@ -258,7 +269,56 @@ func FormatValuesShipmentSummaryWorksheetFormPage1(data services.ShipmentSummary
page1.ActualObligationSIT = formattedSIT.DaysInStorage
page1.TotalWeightAllotmentRepeat = page1.TotalWeightAllotment
page1.PPMRemainingEntitlement = FormatWeights(data.PPMRemainingEntitlement)
return page1
return page1, nil
}

// FormatValuesShipmentSummaryWorksheetFormPage2 formats the data for page 2 of the Shipment Summary Worksheet
func FormatValuesShipmentSummaryWorksheetFormPage2(data services.ShipmentSummaryFormData, isPaymentPacket bool) (services.Page2Values, error) {
var err error
expensesMap := SubTotalExpenses(data.MovingExpenses)
certificationInfo := formatSignedCertifications(data.SignedCertifications, data.PPMShipment.ID)
formattedShipments := FormatAllShipments(data.PPMShipments)

page2 := services.Page2Values{}
page2.CUIBanner = controlledUnclassifiedInformationText
page2.TAC = derefStringTypes(data.Order.TAC)
page2.SAC = derefStringTypes(data.Order.SAC)
if isPaymentPacket {
page2.PreparationDate2, err = formatSSWDate(data.SignedCertifications, data.PPMShipment.ID)
if err != nil {
return page2, err
}
} else {
page2.PreparationDate2 = formatAOADate(data.SignedCertifications, data.PPMShipment.ID)
}
page2.ContractedExpenseMemberPaid = FormatDollars(expensesMap["ContractedExpenseMemberPaid"])
page2.ContractedExpenseGTCCPaid = FormatDollars(expensesMap["ContractedExpenseGTCCPaid"])
page2.PackingMaterialsMemberPaid = FormatDollars(expensesMap["PackingMaterialsMemberPaid"])
page2.PackingMaterialsGTCCPaid = FormatDollars(expensesMap["PackingMaterialsGTCCPaid"])
page2.WeighingFeesMemberPaid = FormatDollars(expensesMap["WeighingFeeMemberPaid"])
page2.WeighingFeesGTCCPaid = FormatDollars(expensesMap["WeighingFeeGTCCPaid"])
page2.RentalEquipmentMemberPaid = FormatDollars(expensesMap["RentalEquipmentMemberPaid"])
page2.RentalEquipmentGTCCPaid = FormatDollars(expensesMap["RentalEquipmentGTCCPaid"])
page2.TollsMemberPaid = FormatDollars(expensesMap["TollsMemberPaid"])
page2.TollsGTCCPaid = FormatDollars(expensesMap["TollsGTCCPaid"])
page2.OilMemberPaid = FormatDollars(expensesMap["OilMemberPaid"])
page2.OilGTCCPaid = FormatDollars(expensesMap["OilGTCCPaid"])
page2.OtherMemberPaid = FormatDollars(expensesMap["OtherMemberPaid"])
page2.OtherGTCCPaid = FormatDollars(expensesMap["OtherGTCCPaid"])
page2.TotalMemberPaid = FormatDollars(expensesMap["TotalMemberPaid"])
page2.TotalGTCCPaid = FormatDollars(expensesMap["TotalGTCCPaid"])
page2.TotalMemberPaidRepeated = FormatDollars(expensesMap["TotalMemberPaid"])
page2.TotalGTCCPaidRepeated = FormatDollars(expensesMap["TotalGTCCPaid"])
page2.TotalMemberPaidSIT = FormatDollars(expensesMap["StorageMemberPaid"])
page2.TotalGTCCPaidSIT = FormatDollars(expensesMap["StorageGTCCPaid"])
page2.TotalMemberPaidRepeated = page2.TotalMemberPaid
page2.TotalGTCCPaidRepeated = page2.TotalGTCCPaid
page2.ShipmentPickupDates = formattedShipments.PickUpDates
page2.TrustedAgentName = trustedAgentText
page2.ServiceMemberSignature = certificationInfo.CustomerField
page2.PPPOPPSORepresentative = certificationInfo.OfficeField
page2.SignatureDate = certificationInfo.DateField
return page2, nil
}

// FormatGrade formats the service member's rank for Shipment Summary Worksheet
Expand Down Expand Up @@ -300,48 +360,6 @@ func FormatGrade(grade *internalmessages.OrderPayGrade) string {
return ""
}

// FormatValuesShipmentSummaryWorksheetFormPage2 formats the data for page 2 of the Shipment Summary Worksheet
func FormatValuesShipmentSummaryWorksheetFormPage2(data services.ShipmentSummaryFormData, isPaymentPacket bool) services.Page2Values {

expensesMap := SubTotalExpenses(data.MovingExpenses)
certificationInfo := formatSignedCertifications(data.SignedCertifications, data.PPMShipment.ID)
formattedShipments := FormatAllShipments(data.PPMShipments)

page2 := services.Page2Values{}
page2.CUIBanner = controlledUnclassifiedInformationText
page2.TAC = derefStringTypes(data.Order.TAC)
page2.SAC = derefStringTypes(data.Order.SAC)
page2.PreparationDate = FormatDate(data.PreparationDate)
page2.ContractedExpenseMemberPaid = FormatDollars(expensesMap["ContractedExpenseMemberPaid"])
page2.ContractedExpenseGTCCPaid = FormatDollars(expensesMap["ContractedExpenseGTCCPaid"])
page2.PackingMaterialsMemberPaid = FormatDollars(expensesMap["PackingMaterialsMemberPaid"])
page2.PackingMaterialsGTCCPaid = FormatDollars(expensesMap["PackingMaterialsGTCCPaid"])
page2.WeighingFeesMemberPaid = FormatDollars(expensesMap["WeighingFeeMemberPaid"])
page2.WeighingFeesGTCCPaid = FormatDollars(expensesMap["WeighingFeeGTCCPaid"])
page2.RentalEquipmentMemberPaid = FormatDollars(expensesMap["RentalEquipmentMemberPaid"])
page2.RentalEquipmentGTCCPaid = FormatDollars(expensesMap["RentalEquipmentGTCCPaid"])
page2.TollsMemberPaid = FormatDollars(expensesMap["TollsMemberPaid"])
page2.TollsGTCCPaid = FormatDollars(expensesMap["TollsGTCCPaid"])
page2.OilMemberPaid = FormatDollars(expensesMap["OilMemberPaid"])
page2.OilGTCCPaid = FormatDollars(expensesMap["OilGTCCPaid"])
page2.OtherMemberPaid = FormatDollars(expensesMap["OtherMemberPaid"])
page2.OtherGTCCPaid = FormatDollars(expensesMap["OtherGTCCPaid"])
page2.TotalMemberPaid = FormatDollars(expensesMap["TotalMemberPaid"])
page2.TotalGTCCPaid = FormatDollars(expensesMap["TotalGTCCPaid"])
page2.TotalMemberPaidRepeated = FormatDollars(expensesMap["TotalMemberPaid"])
page2.TotalGTCCPaidRepeated = FormatDollars(expensesMap["TotalGTCCPaid"])
page2.TotalMemberPaidSIT = FormatDollars(expensesMap["StorageMemberPaid"])
page2.TotalGTCCPaidSIT = FormatDollars(expensesMap["StorageGTCCPaid"])
page2.TotalMemberPaidRepeated = page2.TotalMemberPaid
page2.TotalGTCCPaidRepeated = page2.TotalGTCCPaid
page2.ShipmentPickupDates = formattedShipments.PickUpDates
page2.TrustedAgentName = trustedAgentText
page2.ServiceMemberSignature = certificationInfo.CustomerField
page2.PPPOPPSORepresentative = certificationInfo.OfficeField
page2.SignatureDate = certificationInfo.DateField
return page2
}

func formatEmplid(serviceMember models.ServiceMember) (*string, error) {
const prefix = "EMPLID:"
const separator = " "
Expand Down Expand Up @@ -383,10 +401,10 @@ func formatSignedCertifications(signedCertifications []*models.SignedCertificati
switch {
case *cert.CertificationType == models.SignedCertificationTypePreCloseoutReviewedPPMPAYMENT:
aoaSignature = cert.Signature
aoaDate = FormatSignatureDate(cert.UpdatedAt) // We use updatedat to get the most recent signature dates
aoaDate = FormatDate(cert.UpdatedAt) // We use updatedat to get the most recent signature dates
case *cert.CertificationType == models.SignedCertificationTypeCloseoutReviewedPPMPAYMENT:
sswSignature = cert.Signature
sswDate = FormatSignatureDate(cert.UpdatedAt) // We use updatedat to get the most recent signature dates
sswDate = FormatDate(cert.UpdatedAt) // We use updatedat to get the most recent signature dates
}
}
}
Expand All @@ -397,11 +415,36 @@ func formatSignedCertifications(signedCertifications []*models.SignedCertificati
return certifications
}

// FormatSignatureDate formats the date the office members signed the SSW
func FormatSignatureDate(signature time.Time) string {
dateLayout := "02 Jan 2006" // Removed time to save space on template, per PO it's not needed
dt := signature.Format(dateLayout)
return dt
// The following formats the preparation date, as the preparation date for AOAs is the date the service counselor certifies the advance.
func formatAOADate(signedCertifications []*models.SignedCertification, ppmid uuid.UUID) string {
// This loop evaluates certs to find Office AOA Signature date
for _, cert := range signedCertifications {
if cert.PpmID != nil { // Required to avoid error, service members signatures have nil ppm ids
if *cert.PpmID == ppmid { // PPM ID needs to be checked to prevent signatures from other PPMs on the same move from populating
if *cert.CertificationType == models.SignedCertificationTypePreCloseoutReviewedPPMPAYMENT {
aoaDate := FormatDate(cert.UpdatedAt) // We use updatedat to get the most recent signature dates
return aoaDate
}
}
}
}
return FormatDate(time.Now())
}

// The following formats the preparation date, as the preparation date for SSWs is the date the closeout counselor certifies the closeout.
func formatSSWDate(signedCertifications []*models.SignedCertification, ppmid uuid.UUID) (string, error) {
// This loop evaluates certs to find Office SSW Signature date
for _, cert := range signedCertifications {
if cert.PpmID != nil { // Required to avoid error, service members signatures have nil ppm ids
if *cert.PpmID == ppmid { // PPM ID needs to be checked to prevent signatures from other PPMs on the same move from populating
if *cert.CertificationType == models.SignedCertificationTypeCloseoutReviewedPPMPAYMENT {
sswDate := FormatDate(cert.UpdatedAt) // We use updatedat to get the most recent signature dates
return sswDate, nil
}
}
}
}
return "", errors.New("Payment Packet is not certified")
}

// FormatLocation formats AuthorizedOrigin and AuthorizedDestination for Shipment Summary Worksheet
Expand Down Expand Up @@ -874,7 +917,7 @@ func (SSWPPMGenerator *SSWPPMGenerator) FillSSWPDFForm(Page1Values services.Page
var sswHeader = header{
Source: "SSWPDFTemplate.pdf",
Version: "pdfcpu v0.8.0 dev",
Creation: "2024-07-19 18:07:42 UTC",
Creation: "2024-08-21 19:31:01 UTC",
Producer: "macOS Version 13.5 (Build 22G74) Quartz PDFContext, AppendMode 1.1",
}

Expand Down Expand Up @@ -937,7 +980,7 @@ func createTextFields(data interface{}, pages ...int) []textField {
ID: fmt.Sprintf("%d", len(textFields)+1),
Name: field.Name,
Value: fmt.Sprintf("%v", value),
Multiline: false,
Multiline: true,
Locked: false,
}

Expand Down
Loading

0 comments on commit 43aa0ba

Please sign in to comment.