Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions cypress/e2e/ui/reports/standard.csv.reports.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,86 @@ describe("csv export", () => {
expect(response.body).to.not.include("Parse error");
});
});

it("should include address columns in CSV export with family fallback", () => {
// Test default format includes address fields when requested
// This also validates the family fallback logic for addresses
cy.request({
method: "POST",
url: "/CSVCreateFile.php",
form: true,
body: {
output: "csv",
Format: "default",
familyonly: "false",
Source: "all",
Address1: "1",
Address2: "1",
City: "1",
State: "1",
Zip: "1"
}
}).then((response) => {
expect(response.status).to.eq(200);
expect(response.headers["content-type"]).to.include("text/csv");

// Verify no PHP errors in response
expect(response.body).to.not.include("Fatal error");
expect(response.body).to.not.include("Parse error");

// Verify CSV header contains address columns
const lines = response.body.split('\n');
expect(lines.length).to.be.greaterThan(1);
const header = lines[0].toLowerCase();
expect(header).to.include("address 1");
expect(header).to.include("city");
expect(header).to.include("state");

// Verify at least one data row exists (family fallback should populate addresses)
// Filter out empty lines
const dataLines = lines.slice(1).filter(line => line.trim().length > 0);
expect(dataLines.length).to.be.greaterThan(0, "Expected at least one data row in export");
});
});

it("should include address columns in rollup format CSV export", () => {
// Test rollup format includes address fields when requested
cy.request({
method: "POST",
url: "/CSVCreateFile.php",
form: true,
body: {
output: "csv",
Format: "rollup",
familyonly: "false",
Source: "all",
Address1: "1",
Address2: "1",
City: "1",
State: "1",
Zip: "1"
}
}).then((response) => {
expect(response.status).to.eq(200);
expect(response.headers["content-type"]).to.include("text/csv");

// Verify no PHP errors in response
expect(response.body).to.not.include("Fatal error");
expect(response.body).to.not.include("Parse error");

// Verify CSV header contains address columns
const lines = response.body.split('\n');
expect(lines.length).to.be.greaterThan(1);
const header = lines[0].toLowerCase();
expect(header).to.include("address 1");
expect(header).to.include("city");
expect(header).to.include("state");

// Verify at least one data row exists
const dataLines = lines.slice(1).filter(line => line.trim().length > 0);
expect(dataLines.length).to.be.greaterThan(0, "Expected at least one data row in export");
});
});
});

describe("advanced deposit report", () => {
Expand Down
40 changes: 14 additions & 26 deletions src/CSVCreateFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -374,32 +374,20 @@
extract($aRow);
$person = PersonQuery::create()->findOneById($per_ID);

// Use person data only - each person must enter their own information
if ($sFormat === 'rollup') {
// Even in rollup format, use person data (no family inheritance)
$sHomePhone = $per_HomePhone ?? '';
$sWorkPhone = $per_WorkPhone ?? '';
$sCellPhone = $per_CellPhone ?? '';
$sCountry = $per_Country ?? '';
$sAddress1 = $per_Address1 ?? '';
$sAddress2 = $per_Address2 ?? '';
$sCity = $per_City ?? '';
$sState = $per_State ?? '';
$sZip = $per_Zip ?? '';
$sEmail = $per_Email ?? '';
} else {
// Individual data - use person data only
$sHomePhone = $per_HomePhone ?? '';
$sWorkPhone = $per_WorkPhone ?? '';
$sCellPhone = $per_CellPhone ?? '';
$sCountry = $per_Country ?? '';
$sAddress1 = $per_Address1 ?? '';
$sAddress2 = $per_Address2 ?? '';
$sCity = $per_City ?? '';
$sState = $per_State ?? '';
$sZip = $per_Zip ?? '';
$sEmail = $per_Email ?? '';
}
// Use person data with fallback to family data for addresses/contact
// This ensures members without personal addresses still get exported with their family's address
// Note: Similar logic exists in DirectoryReports.php - consider centralizing in PersonService
// if this pattern needs to be reused elsewhere (see issue #7937)
$sHomePhone = !empty($per_HomePhone) ? $per_HomePhone : ($fam_HomePhone ?? '');
$sWorkPhone = $per_WorkPhone ?? '';
$sCellPhone = $per_CellPhone ?? '';
$sCountry = !empty($per_Country) ? $per_Country : ($fam_Country ?? '');
$sAddress1 = !empty($per_Address1) ? $per_Address1 : ($fam_Address1 ?? '');
$sAddress2 = !empty($per_Address2) ? $per_Address2 : ($fam_Address2 ?? '');
$sCity = !empty($per_City) ? $per_City : ($fam_City ?? '');
$sState = !empty($per_State) ? $per_State : ($fam_State ?? '');
$sZip = !empty($per_Zip) ? $per_Zip : ($fam_Zip ?? '');
$sEmail = !empty($per_Email) ? $per_Email : ($fam_Email ?? '');

// Check if we're filtering out people with incomplete addresses
if (!($bSkipIncompleteAddr && (strlen($sCity) === 0 || strlen($sState) === 0 || strlen($sZip) === 0 || (strlen($sAddress1) === 0 && strlen($sAddress2) === 0)))) {
Expand Down
17 changes: 9 additions & 8 deletions src/Reports/DirectoryReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,17 @@
$pdf->sRecordName .= ' ' . MiscUtils::formatBirthDate($per_BirthYear, $per_BirthMonth, $per_BirthDay, $per_Flags);
}

// Use person data only - each person must enter their own information
$sAddress1 = $per_Address1 ?? '';
$sAddress2 = $per_Address2 ?? '';
$sCity = $per_City ?? '';
$sState = $per_State ?? '';
$sZip = $per_Zip ?? '';
$sHomePhone = $per_HomePhone ?? '';
// Use person data with fallback to family data for addresses
// This ensures members without personal addresses still appear in the directory with their family's address
$sAddress1 = !empty($per_Address1) ? $per_Address1 : ($fam_Address1 ?? '');
$sAddress2 = !empty($per_Address2) ? $per_Address2 : ($fam_Address2 ?? '');
$sCity = !empty($per_City) ? $per_City : ($fam_City ?? '');
$sState = !empty($per_State) ? $per_State : ($fam_State ?? '');
$sZip = !empty($per_Zip) ? $per_Zip : ($fam_Zip ?? '');
$sHomePhone = !empty($per_HomePhone) ? $per_HomePhone : ($fam_HomePhone ?? '');
$sWorkPhone = $per_WorkPhone ?? '';
$sCellPhone = $per_CellPhone ?? '';
$sEmail = $per_Email ?? '';
$sEmail = !empty($per_Email) ? $per_Email : ($fam_Email ?? '');

if ($bDirAddress) {
if (strlen($sAddress1)) {
Expand Down
Loading