laravel-auditing icon indicating copy to clipboard operation
laravel-auditing copied to clipboard

AuditSync is not working

Open ahmedgadit opened this issue 3 years ago • 1 comments
trafficstars

Q A
Bug? yes
New Feature? no
Framework Laravel
Framework version 8.12
Package version 13.0
PHP version 8.0.12

Actual Behaviour

$automation->products()->auditSync('products', array)

this does not audit any entry to automation_audits when trying to use auditSync not recieving any error but doesn't get any audit

Expected Behaviour

it should fire an event of update send the relational changes to audit

Steps to Reproduce

List all the steps needed to reproduce the issue you're having.

i have updated my config file according to v13

Make sure to include code (affected models, configuration, ...).

Automation Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use JamesDordoy\LaravelVueDatatable\Traits\LaravelVueDatatableTrait;
use OwenIt\Auditing\Contracts\Auditable;
use App\Models\Traits\isCachedEntity;
use App\AuditDrivers\CustomAuditDriver;
class Automation extends Model implements Auditable
{
    use \OwenIt\Auditing\Auditable;
    use HasFactory;
    use SoftDeletes;
    use \App\Models\Traits\HasSimpleScope;
    use \App\Models\Traits\HasStatusScope;
    use LaravelVueDatatableTrait;
    use isCachedEntity;
    /**
     * The key name to be used when calling cache or updating the cache.
     *
     * @var string
     */
    public $cache_key = 'automations';

    // protected $softCascade = ['product_variants'];
    // TODO: Link the AutomationProductVariant model.
    // Algolia Search for realtional Data
    public function toSearchableArray()
    {
        $this->products;
        $this->warehouse;
        $this->carrier;

        $array = $this->toArray();

        return $this->transform($array);
    }

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'is_default' => 'boolean',
        'is_priority' => 'boolean',
        'status' => 'boolean',
    ];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $guarded = [];
    protected $auditDriver = CustomAuditDriver::class;

    /**
     * For Datatable columns.
     *
     * @var array
     */
    protected $dataTableColumns = [
        'id' => [
            'searchable' => true,
        ],
        'name' => [
            'searchable' => true,
        ],
        'status' => [
            'searchable' => false,
        ],
        'is_priority' => [
            'searchable' => false,
        ],
        'is_default' => [
            'searchable' => false,
        ],
        'delivery_instructions' => [
            'searchable' => false,
        ],
    ];

    protected $dataTableRelationships = [
        'belongsTo' => [
            'carrier' => [
                'model' => Carrier::class,
                'foreign_key' => 'carrier_id',
                'columns' => [
                    'name' => [
                        'searchable' => true,
                        'orderable' => true,
                    ],
                ],
            ],
            'warehouse' => [
                'model' => Warehouse::class,
                'foreign_key' => 'warehouse_id',
                'columns' => [
                    'name' => [
                        'searchable' => true,
                        'orderable' => true,
                    ],
                ],
            ],
            'state' => [
                'model' => State::class,
                'foreign_key' => 'state_id',
                'columns' => [
                    'name' => [
                        'searchable' => true,
                        'orderable' => true,
                    ],
                ],
            ],
        ],
    ];

    /**
     * Get all of the states.
     */
    public function state()
    {
        return $this->belongsTo(State::class, 'state_id')->select(['id', 'name', 'shortcode', 'status']);
    }

    /**
     * Get all of the products variants.
     */
    public function products()
    {
        return $this->belongsToMany(ProductVariant::class)->select(
            [
                'product_variants.id',
                'product_variants.title',
                'product_variants.sku',
                'product_variants.ecommerce_id',
                'product_variants.ecommerce_product_id',
                'is_dependant',
                'product_variants.weight',
                'automation_product_variant.automation_id as auto_id',
                'product_id',
                'display_order',
            ]
        )->orderBy('display_order');
    }

    /**
     * Get all of the products variants.
     */
    public function product_variants()
    {
        return $this->belongsToMany(ProductVariant::class)->select(
            [
                'product_variants.id',
                'product_variants.title',
                'product_variants.sku',
                'product_variants.ecommerce_id',
                'product_variants.ecommerce_product_id',
                'is_dependant',
                'product_variants.weight',
                'automation_product_variant.automation_id as auto_id',
                'product_id',
                'display_order',
            ]
        )->orderBy('display_order');
    }

    /**
     * Get all of the products.
     */
    public function productss()
    {
        return Product::whereIn('id', $this->products()->get()->pluck('product_id')->unique())->get();
    }

    /**
     * Decode Automation products to Array from Json.
     */
    public function getProductsAttribute($value)
    {
        return json_decode($value);
    }

    /**
     * Get the States for the Automations.
     */
    public function carrier()
    {
        return $this->belongsTo(Carrier::class)->select(
            [
                'carriers.id',
                'carriers.fulfillment_id',
                'carriers.fulfillment_carrier_id',
                'carriers.name',
                'carriers.delivery_instructions',
                'carriers.locality',
                'carriers.atl_enabled',
                'carriers.view_format',
                'carriers.status',
                'carriers.is_default',
                'carriers.fulfillment_service',
            ]
        );
    }

    /**
     * Get the States for the Automations.
     */
    public function warehouse()
    {
        return $this->belongsTo(Warehouse::class)->select(
            [
                'id',
                'fulfillment_id',
                'location_id',
                'state_id',
                'name',
                'contact',
                'special_instructions',
                'address1',
                'address2',
                'suburb',
                'postcode',
            ]
        );
    }

    /**
     * Get the States for the Automations.
     */
    public function fulfillment_service()
    {
        return $this->carrier->fulfillment_service;
    }

    /**
     * Get the States for the Automations.
     */
    public function dependant_products()
    {
        return $this->products()->where('is_dependant', 1)->get();
    }

    /**
     * Get the States for the Automations.
     */
    public function independant_products()
    {
        return $this->products()->where('is_dependant', 0)->get();
    }

    /**
     * hasAllProducts.
     *
     * @param array $base_products
     * @return bool
     */
    public function hasAllProducts(array $base_products): bool
    {
        $payload_variant_ids = collect($base_products)->pluck('variant_id')->toArray();

        return $this->products()->whereIn('automation_product_variant.ecommerce_id', $payload_variant_ids)->count() === count($payload_variant_ids);
    }
}

Automation_audit model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class AutomationAudit extends Model implements \OwenIt\Auditing\Contracts\Audit
{
    use \OwenIt\Auditing\Audit;

    protected $audit_table = 'automation_audits';

    protected $guarded = [];

    protected $casts = [
        'old_values' => 'json',
        'new_values' => 'json',
        // Note: Please do not add 'auditable_id' in here, as it will break non-integer PK models
    ];

    public function getTable(): string
    {
        return $this->audit_table;
    }
}

AutomationProduct Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;

class AutomationProductVariants extends Model implements Auditable
{
    use HasFactory;
    use \OwenIt\Auditing\Auditable;

    protected $table = 'automation_product_variant';
}

Finally my custom audit driver


<?php

namespace App\AuditDrivers;

use OwenIt\Auditing\Contracts\Audit;
use OwenIt\Auditing\Contracts\Auditable;
use OwenIt\Auditing\Contracts\AuditDriver;

class CustomAuditDriver implements AuditDriver
{
    public function audit(Auditable $model): Audit
    {
        $implementation = get_class($model) . 'Audit';

        return call_user_func([$implementation, 'create'], $model->toAudit());
    }

    public function prune(Auditable $model): bool
    {
        if (($threshold = $model->getAuditThreshold()) > 0) {
            $forRemoval = $model->audits()
                ->latest()
                ->get()
                ->slice($threshold)
                ->pluck('id');

            if (!$forRemoval->isEmpty()) {
                return $model->audits()
                    ->whereIn('id', $forRemoval)
                    ->delete() > 0;
            }
        }

        return false;
    }
}

ahmedgadit avatar Mar 18 '22 14:03 ahmedgadit

Use markdown correctly, ```php

PaolaRuby avatar Jun 24 '22 21:06 PaolaRuby

Use markdown correctly, ```php

Fixed it :)

A lot of info here! - at a glance i am not able to see the issue, and i probably will not be able to recreate your setup here in order to reproduce the issue. you may need to simple it down in order to narrow in.

In some cases when i'm trying to figure out why a package i'm using is not doing what i expect it to, i create a fresh laravel application and install the package. That way i am able to confirm that it works as expected when decoupled from my application. Then i can experiment with modifications.

MortenDHansen avatar Mar 14 '23 09:03 MortenDHansen