Laravel将CSV数据解析为数组/对象:添加了重复/错误记录

时间:2019-02-26 14:59:05

标签: php laravel

此功能的想法是上传CSV,将其与数据库中的多个点进行比较,然后根据比较的方式将每一行推入单独的数组中。这将帮助我确定在可以上传干净副本提交到数据库之前需要完成哪些手动输入工作(如果有)。由于某些原因,CSV行被多次检查并放入错误的数组中。我的代码(包括所需结果)如下。这是基本概念:

上传CSV文件,并通过rx#/ pharmacy和医生/患者创建唯一变量。

对照数据库检查rx#/ pharmacy以查看是否存在完全匹配的内容。如果是这样,请将行添加到existing_records数组中。如果存在rx#,但药房错误,则出于rx#/药房不匹配的原因将其添加到fail_array

如果数据库中不存在rx#,请将医生/患者姓名与数据库进行比较以确保它们存在。如果它们确实存在,那么两个地方的名称拼写正确,我将能够正确上载电子表格以提交到数据库,因此将记录添加到success_array中。如果不是,则由于医生/患者姓名不匹配的原因,将该记录添加到fail_array

然后将数组变成对象,以便Laravel刀片可以运行foreach循环。

控制器

public function comparePharmacyReport(Request $request)
{
    // Initialize variables
    $header_array = [];
    $existing_records_array = [];
    $existing_records = new \stdClass();
    $fail_records_array = [];
    $fail_records = new \stdClass();
    $success_records_array = [];
    $success_records = new \stdClass();

    // Get CSV file
    $upload = $request->file('upload_file');
    $file_path = $upload->getRealPath();

    // Open and read the file
    $file = fopen($file_path, 'r');
    $header = fgetcsv($file);

    // Validate the file
    foreach ($header as $key => $value) {
        // Transform $header to lowercase
        $header_item = strtolower(trim($value));

        // Place each item in the $header_array
        array_push($header_array, $header_item);
    }

    // Loop through the columns
    while ($columns = fgetcsv($file)) {
        if ($columns[0] == "") {
            continue;
        }

        $record = array_combine($header_array, $columns);

        // Update table
        $upload_rx_number = $record['rx_number'];
        $upload_doctor = $record['provider'];
        $upload_patient = $record['patient'];
        $upload_pharmacy = $record['pharmacy'];

        // create unique identifier for uploaded records
        $upload_unique_pharmacy_rx_number = $upload_pharmacy . '_' . $upload_rx_number;
        $upload_unique_doctor_patient = $upload_doctor . '_' . $upload_patient;

        // check to see if $upload_rx_number is already in Prescriptions
        if (Prescription::where('rx_number', $upload_rx_number)->first() != null) {
            // $upload_rx_number exists

            // get $database_pharmacy_id associated with the $upload_rx_number
            $rx_check_prescription = Prescription::where('rx_number', $upload_rx_number)->first();
            $database_pharmacy_id = Script::where('id', $rx_check_prescription->id)->first()->pharmacy_id;

            // create database identifier for matching to database
            $database_unique_pharmacy_rx_number = $database_pharmacy_id . '_' . $upload_rx_number;

            // check to see if the uploaded pharmacy_rx_number unique identifier matches the database pharmacy_rx_number unique identifier
            if ($upload_unique_pharmacy_rx_number == $database_unique_pharmacy_rx_number) {
                // unique identifiers match
                // add to existing array

                array_push($existing_records_array, [
                    'rx_number' => $upload_rx_number,
                    'doctor' => $upload_doctor,
                    'patient' => $upload_patient,
                    'pharmacy' => $upload_pharmacy
                ]);
            } else {
                // unique identifiers DO NOT match
                // add to fail array

                array_push($fail_records_array, [
                    'rx_number' => $upload_rx_number,
                    'doctor' => $upload_doctor,
                    'patient' => $upload_patient,
                    'pharmacy' => $upload_pharmacy,
                    'reason' => "RX number-pharmacy mismatch"
                ]);
            }

        } else {
            // $upload_rx_number doesn't exist in database
            // prescription is new

            $database_prescriptions = Prescription::all();

            // run through all $database_prescriptions and check patient names
            foreach ($database_prescriptions as $database_prescription) {
                // setup database variables
                $database_script_id = $database_prescription->script_id;
                $database_script = Script::find($database_script_id);
                $database_patient_id = $database_script->patient_id;
                $database_patient = Patient::find($database_patient_id);
                $database_doctor = $database_patient->doctors()->first();

                // create database doctor/patient identifier
                $database_unique_doctor_patient = $database_doctor->full_name . '_' . $database_patient->full_name;

                // check to see if the uploaded doctor_patient unique identifier matches the database doctor_patient unique identifier
                if ($database_unique_doctor_patient == $upload_unique_doctor_patient) {
                    // unique identifiers match
                    // add to success array

                    array_push($success_records_array, [
                        'rx_number' => $upload_rx_number,
                        'doctor' => $upload_doctor,
                        'patient' => $upload_patient,
                        'pharmacy' => $upload_pharmacy
                    ]);
                } else {
                    // unique identifiers DO NOT match
                    // add to fail array

                    array_push($fail_records_array, [
                        'rx_number' => $upload_rx_number,
                        'doctor' => $upload_doctor,
                        'patient' => $upload_patient,
                        'pharmacy' => $upload_pharmacy,
                        'reason' => "Doctor-patient name mismatch"
                    ]);
                }
            }                
        }
    }

    foreach ($existing_records_array as $key => $value) {
        $existing_records->$key = $value;
    }

    foreach ($fail_records_array as $key => $value) {
        $fail_records->$key = $value;
    }

    foreach ($success_records_array as $key => $value) {
        $success_records->$key = $value;
    }

    $data = [
        'existing_records' => $existing_records,
        'fail_records' => $fail_records,
        'success_records' => $success_records,
    ];

    return view('prescriptions.compare-results')->with($data);
}

刀片

<h1>Fail Records</h1>
<div class="table-responsive">
    <table class="table table-hover table-sm">
        <thead>
            <tr>
                <th scope="col">RX #</th>
                <th scope="col">Doctor</th>
                <th scope="col">Patient</th>
                <th scope="col">Pharmacy</th>
                <th scope="col">Fail Reason</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($fail_records as $fail_record)
                <tr>
                    <th scope="row">{{$fail_record['rx_number']}}</th>
                    <td>{{$fail_record['doctor']}}</td>
                    <td>{{$fail_record['patient']}}</td>
                    <td>{{$fail_record['pharmacy']}}</td>
                    <td>{{$fail_record['reason']}}</td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>
<br><br>
<h1>Success Records</h1>
<div class="table-responsive">
    <table class="table table-hover table-sm">
        <thead>
            <tr>
                <th scope="col">RX #</th>
                <th scope="col">Doctor</th>
                <th scope="col">Patient</th>
                <th scope="col">Pharmacy</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($success_records as $success_record)
                <tr>
                    <th scope="row">{{$success_record['rx_number']}}</th>
                    <td>{{$success_record['doctor']}}</td>
                    <td>{{$success_record['patient']}}</td>
                    <td>{{$success_record['pharmacy']}}</td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>
<br><br>
<h1>Existing Records</h1>
<div class="table-responsive">
    <table class="table table-hover table-sm">
        <thead>
            <tr>
                <th scope="col">RX #</th>
                <th scope="col">Doctor</th>
                <th scope="col">Patient</th>
                <th scope="col">Pharmacy</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($existing_records as $existing_record)
                <tr>
                    <th scope="row">{{$existing_record['rx_number']}}</th>
                    <td>{{$existing_record['doctor']}}</td>
                    <td>{{$existing_record['patient']}}</td>
                    <td>{{$existing_record['pharmacy']}}</td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>

所需结果(接收号码)

Fail Records
10  RX number-pharmacy mismatch
12  Doctor-patient name mismatch

Success Records
11

Existing Records
1
2
3
4
5
6
7

实际结果(接收号码)

Fail Records
2   RX number-pharmacy mismatch
3   RX number-pharmacy mismatch
4   RX number-pharmacy mismatch
5   RX number-pharmacy mismatch
7   RX number-pharmacy mismatch
11  Doctor-patient name mismatch
11  Doctor-patient name mismatch
11  Doctor-patient name mismatch
11  Doctor-patient name mismatch
11  Doctor-patient name mismatch
11  Doctor-patient name mismatch
11  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
12  Doctor-patient name mismatch
10  RX number-pharmacy mismatch

Success Records
11
11
11

Existing Records
1
6

CSV示例

rx_number   provider       patient           pharmacy   desired result
1           Doctor, John   Anderson, Aaron   5          existing
2           Doctor, John   Anderson, Aaron   5          existing
3           Doctor, Brad   Smith, Kevin      4          existing
4           Doctor, Brad   Smith, Kevin      4          existing
5           Doctor, Brad   Smith, Kevin      4          existing
6           Doctor, Brad   Doe, Richard      5          existing
7           Doctor, Brad   Small, Big        5          existing
10          Doctor, Brad   Hope, Bob         6          fail - rx#matches, but pharmacy wrong
11          Doctor, Brad   Hope, Bob         5          success - rx# not in system, but names correct
12          Doctor, Brad   Hope, Bobb        5          fail - patient name incorrect

1 个答案:

答案 0 :(得分:1)

这就是这里

 $database_prescriptions = Prescription::all();

        // run through all $database_prescriptions and check patient names
        foreach ($database_prescriptions as $database_prescription) {
            // setup database variables
            $database_script_id = $database_prescription->script_id;
            $database_script = Script::find($database_script_id);
            $database_patient_id = $database_script->patient_id;
            $database_patient = Patient::find($database_patient_id);
            $database_doctor = $database_patient->doctors()->first();

            // create database doctor/patient identifier
            $database_unique_doctor_patient = $database_doctor->full_name . '_' . $database_patient->full_name;

            // check to see if the uploaded doctor_patient unique identifier matches the database doctor_patient unique identifier
            if ($database_unique_doctor_patient == $upload_unique_doctor_patient) {
                // unique identifiers match
                // add to success array

                array_push($success_records_array, [
                    'rx_number' => $upload_rx_number,
                    'doctor' => $upload_doctor,
                    'patient' => $upload_patient,
                    'pharmacy' => $upload_pharmacy
                ]);
            } else {
                // unique identifiers DO NOT match
                // add to fail array

                array_push($fail_records_array, [
                    'rx_number' => $upload_rx_number,
                    'doctor' => $upload_doctor,
                    'patient' => $upload_patient,
                    'pharmacy' => $upload_pharmacy,
                    'reason' => "Doctor-patient name mismatch"
                ]);
            }
        }                
    }

对于处方数据库中的每个条目,您要检查名称是否匹配并相应地添加到失败/成功中,这可能是重复项的来源。

有很多方法可以解决此问题,但是如果修复起来有点丑陋,最省力的方法就是像现在一样使用循环遍历每条记录进行比较,而不是每次找到匹配项都添加一条记录,而不是每次找到匹配项一个不匹配项,添加一个失败的记录,找到匹配项后,将布尔值设置为true并中断,并在循环结束时进行一次简单的if检查,看看您的匹配布尔值是否为true,以及是否为true是,将记录添加到成功,如果未添加,则将记录添加到失败列表。

希望这是有道理的。