Cakephp 3 - Manual patch & save of associated data

26 views Asked by At

I am trying to manually update a primary record and the associated records (a sales order and it's line items). The fields that need to be updated in both tables happen to be exactly the same fields (Processed, Updated & DocEntry) with the caveat of WHERE dizOrderID = 1 for the associated table. The primary record updates just fine, but the associated records are never marked as dirty and are therefore not updated. Thankfully, it's not inserting additional records either.

I've looked at and used the comments from here and here. All fields in both tables are marked as accessible.

Here's my controller code:

$update = $this->dizSales->get($ID, ['contain' => ['dizSalesLines']]);
$upData = ['Processed' => 'Y', 'Updated' => date('Y-m-d H:i:s'), 'DocEntry' => $newRec['DocEntry'], 'dizSalesLines' => ['dizOrderID' => $ID, 'Processed' => 'Y', 'Updated' => date('Y-m-d H:i:s'), 'DocEntry' => $newRec['DocEntry']]];
$update = $this->dizSales->patchEntity($update, $upData, ['associated' => ['dizSalesLines']]);
$update->setDirty('dizSalesLines', true);

And here's the debug of the patch:

object(App\Model\Entity\DizSale) {

        'ID' => (int) 1,
        'Created' => object(Cake\I18n\FrozenTime) {

                'time' => '2024-01-11 16:20:11.110000-05:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

        },
        'Updated' => object(Cake\I18n\FrozenTime) {

                'time' => '2024-02-09 15:20:48.000000-05:00',
                'timezone' => 'America/New_York',
                'fixedNowTime' => false

        },
        'Processed' => 'Y',
        'Customer_ID' => 'ABC123',
        'ShipTo' => 'Location 123',
        'Street1' => '200 Station Drive',
        'Street2' => null,
        'City' => 'Anderson',
        'State' => 'SC',
        'County' => 'Anderson',
        'ZipCode' => '29621',
        'Country' => 'US',
        'DocEntry' => (int) 113649,
        'Status' => 'O',
        'Canceled' => 'N',
        'CancelDate' => null,
        'diz_sales_lines' => [
                (int) 0 => object(App\Model\Entity\DizSalesLine) {

                        'ID' => (int) 1,
                        'dizOrderID' => (int) 1,
                        'Created' => object(Cake\I18n\FrozenTime) {

                                'time' => '2024-01-11 16:24:33.323000-05:00',
                                'timezone' => 'America/New_York',
                                'fixedNowTime' => false

                        },
                        'Updated' => object(Cake\I18n\FrozenTime) {

                                'time' => '2024-01-11 16:24:33.323000-05:00',
                                'timezone' => 'America/New_York',
                                'fixedNowTime' => false

                        },
                        'Processed' => 'N',
                        'ItemCode' => '6311',
                        'Quantity' => (float) 7,
                        'WhsCode' => '52',
                        'LineStatus' => 'O',
                        'DocEntry' => null,
                        'OpenQty' => null,
                        'TargetEntry' => null,
                        '[new]' => false,
                        '[accessible]' => [
                                'ID' => true,
                                'dizOrderID' => true,
                                'Created' => true,
                                'Updated' => true,
                                'Processed' => true,
                                'ItemCode' => true,
                                'Quantity' => true,
                                'WhsCode' => true,
                                'LineStatus' => true,
                                'DocEntry' => true,
                                'OpenQty' => true,
                                'TargetEntry' => true
                        ],
                        '[dirty]' => [],
                        '[original]' => [],
                        '[virtual]' => [],
                        '[hasErrors]' => false,
                        '[errors]' => [],
                        '[invalid]' => [],
                        '[repository]' => 'DizSalesLines'

                },
                (int) 1 => object(App\Model\Entity\DizSalesLine) {

                        'ID' => (int) 2,
                        'dizOrderID' => (int) 1,
                        'Created' => object(Cake\I18n\FrozenTime) {

                                'time' => '2024-01-11 16:24:33.323000-05:00',
                                'timezone' => 'America/New_York',
                                'fixedNowTime' => false

                        },
                        'Updated' => object(Cake\I18n\FrozenTime) {

                                'time' => '2024-01-11 16:24:33.323000-05:00',
                                'timezone' => 'America/New_York',
                                'fixedNowTime' => false

                        },
                        'Processed' => 'N',
                        'ItemCode' => '5890',
                        'Quantity' => (float) 5,
                        'WhsCode' => '52',
                        'LineStatus' => 'O',
                        'DocEntry' => null,
                        'OpenQty' => null,
                        'TargetEntry' => null,
                        '[new]' => false,
                        '[accessible]' => [
                                'ID' => true,
                                'dizOrderID' => true,
                                'Created' => true,
                                'Updated' => true,
                                'Processed' => true,
                                'ItemCode' => true,
                                'Quantity' => true,
                                'WhsCode' => true,
                                'LineStatus' => true,
                                'DocEntry' => true,
                                'OpenQty' => true,
                                'TargetEntry' => true
                        ],
                        '[dirty]' => [],
                        '[original]' => [],
                        '[virtual]' => [],
                        '[hasErrors]' => false,
                        '[errors]' => [],
                        '[invalid]' => [],
                        '[repository]' => 'DizSalesLines'

                }
        ],
        '[new]' => false,
        '[accessible]' => [
                'ID' => true,
                'Created' => true,
                'Updated' => true,
                'Processed' => true,
                'Customer_ID' => true,
                'ShipTo' => true,
                'Street1' => true,
                'Street2' => true,
                'City' => true,
                'State' => true,
                'County' => true,
                'ZipCode' => true,
                'Country' => true,
                'DocEntry' => true,
                'Status' => true,
                'Canceled' => true,
                'CancelDate' => true
        ],
        '[dirty]' => [
                'Processed' => true,
                'Updated' => true,
                'DocEntry' => true,
                'DizSalesLines' => true
        ],
        '[original]' => [
                'Processed' => 'N',
                'Updated' => object(Cake\I18n\FrozenTime) {

                        'time' => '2024-01-11 16:20:11.110000-05:00',
                        'timezone' => 'America/New_York',
                        'fixedNowTime' => false

                },
                'DocEntry' => null
        ],
        '[virtual]' => [],
        '[hasErrors]' => false,
        '[errors]' => [],
        '[invalid]' => [],
        '[repository]' => 'DizSales'

}

I see that the patch has picked up the "dirty" for the primary table but the associated tables are not and I'm setting the dirty for the associated (I think I am). I've called setDirty() before and after the patchEntity without any differences.

I'm so stumped and I know that the answer is probably right in front of me but I think I've looked at this too long.

TIA for any and all help. I appreciate it.

1

There are 1 answers

0
Salines On

Your data structure should look like this:

$upData = [
    'Processed' => 'Y',
    'Updated' => date('Y-m-d H:i:s'),
    'DocEntry' => $newRec['DocEntry'],
    'dizSalesLines' => [
        [
            'id' => 1,
            'dizOrderID' => $ID,
            'Processed' => 'Y',
            'Updated' => date('Y-m-d H:i:s'),
            'DocEntry' => $newRec['DocEntry']
        ],
        [
            'id' => 2,
            'dizOrderID' => $ID,
            'Processed' => 'Y',
            'Updated' => date('Y-m-d H:i:s'),
            'DocEntry' => $newRec['DocEntry']
        ],
    ]
];