Merge Invoice and Bill into Document
This commit is contained in:
		
							
								
								
									
										353
									
								
								app/Models/Document/Document.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								app/Models/Document/Document.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,353 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Models\Document; | ||||
|  | ||||
| use App\Abstracts\Model; | ||||
| use App\Scopes\Document as Scope; | ||||
| use App\Models\Setting\Tax; | ||||
| use App\Traits\Currencies; | ||||
| use App\Traits\DateTime; | ||||
| use App\Traits\Documents; | ||||
| use App\Traits\Media; | ||||
| use App\Traits\Recurring; | ||||
| use Bkwld\Cloner\Cloneable; | ||||
| use Database\Factories\Document as DocumentFactory; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Eloquent\Factories\Factory; | ||||
| use Illuminate\Database\Eloquent\Factories\HasFactory; | ||||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||
| use Illuminate\Database\Eloquent\Relations\HasMany; | ||||
| use Illuminate\Database\Eloquent\Relations\MorphOne; | ||||
|  | ||||
| class Document extends Model | ||||
| { | ||||
|     use HasFactory, Documents, Cloneable, Currencies, DateTime, Media, Recurring; | ||||
|  | ||||
|     public const INVOICE_TYPE = 'invoice'; | ||||
|     public const BILL_TYPE = 'bill'; | ||||
|  | ||||
|     protected $table = 'documents'; | ||||
|  | ||||
|     protected $appends = ['attachment', 'amount_without_tax', 'discount', 'paid', 'status_label']; | ||||
|  | ||||
|     protected $dates = ['deleted_at', 'issued_at', 'due_at']; | ||||
|  | ||||
|     protected $fillable = [ | ||||
|         'company_id', | ||||
|         'type', | ||||
|         'document_number', | ||||
|         'order_number', | ||||
|         'status', | ||||
|         'issued_at', | ||||
|         'due_at', | ||||
|         'amount', | ||||
|         'currency_code', | ||||
|         'currency_rate', | ||||
|         'contact_id', | ||||
|         'contact_name', | ||||
|         'contact_email', | ||||
|         'contact_tax_number', | ||||
|         'contact_phone', | ||||
|         'contact_address', | ||||
|         'notes', | ||||
|         'category_id', | ||||
|         'parent_id', | ||||
|         'footer', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * The attributes that should be cast. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $casts = [ | ||||
|         'amount' => 'double', | ||||
|         'currency_rate' => 'double', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     public $sortable = ['document_number', 'contact_name', 'amount', 'status', 'issued_at', 'due_at']; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     public $cloneable_relations = ['items', 'recurring', 'totals']; | ||||
|  | ||||
|     /** | ||||
|      * The "booting" method of the model. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected static function boot() | ||||
|     { | ||||
|         parent::boot(); | ||||
|  | ||||
|         static::addGlobalScope(new Scope); | ||||
|     } | ||||
|  | ||||
|     public function category() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Setting\Category')->withDefault(['name' => trans('general.na')]); | ||||
|     } | ||||
|  | ||||
|     public function contact() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Common\Contact')->withDefault(['name' => trans('general.na')]); | ||||
|     } | ||||
|  | ||||
|     public function currency() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Setting\Currency', 'currency_code', 'code'); | ||||
|     } | ||||
|  | ||||
|     public function items() | ||||
|     { | ||||
|         return $this->hasMany('App\Models\Document\DocumentItem', 'document_id'); | ||||
|     } | ||||
|  | ||||
|     public function item_taxes() | ||||
|     { | ||||
|         return $this->hasMany('App\Models\Document\DocumentItemTax', 'document_id'); | ||||
|     } | ||||
|  | ||||
|     public function histories() | ||||
|     { | ||||
|         return $this->hasMany('App\Models\Document\DocumentHistory', 'document_id'); | ||||
|     } | ||||
|  | ||||
|     public function payments() | ||||
|     { | ||||
|         return $this->transactions(); | ||||
|     } | ||||
|  | ||||
|     public function recurring() | ||||
|     { | ||||
|         return $this->morphOne('App\Models\Common\Recurring', 'recurable'); | ||||
|     } | ||||
|  | ||||
|     public function totals() | ||||
|     { | ||||
|         return $this->hasMany('App\Models\Document\DocumentTotal', 'document_id'); | ||||
|     } | ||||
|  | ||||
|     public function transactions() | ||||
|     { | ||||
|         return $this->hasMany('App\Models\Banking\Transaction', 'document_id')->where('type', 'income'); | ||||
|     } | ||||
|  | ||||
|     public function totals_sorted() | ||||
|     { | ||||
|         return $this->totals()->orderBy('sort_order'); | ||||
|     } | ||||
|  | ||||
|     public function scopeLatest(Builder $query) | ||||
|     { | ||||
|         return $query->orderBy('issued_at', 'desc'); | ||||
|     } | ||||
|  | ||||
|     public function scopeNumber(Builder $query, string $number) | ||||
|     { | ||||
|         return $query->where('document_number', '=', $number); | ||||
|     } | ||||
|  | ||||
|     public function scopeDue($query, $date) | ||||
|     { | ||||
|         return $query->whereDate('due_at', '=', $date); | ||||
|     } | ||||
|  | ||||
|     public function scopeAccrued($query) | ||||
|     { | ||||
|         return $query->whereNotIn('status', ['draft', 'cancelled']); | ||||
|     } | ||||
|  | ||||
|     public function scopePaid($query) | ||||
|     { | ||||
|         return $query->where('status', '=', 'paid'); | ||||
|     } | ||||
|  | ||||
|     public function scopeNotPaid($query) | ||||
|     { | ||||
|         return $query->where('status', '<>', 'paid'); | ||||
|     } | ||||
|  | ||||
|     public function scopeType(Builder $query, string $type) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', $type); | ||||
|     } | ||||
|  | ||||
|     public function scopeInvoice(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', self::INVOICE_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function scopeBill(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', self::BILL_TYPE); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      * | ||||
|      * @param  Document $src | ||||
|      * @param  boolean $child | ||||
|      */ | ||||
|     public function onCloning($src, $child = null) | ||||
|     { | ||||
|         $this->status          = 'draft'; | ||||
|         $this->document_number = $this->getNextDocumentNumber($src->type); | ||||
|     } | ||||
|  | ||||
|     public function getSentAtAttribute(string $value = null) | ||||
|     { | ||||
|         $sent = $this->histories()->where('status', 'sent')->first(); | ||||
|  | ||||
|         return $sent->created_at ?? null; | ||||
|     } | ||||
|  | ||||
|     public function getReceivedAtAttribute(string $value = null) | ||||
|     { | ||||
|         $received = $this->histories()->where('status', 'received')->first(); | ||||
|  | ||||
|         return $received->created_at ?? null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the current balance. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getAttachmentAttribute($value = null) | ||||
|     { | ||||
|         if (!empty($value) && !$this->hasMedia('attachment')) { | ||||
|             return $value; | ||||
|         } elseif (!$this->hasMedia('attachment')) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $this->getMedia('attachment')->last(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the discount percentage. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getDiscountAttribute() | ||||
|     { | ||||
|         $percent = 0; | ||||
|  | ||||
|         $discount = $this->totals->where('code', 'discount')->makeHidden('title')->pluck('amount')->first(); | ||||
|  | ||||
|         if ($discount) { | ||||
|             $sub_total = $this->totals->where('code', 'sub_total')->makeHidden('title')->pluck('amount')->first(); | ||||
|  | ||||
|             $percent = number_format((($discount * 100) / $sub_total), 0); | ||||
|         } | ||||
|  | ||||
|         return $percent; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the paid amount. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getPaidAttribute() | ||||
|     { | ||||
|         if (empty($this->amount)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $paid = 0; | ||||
|         $reconciled = $reconciled_amount = 0; | ||||
|  | ||||
|         $code = $this->currency_code; | ||||
|         $rate = config('money.' . $code . '.rate'); | ||||
|         $precision = config('money.' . $code . '.precision'); | ||||
|  | ||||
|         if ($this->transactions->count()) { | ||||
|             foreach ($this->transactions as $item) { | ||||
|                 $amount = $item->amount; | ||||
|  | ||||
|                 if ($code != $item->currency_code) { | ||||
|                     $amount = $this->convertBetween($amount, $item->currency_code, $item->currency_rate, $code, $rate); | ||||
|                 } | ||||
|  | ||||
|                 $paid += $amount; | ||||
|  | ||||
|                 if ($item->reconciled) { | ||||
|                     $reconciled_amount = +$amount; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (bccomp(round($this->amount, $precision), round($reconciled_amount, $precision), $precision) === 0) { | ||||
|             $reconciled = 1; | ||||
|         } | ||||
|  | ||||
|         $this->setAttribute('reconciled', $reconciled); | ||||
|  | ||||
|         return round($paid, $precision); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the status label. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getStatusLabelAttribute() | ||||
|     { | ||||
|         switch ($this->status) { | ||||
|             case 'paid': | ||||
|                 $label = 'success'; | ||||
|                 break; | ||||
|             case 'partial': | ||||
|                 $label = 'info'; | ||||
|                 break; | ||||
|             case 'sent': | ||||
|             case 'received': | ||||
|                 $label = 'danger'; | ||||
|                 break; | ||||
|             case 'viewed': | ||||
|                 $label = 'warning'; | ||||
|                 break; | ||||
|             case 'cancelled': | ||||
|                 $label = 'dark'; | ||||
|                 break; | ||||
|             default: | ||||
|                 $label = 'primary'; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $label; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the amount without tax. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getAmountWithoutTaxAttribute() | ||||
|     { | ||||
|         $amount = $this->amount; | ||||
|  | ||||
|         $this->totals->where('code', 'tax')->each(function ($total) use(&$amount) { | ||||
|             $tax = Tax::name($total->name)->first(); | ||||
|  | ||||
|             if (!empty($tax) && ($tax->type == 'withholding')) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $amount -= $total->amount; | ||||
|         }); | ||||
|  | ||||
|         return $amount; | ||||
|     } | ||||
|  | ||||
|     protected static function newFactory(): Factory | ||||
|     { | ||||
|         return DocumentFactory::new(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								app/Models/Document/DocumentHistory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Models/Document/DocumentHistory.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Models\Document; | ||||
|  | ||||
| use App\Abstracts\Model; | ||||
| use App\Traits\Currencies; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||
|  | ||||
| class DocumentHistory extends Model | ||||
| { | ||||
|     use Currencies; | ||||
|  | ||||
|     protected $table = 'document_histories'; | ||||
|  | ||||
|     protected $fillable = ['company_id', 'type', 'document_id', 'status', 'notify', 'description']; | ||||
|  | ||||
|     public function document() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Document\Document'); | ||||
|     } | ||||
|  | ||||
|     public function scopeType(Builder $query, string $type) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', $type); | ||||
|     } | ||||
|  | ||||
|     public function scopeInvoice(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::INVOICE_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function scopeBill(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::BILL_TYPE); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										140
									
								
								app/Models/Document/DocumentItem.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								app/Models/Document/DocumentItem.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Models\Document; | ||||
|  | ||||
| use App\Abstracts\Model; | ||||
| use App\Traits\Currencies; | ||||
| use Bkwld\Cloner\Cloneable; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||
| use Illuminate\Database\Eloquent\Relations\HasMany; | ||||
|  | ||||
| class DocumentItem extends Model | ||||
| { | ||||
|     use Cloneable, Currencies; | ||||
|  | ||||
|     protected $table = 'document_items'; | ||||
|  | ||||
|     protected $appends = ['discount']; | ||||
|  | ||||
|     protected $fillable = [ | ||||
|         'company_id', | ||||
|         'type', | ||||
|         'document_id', | ||||
|         'item_id', | ||||
|         'name', | ||||
|         'description', | ||||
|         'quantity', | ||||
|         'price', | ||||
|         'total', | ||||
|         'tax', | ||||
|         'discount_rate', | ||||
|         'discount_type', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * The attributes that should be cast. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $casts = [ | ||||
|         'price' => 'double', | ||||
|         'total' => 'double', | ||||
|         'tax' => 'double', | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     public $cloneable_relations = ['taxes']; | ||||
|  | ||||
|     public static function boot() | ||||
|     { | ||||
|         parent::boot(); | ||||
|  | ||||
|         static::retrieved( | ||||
|             function ($model) { | ||||
|                 $model->setTaxIds(); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     public function document() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Document\Document'); | ||||
|     } | ||||
|  | ||||
|     public function item() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Common\Item')->withDefault(['name' => trans('general.na')]); | ||||
|     } | ||||
|  | ||||
|     public function taxes() | ||||
|     { | ||||
|         return $this->hasMany('App\Models\Document\DocumentItemTax', 'document_item_id', 'id'); | ||||
|     } | ||||
|  | ||||
|     public function scopeType(Builder $query, string $type) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', $type); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function scopeInvoice(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::INVOICE_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function scopeBill(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::BILL_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function getDiscountAttribute(): string | ||||
|     { | ||||
|         if (setting('localisation.percent_position', 'after') === 'after') { | ||||
|             $text = ($this->discount_type === 'normal') ? $this->discount_rate . '%' : $this->discount_rate; | ||||
|         } else { | ||||
|             $text = ($this->discount_type === 'normal') ? '%' . $this->discount_rate : $this->discount_rate; | ||||
|         } | ||||
|  | ||||
|         return $text; | ||||
|     } | ||||
|  | ||||
|     public function getDiscountRateAttribute(int $value = 0) | ||||
|     { | ||||
|         $discount_rate = 0; | ||||
|  | ||||
|         switch (setting('localisation.discount_location', 'total')) { | ||||
|             case 'no': | ||||
|             case 'total': | ||||
|                 $discount_rate = 0; | ||||
|                 break; | ||||
|             case 'both': | ||||
|             case 'item': | ||||
|                 $discount_rate = $value; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $discount_rate; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Convert tax to Array. | ||||
|      */ | ||||
|     public function setTaxIds() | ||||
|     { | ||||
|         $tax_ids = []; | ||||
|  | ||||
|         foreach ($this->taxes as $tax) { | ||||
|             $tax_ids[] = (string)$tax->tax_id; | ||||
|         } | ||||
|  | ||||
|         $this->setAttribute('tax_ids', $tax_ids); | ||||
|     } | ||||
|  | ||||
|     public function onCloning($src, $child = null) | ||||
|     { | ||||
|         unset($this->tax_ids); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										58
									
								
								app/Models/Document/DocumentItemTax.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								app/Models/Document/DocumentItemTax.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Models\Document; | ||||
|  | ||||
| use App\Abstracts\Model; | ||||
| use App\Traits\Currencies; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||
| use Znck\Eloquent\Relations\BelongsToThrough as BelongsToThroughRelation; | ||||
| use Znck\Eloquent\Traits\BelongsToThrough; | ||||
|  | ||||
| class DocumentItemTax extends Model | ||||
| { | ||||
|     use Currencies, BelongsToThrough; | ||||
|  | ||||
|     protected $table = 'document_item_taxes'; | ||||
|  | ||||
|     protected $fillable = ['company_id', 'type', 'document_id', 'document_item_id', 'tax_id', 'name', 'amount']; | ||||
|  | ||||
|     /** | ||||
|      * The attributes that should be cast. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $casts = [ | ||||
|         'amount' => 'double', | ||||
|     ]; | ||||
|  | ||||
|     public function document() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Document\Document'); | ||||
|     } | ||||
|  | ||||
|     public function item() | ||||
|     { | ||||
|         return $this->belongsToThrough('App\Models\Common\Item', 'App\Models\Document\DocumentItem', 'document_item_id')->withDefault(['name' => trans('general.na')]); | ||||
|     } | ||||
|  | ||||
|     public function tax() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Setting\Tax')->withDefault(['name' => trans('general.na'), 'rate' => 0]); | ||||
|     } | ||||
|  | ||||
|     public function scopeType(Builder $query, string $type) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', $type); | ||||
|     } | ||||
|  | ||||
|     public function scopeInvoice(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::INVOICE_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function scopeBill(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::BILL_TYPE); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										93
									
								
								app/Models/Document/DocumentTotal.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								app/Models/Document/DocumentTotal.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\Models\Document; | ||||
|  | ||||
| use App\Abstracts\Model; | ||||
| use App\Models\Setting\Tax; | ||||
| use App\Traits\DateTime; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Eloquent\Relations\BelongsTo; | ||||
|  | ||||
| class DocumentTotal extends Model | ||||
| { | ||||
|     use DateTime; | ||||
|  | ||||
|     protected $table = 'document_totals'; | ||||
|  | ||||
|     protected $appends = ['title']; | ||||
|  | ||||
|     protected $fillable = ['company_id', 'type', 'document_id', 'code', 'name', 'amount', 'sort_order']; | ||||
|  | ||||
|     /** | ||||
|      * The attributes that should be cast. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $casts = [ | ||||
|         'amount' => 'double', | ||||
|     ]; | ||||
|  | ||||
|     public function document() | ||||
|     { | ||||
|         return $this->belongsTo('App\Models\Document\Document'); | ||||
|     } | ||||
|  | ||||
|     public function getTitleAttribute() | ||||
|     { | ||||
|         $title = $this->name; | ||||
|  | ||||
|         $percent = 0; | ||||
|  | ||||
|         $tax = null; | ||||
|  | ||||
|         switch ($this->code) { | ||||
|             case 'discount': | ||||
|                 $title = trans($title); | ||||
|                 $percent = $this->document->discount; | ||||
|  | ||||
|                 break; | ||||
|             case 'tax': | ||||
|                 $tax = Tax::where('name', $title)->first(); | ||||
|  | ||||
|                 if (!empty($tax->rate)) { | ||||
|                     $percent = $tax->rate; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         if (!empty($percent)) { | ||||
|             $title .= ' ('; | ||||
|  | ||||
|             if (setting('localisation.percent_position', 'after') === 'after') { | ||||
|                 $title .= ($this->code === 'discount') ? $percent . '%' : (($tax->type === 'fixed') ? $percent : $percent . '%'); | ||||
|             } else { | ||||
|                 $title .= ($this->code === 'discount') ? '%' . $percent : (($tax->type === 'fixed') ? $percent : '%' . $percent); | ||||
|             } | ||||
|  | ||||
|             $title .= ')'; | ||||
|         } | ||||
|  | ||||
|         return $title; | ||||
|     } | ||||
|  | ||||
|     public function scopeType(Builder $query, string $type) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', $type); | ||||
|     } | ||||
|  | ||||
|     public function scopeInvoice(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::INVOICE_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function scopeBill(Builder $query) | ||||
|     { | ||||
|         return $query->where($this->table . '.type', '=', Document::BILL_TYPE); | ||||
|     } | ||||
|  | ||||
|     public function scopeCode($query, $code) | ||||
|     { | ||||
|         return $query->where('code', '=', $code); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user