1

I'm not sure if I'm on the right track for this or not. So I've been given an assignment where I have two reports on two different cvs files that hold the information below:

One csv holds payment information under these headers:

Payments.csv:

id,employee_id,payment,code 

The other holds employee information using the following headers:

Employee.csv:

id,first_name,last_name,email,city,ip_address

The primary key here is id in the employee.csv file while the foreign key is employee_id in the payments.csv file. This means that id on the employee.csv file should match up with employee_id on the payment.csv.

With this information I am supposed to create 2 classes. One will be an employee class that creates objects using the information from the employee.csv file. The other will be a payments class that creates objects using the payments.csv.

I will then need to compare both sets of objects where id on employee.csv equals employee_id on payments.csv. Then I'd like to use this data to create a new csv that consolidates the data on both csv files into one file where employees on employee.csv are linked to their payments on payments.csv.

Any assistance or guidance is appreciated! This is what I've go so far. I might be way off so please no judgement. Just trying to learn. I've hit a road block on exactly what to do after being able to create employee and payment objects.

#Class that creates employee object

class Employee {

    [Int]$id
    [String]$first_name
    [String]$last_name
    [String]$email
    [String]$city
    [String]$ip_address

    Employee ([Int]$id,[String]$first_name,[String]$last_name,[String]$email,[String]$city,[String]$ip_address){

        $This.id = $id
        $This.first_name = $first_name
        $This.last_name = $last_name
        $This.email = $email
        $This.city = $city
        $This.ip_address = $ip_address
    }
}

#Class that creates payment object

class Payment{

    [Int]$id
    [Int]$employee_id
    [String]$payment
    [String]$code

    Payment ([Int]$id,[Int]$employee_id,[String]$payment,[String]$code){

        $This.id = $id 
        $This.employee_id = $employee_id
        $This.payment = $payment
        $This.code = $code
    }
}

#Importing spreadsheets w/ data being used

$ImportedEmployees = Import-Csv ".\Employee.csv" 
$ImportedPayments = Import-Csv ".\Payment.csv"
$FinalEmployeeReport = @{}

#Calling [Employee] to create new objects using the employee.csv

Foreach ($Employee in $ImportedEmployees){

    $NewEmployeeEntry = [Employee]::new([Int]$Employee.id,[String]$Employee.first_name,[String]$Employee.last_name,[String]$Employee.email,[String]$Employee.city,[String]$Employee.ip_address)

    #Adding object to $FinalEmployeeReport

    $FinalEmployeeReport.Add([String]$NewEmployeeEntry.last_name,[Int]$NewEmployeeEntry.id)
}

Foreach ($Payment in $ImportedPayments)
{
    $NewPayment = [Payment]::new([Int]$Payment.id,[Int]$Payment.employee_id,[String]$Payment.payment,[String]$Payment.code)

    $FinalEmployeeReport.Add[Int]$Payment.employee_id,[String]$Payment.payment))
}


Foreach($Payment in $ImportedPayments){

    $NewPayment = [Payment]::new([Int]$Payment.id,[Int]$Payment.employee_id,[String]$Payment.payment,[String]$Payment.code)

    Foreach($NewEmployeeEntry in $Payment){

        if($NewPayment.employee_id -eq $NewEmployeeEntry.id ){

            $NewEmployeeEntry.Add($NewPayment)  
        }
    } 
} 

$FinalEmployeeReport.Add($NewEmployeeEntry)
zett42
  • 25,437
  • 3
  • 35
  • 72
  • Hello Elijah, The answer you seek can be found in this link. If you use the **match** command PowerShell you match the same ID and build a new table for export. – NeoTheNerd Dec 05 '21 at 08:07
  • This sounds like a homework assignment. ;-} This is also real overkill for what the end result is to be. You don't need classes (object blueprints) to join data from csv files and the like. [You use classes to create instances of that class for another purpose](https://duckduckgo.com/?q=powershell+%27why+use+classes%27&t=h_&ia=web). [Just join/match on the ID and output a new file](https://duckduckgo.com/?q=%27powershell+join+two+csv+file+by+id%27&t=h_&ia=web). This could be just a one-liner script effort. – postanote Dec 05 '21 at 08:26
  • 2
    I don't think there is a reason to build classes (with static properties) for this. Using this [`Join-Object script`](https://www.powershellgallery.com/packages/Join)/[`Join-Object Module`](https://www.powershellgallery.com/packages/JoinModule) (see also: [In Powershell, what's the best way to join two tables into one?](https://stackoverflow.com/a/45483110/1701026)): `Import-Csv ".\Employee.csv" lJoin (Import-Csv ".\Payment.csv") -on id -eq employee_id` – iRon Dec 05 '21 at 08:27

1 Answers1

1

One way of achieving this is by using a simple loop and inside find matching records based on the employee id.

If these are your input fies

payments.csv

id,employee_id,payment,code
123,8765,1500,abc123
456,9007,100,xyz456
999,9007,200,def666

employee.csv

id,first_name,last_name,email,city,ip_address
9007,John,Doe,jdoe@yourcompany.com,Miami,10.10.10.10
8765,Joe,Bloggs,jbloggs@somewhere.org,Salem,10.11.12.13

Then try

# load both csv files
$payments  = Import-Csv -Path 'D:\Test\payments.csv'
$employees = Import-Csv -Path 'D:\Test\employee.csv'
# loop through the employees records
$result = foreach ($emp in $employees){
    # find a record in the payments.csv where the .employee_id is equal to the .id in the employee.csv
    $payments | Where-Object { $_.employee_id -eq $emp.id } | ForEach-Object {
        # create an object with properties from both csv files combined
        $obj = $emp | Select-Object @{Name = 'employee_id'; Expression = {$_.id}}, * -ExcludeProperty id
        # add the details from $payments to this
        $obj | Add-Member -MemberType NoteProperty -Name 'payment_id' -Value $_.id
        $obj | Add-Member -MemberType NoteProperty -Name 'payment' -Value $_.payment
        $obj | Add-Member -MemberType NoteProperty -Name 'payment_code' -Value $_.code
        # output the combined object to be collected in variable $result
        $obj
    }
}
# now you can show the results in the console
$result | Format-Table -AutoSize

# and save as new csv file
$result | Export-Csv -Path 'D:\Test\EmployeePayments.csv' -NoTypeInformation

Output on screen:

employee_id first_name last_name email                 city  ip_address  payment_id payment payment_code
----------- ---------- --------- -----                 ----  ----------  ---------- ------- ------------
9007        John       Doe       jdoe@yourcompany.com  Miami 10.10.10.10 456        100     xyz456      
9007        John       Doe       jdoe@yourcompany.com  Miami 10.10.10.10 999        200     def666      
8765        Joe        Bloggs    jbloggs@somewhere.org Salem 10.11.12.13 123        1500    abc123 
Theo
  • 57,719
  • 8
  • 24
  • 41