Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

yonka's avatar

How to solve softDelete erorr I am using UniqueNoGenerator helper to generate Unique Invoice No

I am using UniqueNoGenerator helper to generate Unique Invoice No, When I delete Invoice_no it shows an error not able to generate or save new record. this is the code to generate invoice_no and receipt number if the invoice has receipts:

if ($branch = strtoupper(substr(auth()->user()->branch->branch_name,0,2))) {
            $invoice_no = Helper::UniqueNoGenerator(new SalesInvoice(), 'invoice_no', 5, 'SINV['.$branch.']'); /** Generate Invoice No */
        }
        if ($branch = strtoupper(substr(auth()->user()->branch->branch_name,0,2))) {
            $receipt_no = Helper::UniqueNoGenerator(new SalesInvoiceReceipt(), 'receipt_no', 5, 'SRV['.$branch.']'); /** Generate Invoice No */
        }
0 likes
5 replies
LaryAI's avatar

The issue arises because Laravel's soft deletes do not actually remove the record from the database; instead, they set the deleted_at column. If your UniqueNoGenerator checks for uniqueness using a query like:

SalesInvoice::where('invoice_no', $generatedNo)->exists()

then soft-deleted records will still be found, and the generator will think the number is taken, causing the error.

Solution:
You need to ensure that your uniqueness check ignores soft-deleted records. In Eloquent, this is done by default when using the model (unless you use withTrashed() or onlyTrashed()), but if your helper is using a raw query or not using Eloquent's default behavior, you may need to adjust it.

1. Check Your Helper

Make sure your UniqueNoGenerator uses the model's query builder, which excludes soft-deleted records by default:

SalesInvoice::where('invoice_no', $generatedNo)->exists();

If you are using withTrashed() or a custom query, remove it so soft-deleted records are not included.

2. Example Fix

If your helper uses a query like this:

$model::where($field, $number)->exists();

That is correct, as it will not include soft-deleted records.

But if you see:

$model::withTrashed()->where($field, $number)->exists();

Remove withTrashed() so soft-deleted records are not checked.

3. If You Need to Keep Numbers Unique Forever

If you want to never reuse an invoice number, even if soft-deleted, then your current logic is correct. But if you want to allow reuse after soft delete, make sure not to include soft-deleted records in your uniqueness check.

4. Example Helper Adjustment

Here’s a simplified example of how your helper should check for uniqueness:

public static function UniqueNoGenerator($model, $field, $length, $prefix)
{
    do {
        $number = $prefix . str_pad(mt_rand(1, 99999), $length, '0', STR_PAD_LEFT);
    } while ($model::where($field, $number)->exists()); // This ignores soft-deleted records

    return $number;
}

Do not use withTrashed() unless you want to include soft-deleted records.


Summary:

  • Make sure your uniqueness check does not include soft-deleted records (do not use withTrashed()).
  • If you want to keep numbers unique forever, include soft-deleted records.
  • Adjust your helper accordingly.

If you need more specific help, please share your UniqueNoGenerator code!

yonka's avatar

The helper function i am using is this one

// generate unique invoiceID
    public static function UniqueNoGenerator($model, $trow, $length = 4, $prefix){
        $data = $model::orderBy('id','desc')->first();
        if(!$data){
            $og_length = $length;
            $last_number = '';
        }else{
            $code = substr($data->$trow, strlen($prefix)+1);
            $actial_last_number = ($code/1)*1;
            $increment_last_number = ((int)$actial_last_number)+1;
            $last_number_length = strlen($increment_last_number);
            $og_length = $length - $last_number_length;
            $last_number = $increment_last_number;
        }
        $zeros = "";
        for($i=0;$i<$og_length;$i++){
            $zeros.="0";
        }
        return $prefix.'-'.$zeros.$last_number;
    }
Glukinho's avatar
  1. comparison is done with === (preferably) and == operators, you have one equal sign:
if ($branch = strtoupper(....

Most likely this is mistake.

  1. what error exactly you have?

  2. show Helper::UniqueNoGenerator class

yonka's avatar
yonka
OP
Best Answer
Level 2

I have just solved by adding withTrashed to UniqueNoGenerator Static function like this

$data = $model::withTrashed()->orderBy('id','desc')->first();

So Thank u guys for your help

Please or to participate in this conversation.