kfirba
kfirba
2 months ago (211,115 XP)

@Lalit I'd suggest you learn how to read those stack traces for your own benefit.

Anyway, it seems like your issue is with some code in your Invoice model class at line 275. What does line 275 looks like? Paste the full method code which line 275 resides in.

Lalit

namespace App\Models;

use Advmaker\CarbonPeriod; use Alsofronie\Uuid\UuidModelTrait; use App\Models\Child; use Carbon\Carbon; use Exception; use Illuminate\Support\Facades\Log; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Spatie\MediaLibrary\HasMedia\HasMediaTrait; use Spatie\MediaLibrary\HasMedia\Interfaces\HasMedia;

class Invoice extends Model implements HasMedia {

use UuidModelTrait, SoftDeletes, HasMediaTrait;

protected $fillable = [
    'ends_at',
    'starts_at',
    'enrolment_id',
    'value',
    'subsidies',
    
];

protected $dates = [
    'starts_at',
    'ends_at',
];

protected $casts = [
    'data' => 'array',
];

/**
 * @var Collection
 */
protected $deductions;

/* protected static function boot() { parent::boot(); static::saving(function ($invoice) { $enrolment = Enrolment::find($invoice->enrolment_id);

        $enrolmentPeriod = $enrolment
            ->periods()
            ->where('ends_at', '>=', $invoice->starts_at)
            ->orderBy('ends_at', 'ASC')
            ->first();

        if (! $enrolmentPeriod) {
            $enrolmentPeriod = $enrolment
                ->periods()
                ->whereNull('ends_at')
                ->first();
        };

        if (! $enrolmentPeriod) {
            throw new Exception("Error saving invoice. Enrolment period is required.", 1);
        }

        switch ($enrolmentPeriod->payment_frequency) {
            default:
            case 'weekly':
                $invoice->ends_at = $invoice->starts_at->copy()->startOfDay()->addWeeks(1)->subSeconds(1);
                break;
            case 'fortnightly':
                $invoice->ends_at = $invoice->starts_at->copy()->startOfDay()->addWeeks(2)->subSeconds(1);
                break;
            case 'monthly':
                $invoice->ends_at = $invoice->starts_at->copy()->startOfDay()->addMonths(1)->subSeconds(1);
                break;
        }

        $invoice->deductions = new Collection();

        $invoice->days_to_pay     = 0;
        $invoice->days_deducted   = 0;
        $invoice->subsidies         = 0;
        $invoice->discounts        = 0;
        $invoice->total_fee       = 0;
        $invoice->total_deduction = 0;
        $invoice->total           = 0;
        $data                     = [];
        $data['details']          = '';
        $period                   = CarbonPeriod::instance($invoice->starts_at, $invoice->ends_at);

        $period->eachDays(1, function ($day) use ($invoice, $enrolment, &$data) {

            if (! $day->start()->isWeekend()) {
                $enrolmentPeriod = $enrolment
                    ->periods()
                    ->where('starts_at', '<=', $day->end())
                    ->where('ends_at', '>=', $day->start())
                    ->first();
                //if enrolment period exists check
                if($enrolmentPeriod) {

                    $discounts = $enrolmentPeriod
                        ->discounts()
                        ->get();

                    $subsidies = $enrolmentPeriod
                        ->subsidies()->where('status', 'Subsidy Received')
                        ->get();

                    //  Log::info('Current financial year: '. $day->start()->year);

                    // Get the fee of the active enrolment type
                    $year = FinancialYear::where('end_year', $day->start()->year + 1)->first();
                    //Log::info('Current financial year: '. $year->id);

                    $fee = $enrolmentPeriod->enrolmentType->fees()->where('financial_year_id', $year->id)->first();

                    $invoice->total_fee += $fee->value / 5;
                    $invoice->days_to_pay++;

                    $details = [
                        'date' => $day,
                        'daily_fee' => $fee->value / 5,
                        'daily_discounts' => 0,
                        'daily_subsidies' => 0,
                        'total' => 0,
                    ];

                    // Get the active discounts
                    foreach ($discounts as $discount) {
                        $invoice->days_deducted++;
                        $invoice->total_deduction += $discount->value / 5;
                        $details['daily_discounts'] += $discount->value / 5;
                        $invoice->discounts += $discount->value / 5;
                    }
                    // Get the active subsidies
                    foreach ($subsidies as $subsidy) {
                        //$invoice->days_deducted++;
                        //$invoice->total_deduction += $subsidy->value / 5;
                        $details['daily_subsidies'] += $subsidy->value / 5;
                        $invoice->subsidies += $subsidy->value / 5;
                    }
                    $details['total'] = $details['daily_fee'] - $details['daily_discounts'];// - $details['daily_subsidies'];
                    $data['details'][] = $details;
                }
                else
                {
                    Log::debug('[Invoice] - function() :: Enrolment period does not exists',
                        [$enrolment->id,$day->end(),$day->start()]);
                }
                //end enrolment period check;
            }
        });
        $invoice->total = $invoice->total_fee - $invoice->total_deduction;
        $invoice->data = $data['details'];
    });
}
*/
public function CreateInvoice(){
        $invoice=$this;
        $enrolment = Enrolment::find($invoice->enrolment_id);

        $enrolmentPeriod = $enrolment
            ->periods()
            ->where('ends_at', '>=', $invoice->starts_at)
            ->orderBy('ends_at', 'ASC')
            ->first();

        if (! $enrolmentPeriod) {
            $enrolmentPeriod = $enrolment
                ->periods()
                ->whereNull('ends_at')
                ->first();
        };

        if (! $enrolmentPeriod) {
            throw new Exception("Error saving invoice. Enrolment period is required.", 1);
        }

        switch ($enrolmentPeriod->payment_frequency) {
            default:
            case 'weekly':
                $invoice->ends_at = $invoice->starts_at->copy()->startOfDay()->addWeeks(1)->subSeconds(1);
                break;
            case 'fortnightly':
                $invoice->ends_at = $invoice->starts_at->copy()->startOfDay()->addWeeks(2)->subSeconds(1);
                break;
            case 'monthly':
                $invoice->ends_at = $invoice->starts_at->copy()->startOfDay()->addMonths(1)->subSeconds(1);
                break;
        }

        $invoice->deductions = new Collection();

        $invoice->days_to_pay     = 0;
        $invoice->days_deducted   = 0;
        $invoice->subsidies         = 0;
        $invoice->discounts        = 0;
        $invoice->total_fee       = 0;
        $invoice->total_deduction = 0;
        $invoice->total           = 0;
        $data                     = [];
        $data['details']          = '';
        $period                   = CarbonPeriod::instance($invoice->starts_at, $invoice->ends_at);

        $period->eachDays(1, function ($day) use ($invoice, $enrolment, &$data) {

            if (! $day->start()->isWeekend()) {
                $enrolmentPeriod = $enrolment
                    ->periods()
                    ->where('starts_at', '<=', $day->end())
                    ->where('ends_at', '>=', $day->start())
                    ->orderBy('ends_at','DESC')
                    ->first();


                //if enrolment period exists check
                if($enrolmentPeriod) {
                    Log::info('[Generate invoice] - Enrolment Period for child ',[$invoice->enrolment->child->name,$enrolmentPeriod->id]);
                    $discounts = $enrolmentPeriod
                        ->discounts()
                        ->where('starts_at', '<=', $day->end())
                        ->where('ends_at', '>=', $day->start())
                        ->get();

                    $subsidies = $enrolmentPeriod
                        ->subsidies()->where('status', 'Subsidy Received')
                        ->where('starts_at', '<=', $day->end())
                        ->where('ends_at', '>=', $day->start())
                        ->get();


                    Log::info('[Generate invoice] - Enrolment Period for child - enrolment_ id- subsidy_value ',[$invoice->enrolment->child->name,$enrolmentPeriod->id,$enrolmentPeriod
                        ->subsidies()->where('status', 'Subsidy Received')
                        ->sum('value')]);
                    //  Log::info('Current financial year: '. $day->start()->year);

                    // Get the fee of the active enrolment type
                    $year = FinancialYear::where('end_year', $day->start()->year + 1)->first();
                    //Log::info('Current financial year: '. $year->id);

                    $fee = $enrolmentPeriod->enrolmentType->fees()->where('financial_year_id', $year->id)->first();

                    $invoice->total_fee += $fee->value / 5;
                    $invoice->days_to_pay++;

                    $details = [
                        'date' => $day,
                        'daily_fee' => $fee->value / 5,
                        'daily_discounts' => 0,
                        'daily_subsidies' => 0,
                        'total' => 0,
                    ];

                    // Get the active discounts
                    foreach ($discounts as $discount) {
                        $invoice->days_deducted++;
                        $invoice->total_deduction += $discount->value / 5;
                        $details['daily_discounts'] = $discount->value / 5;
                        $invoice->discounts += $discount->value / 5;
                    }
                    // Get the active subsidies
                    foreach ($subsidies as $subsidy) {
                        $invoice->days_deducted++;
                        $invoice->total_deduction += $subsidy->value / 5;
                        $details['daily_subsidies'] = $subsidy->value / 5;
                        $invoice->subsidies += $subsidy->value / 5;
                    }
                    $details['total'] = $details['daily_fee'] - $details['daily_discounts'];// - $details['daily_subsidies'];
                    $data['details'][] = $details;
                }
                else
                {
                    Log::debug('[Invoice] - function() :: Enrolment period does not exists',
                        [$enrolment->id,$day->end(),$day->start()]);
                }
                //end enrolment period check;
            }
        });
        $invoice->total = $invoice->total_fee - $invoice->discounts;
        $invoice->data = $data['details'];

        $invoice->save();

}

#region Scopes
public function scopeOfCustomer(Builder $query, Customer $customer)
{
    return $query
        ->select('invoices.*')
        ->join('enrolments', 'enrolments.id', '=', 'invoices.enrolment_id')
        ->join('children', 'children.id', '=', 'enrolments.child_id')
        ->join('customers', 'customers.id', '=', 'children.customer_id')
        ->where('customers.id', $customer->id)
        ->where('children.deleted_at',NULL)
        ->where('customers.deleted_at',NULL)
        ->orderBy('invoices.ends_at', 'DESC');
}

public function scopeOfChild(Builder $query, Child $child)
{
    return $query->whereHas('enrolment', function($q) use ($child) {
        return $q->where('child_id', $child->id);
    });
}

public function scopeOverdue(Builder $query)
{
    return $query
        ->where('invoices.ends_at', '<', Carbon::now());
}

public function scopeDue(Builder $query)
{
    return $query
        ->where('invoices.ends_at', '>=', Carbon::now())
        ->where('invoices.starts_at', '<', Carbon::now())
        ;
}

public function scopeByCostCentre(Builder $query, CostCentre $cost_centre)
{
    return $query->whereHas('enrolment', function ($q) use ($cost_centre) {
        $q->where('cost_centre_id', $cost_centre->id);
    });
}

public function scopeByArea(Builder $query, Area $area)
{
    return $query->whereHas('enrolment', function ($q) use ($area) {
        $q->whereIn('cost_centre_id', collect($area->costCentres)->pluck('id'));
    });
}

public function scopeByDateCreated(Builder $query, Carbon $date_from, Carbon $date_to)
{
    return $query
        ->where('invoices.created_at', '>=', $date_from->startOfDay())
        ->where('invoices.created_at', '<=', $date_to->endOfDay());
}

public function scopeCurrent(Builder $query)
{
    return $query
        ->where('invoices.starts_at', '<=', Carbon::now())
        ->where('invoices.ends_at', '>=', Carbon::now());
}

public function scopeExceptCurrent(Builder $query)
{
    return $query
        ->where('invoices.ends_at', '<', Carbon::now());
       
}





#endregion

#region Relations
public function enrolment()
{
    return $this->belongsTo('App\Models\Enrolment');
}

public function notes()
{
    return $this->morphMany('App\Models\Note', 'notable');
}
#endregion

#region Accessors
public function getIsUnpaidAttribute()
{
    return $this->payments()->sum('value') < $this->total;
}

public function getIsDueAttribute()
{
    return $this->ends_at >= Carbon::now();
}

public function getPaidAttribute()
{
    return $this->payments()->paid()->sum('value');
}

public function payments()
{
    return $this->enrolment->child->payments();
}

public function currentPayments()
{
    return $this->enrolment->child->payments()->paid()->CurrentByInvoice($this);
}

public function currentWaived()
{
    return $this->enrolment->child->payments()->waived()->CurrentByInvoice($this);
}



public function getCurrentDueAttribute()
{
    if($this->total < $this->enrolment->child->currentpaymentsByInvoice($this)->paid()->sum('value'))
        $currentDue=0;
    else
        $currentDue = $this->total - $this->enrolment->child->currentpaymentsByInvoice($this)->paid()->sum('value');
    
    //$duepaid= $this->id.'----'.$this->total.'------'.$this->enrolment->child->id.'----'.$this->enrolment->child->currentpaymentsByInvoice($this)->paid()->sum('value').'----'.$this->starts_at.'---'.$this->ends_at.'----'.$this->enrolment->id ;
    //- $this->enrolment->child->payments()->paid()->sum('value');
    return $currentDue;
    //$this->enrolment->child->payments()->paid()->sum('value');
}

/* public function getWaivedAttribute() { return $this->payments()->waived()->sum('value'); } */ public function getWaivedAmountAttribute() { return $this->waived; }

 public function getPendingBalanceAttribute()
{
    return $this->balance;
}


public function getOutstandingAttribute()
{
    return $this->total - $this->payments()->sum('value');
}

public function getTotalSubsidiesAttribute()
{
    return collect($this->data)->sum('daily_subsidies');
}

public function getTotalDiscountsAttribute()
{
    return collect($this->data)->sum('daily_discounts');
}

public function getCurrentPaymentAttribute()
{
    return $this->currentPayments->sum('value');
}

public function getCurrentPaymentWaivedAttribute()
{
    return $this->currentWaived->sum('value');
}

public function getCurrentPaymentTotalAttribute()
{
    return $this->currentPayments->sum('value');
}


#endregion

}

kfirba
kfirba
2 months ago (211,115 XP)

@Lalit No, that's too much information. I just need to know what is the code at line 275 and in which functions it exists within

Lalit

this is the line 275

function is public function CreateInvoice(){

$data['details'][] = $details;

kfirba
kfirba
2 months ago (211,115 XP)

@Lalit In your createInvoice() method you have this line of code:

$data['details'] = '';

Which means you initialize the details key within the $data array to an empty string. Then somewhere else in that method, you try to interact with it as if it was an array:

$data['details'][] = $details;

And you get your error. The reason for the error is that what you are calling the shorthand array_push() on a string. Usually in PHP you can do:

// initialize an array
$array = [];
// push items to the array
$array[] = 'Item A';
$array[] = 'Item B';
// Now the array looks something like:
// -> ["Item A", "Item B"]

// The above code is a shorthand for:
$array = [];
array_push($array, 'Item A');
array_push($array, 'Item B');
// -> ["Item A", "Item B"]

What happens in your code that you try to use the $data['details'] value as if it was an array when it is actually a string (remember the $data['details'] = ''; line of code).

What you need to do is change this line of code:

$data['details'] = '';

To:

$data['details'] = [];

Also, it is better if you try to debug your code by yourself. You will learn a lot. Try going through the stack trace whenever you have an error. I know it looks long and intimidating but once you get used to it, it is a breeze to do so :) Also, don't forget the Google is any developer's best friend!

Please sign in or create an account to participate in this conversation.