<?php

namespace App\Models\Sales;

use App\Helpers\Helper;
use App\Models\Base\Company;
use App\Models\Catalogs\Project;
use App\Models\Base\BranchOffice;
use App\Models\Base\DocumentType;
use App\Models\Catalogs\Currency;
use App\Models\Catalogs\PaymentWay;
use App\Models\Catalogs\TaxRegimen;
use Kyslik\ColumnSortable\Sortable;
use App\Models\Catalogs\CfdiRelation;
use App\Models\Base\CompanyBankAccount;
use Illuminate\Database\Eloquent\Model;
use Hyn\Tenancy\Traits\UsesTenantConnection;

/**
 * App\Models\Sales\CustomerPayment
 *
 * @property int $id
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property int|null $created_uid
 * @property int|null $updated_uid
 * @property string $name
 * @property string|null $serie
 * @property int|null $folio
 * @property string|null $date
 * @property string|null $date_payment
 * @property string|null $reference
 * @property int|null $company_bank_account_id
 * @property int|null $customer_id
 * @property int|null $customer_bank_account_id
 * @property int|null $branch_office_id
 * @property int|null $payment_way_id
 * @property int|null $currency_id
 * @property float $currency_value
 * @property float $amount
 * @property float $balance
 * @property int|null $document_type_id
 * @property int|null $cfdi_relation_id
 * @property bool $cfdi
 * @property string|null $comment
 * @property bool $mail_sent
 * @property int $sort_order
 * @property bool $status
 * @property string|null $confirmacion
 * @property string|null $tipo_cadena_pago
 * @property string|null $certificado_pago
 * @property string|null $cadena_pago
 * @property string|null $sello_pago
 * @property int|null $company_id
 * @property string|null $draft
 * @property-read \App\Models\Base\BranchOffice|null $branchOffice
 * @property-read \App\Models\Catalogs\CfdiRelation|null $cfdiRelation
 * @property-read \App\Models\Base\Company|null $company
 * @property-read \App\Models\Base\CompanyBankAccount|null $companyBankAccount
 * @property-read \App\Models\Catalogs\Currency|null $currency
 * @property-read \App\Models\Sales\Customer|null $customer
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Sales\CustomerPaymentReconciled[] $customerActiveManualPaymentReconcileds
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Sales\CustomerPaymentReconciled[] $customerActiveNormalPaymentReconcileds
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Sales\CustomerPaymentReconciled[] $customerActivePaymentReconcileds
 * @property-read \App\Models\Sales\CustomerBankAccount|null $customerBankAccount
 * @property-read \App\Models\Sales\CustomerPaymentCfdi $customerPaymentCfdi
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Sales\CustomerPaymentReconciled[] $customerPaymentReconcileds
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Sales\CustomerPaymentRelation[] $customerPaymentRelations
 * @property-read \App\Models\Base\DocumentType|null $documentType
 * @property-read mixed $description_select2
 * @property-read mixed $text_select2
 * @property-read \App\Models\Catalogs\PaymentWay|null $paymentWay
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment filter($input = array())
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment query()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment sortable($defaultParameters = null)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment totalDashboard($input = array())
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereAmount($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereBalance($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereBranchOfficeId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCadenaPago($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCertificadoPago($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCfdi($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCfdiRelationId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereComment($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCompanyBankAccountId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCompanyId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereConfirmacion($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCreatedUid($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCurrencyId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCurrencyValue($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCustomerBankAccountId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereCustomerId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereDate($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereDatePayment($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereDocumentTypeId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereDraft($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereFolio($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereMailSent($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment wherePaymentWayId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereReference($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereSelloPago($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereSerie($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereSortOrder($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereTipoCadenaPago($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereUpdatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sales\CustomerPayment whereUpdatedUid($value)
 * @mixin \Eloquent
 * @property-read \App\Models\Catalogs\Project $project
 */
class CustomerPayment extends Model
{
    use Sortable,UsesTenantConnection;

    protected $table = 'customer_payments';

    const PATH_XML_FILES = 'files/customer_payments/xml';

    //Por timbrar
    const DRAFT = 1; //Borrador
    const OPEN = 2; //Abierto
    const RECONCILED = 3; //Conciliado
    const CANCEL = 4; //Cancelada
    const PER_RECONCILED = 5; //Por aplicar

    /**
     * Attributes that should be mass-assignable.
     *
     * @var array
     */
    protected $fillable = [
        'created_uid',
        'updated_uid',
        'name',
        'serie',
        'folio',
        'date',
        'date_payment',
        'reference',
        'company_bank_account_id',
        'customer_id',
        'customer_bank_account_id',
        'branch_office_id',
        'payment_way_id',
        'currency_id',
        'currency_value',
        'amount',
        'balance',
        'document_type_id',
        'cfdi_relation_id',
        'cfdi',
        'comment',
        'mail_sent',
        'sort_order',
        'status',
        'confirmacion',
        'tipo_cadena_pago',
        'certificado_pago',
        'cadena_pago',
        'sello_pago',
        'company_id',
        'draft',
        'project_id',
        'tax_regimen_id',
        'tax_regimen_customer_id',
    ];

    /**
     * Sortable columns.
     *
     * @var array
     */
    public $sortable = [
        'name',
        'date',
        'date_payment',
        'amount_total',
        'balance',
        'cfdi',
        'mail_sent',
        'sort_order',
        'status'
    ];

    public function scopeFilter($query, array $input = [])
    {
        $query->where(function ($query) {
            $query->where('customer_payments.company_id', '=', \App\Helpers\Helper::defaultCompany()->id);
        })->where(function($query) use ($input) {
            if (!empty($input['filter_search'])) {
                $search = $input['filter_search'];
                $query->orWhere('name', 'like', '%' . str_replace(' ', '%%', $search) . '%');
            }
            if (!empty($input['filter_document_type_code'])) {
                $filter_document_type_code = $input['filter_document_type_code'];
                $query->WhereHas('documentType', function ($q) use ($filter_document_type_code) {
                    $q->where('document_types.code', '=', $filter_document_type_code);
                });
            }
            if (!empty($input['filter_name'])) {
                $name = $input['filter_name'];
                $query->where('name', 'like', '%' . str_replace(' ', '%%', $name) . '%');
            }
            if (!empty($input['filter_date_type']) && $input['filter_date_type'] == '2') {
                if (!empty($input['filter_date_from'])) {
                    $query->whereDate('date_payment', '>=', Helper::convertDateToSql($input['filter_date_from']));
                }
                if (!empty($input['filter_date_to'])) {
                    $query->whereDate('date_payment', '<=', Helper::convertDateToSql($input['filter_date_to']));
                }
            }else{
                if (!empty($input['filter_date_from'])) {
                    $query->whereDate('date', '>=', Helper::convertDateToSql($input['filter_date_from']));
                }
                if (!empty($input['filter_date_to'])) {
                    $query->whereDate('date', '<=', Helper::convertDateToSql($input['filter_date_to']));
                }
            }
            if (!empty($input['filter_payment_way_id'])) {
                $payment_way_id = $input['filter_payment_way_id'];
                $query->where('payment_way_id', '=', $payment_way_id);
            }
            if (!empty($input['filter_customer_id'])) {
                $customer_id = $input['filter_customer_id'];
                $query->where('customer_id', '=', $customer_id);
            }
            if (!empty($input['filter_currency_id'])) {
                $currency_id = $input['filter_currency_id'];
                $query->where('currency_id', '=', $currency_id);
            }
            if (!empty($input['filter_branch_office_id'])) {
                $branch_office_id = $input['filter_branch_office_id'];
                $query->where('branch_office_id', '=', $branch_office_id);
            }
            if (!empty($input['filter_project_id'])) {
                $project_id = $input['filter_project_id'];
                $query->where('project_id', '=', $project_id);
            }
            if (!empty($input['filter_status'])) {
                $status = $input['filter_status'];
                $query->where('status', '=', $status);
            }
            if (!empty($input['filter_search_cfdi_select2'])) {
                $search = $input['filter_search_cfdi_select2'];
                //agregar los estatus y que tengan UUID para buscar
                $query->whereIn('status', [self::OPEN, self::RECONCILED, self::CANCEL, self::PER_RECONCILED])
                    ->whereHas('customerPaymentCfdi', function ($q) {
                        $q->where('customer_payment_cfdis.uuid', '<>', '');
                    })
                    ->where(function ($q) use ($search) {
                        $q->where('name', 'like', '%' . str_replace(' ', '%%', $search) . '%')
                            ->orWhereHas('customerPaymentCfdi', function ($q) use ($search) {
                                $q->where('customer_payment_cfdis.uuid', 'like',
                                    '%' . str_replace(' ', '%%', $search) . '%');
                            });
                    });
            }
        });

        return $query;
    }

    public function scopeTotalDashboard($query, array $input = []){
        $query->where(function ($query) {
            $query->where('company_id', '=', \App\Helpers\Helper::defaultCompany()->id);
        })->where(function($query) use ($input) {
            $query->whereIn('status', [self::OPEN,self::RECONCILED, self::PER_RECONCILED]);
            if (!empty($input['filter_date_from'])) {
                $query->whereDate('date', '>=', Helper::convertDateToSql($input['filter_date_from']));
            }
            if (!empty($input['filter_date_to'])) {
                $query->whereDate('date', '<=', Helper::convertDateToSql($input['filter_date_to']));
            }
            if (!empty($input['filter_document_type_code'])) {
                $filter_document_type_code = $input['filter_document_type_code'];
                $query->WhereHas('documentType', function ($q) use ($filter_document_type_code) {
                    $q->where('document_types.code', '=', $filter_document_type_code);
                });
            }
        });
        return $query;
    }

    public function getTextSelect2Attribute()
    {
        return $this->name;
    }

    public function getDescriptionSelect2Attribute()
    {
        return $this->name;
    }

    public function companyBankAccount()
    {
        return $this->belongsTo(CompanyBankAccount::class);
    }

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function customerBankAccount()
    {
        return $this->belongsTo(CustomerBankAccount::class);
    }

    public function branchOffice()
    {
        return $this->belongsTo(BranchOffice::class);
    }

    public function paymentWay()
    {
        return $this->belongsTo(PaymentWay::class);
    }

    public function currency()
    {
        return $this->belongsTo(Currency::class);
    }

    public function documentType()
    {
        return $this->belongsTo(DocumentType::class);
    }

    public function cfdiRelation()
    {
        return $this->belongsTo(CfdiRelation::class);
    }

    public function customerPaymentReconcileds()
    {
        return $this->hasMany(CustomerPaymentReconciled::class);
    }

    public function customerActivePaymentReconcileds()
    {
        return $this->hasMany(CustomerPaymentReconciled::class)->where('status','=','1');
    }

    public function customerActiveNormalPaymentReconcileds()
    {
        return $this->hasMany(CustomerPaymentReconciled::class)->where('status','=','1')->whereNotNull('reconciled_id');
    }

    public function customerActiveManualPaymentReconcileds()
    {
        return $this->hasMany(CustomerPaymentReconciled::class)->where('status','=','1')->whereNull('reconciled_id');
    }

    public function customerPaymentRelations()
    {
        return $this->hasMany(CustomerPaymentRelation::class);
    }

    public function customerPaymentCfdi()
    {
        return $this->hasOne(CustomerPaymentCfdi::class);
    }

    public function company()
    {
        return $this->belongsTo(Company::class);
    }

    public function project()
    {
        return $this->belongsTo(Project::class);
    }

    public function taxRegimen()
    {
        return $this->belongsTo(TaxRegimen::class);
    }

    public function taxRegimenCustomer()
    {
        return $this->belongsTo(TaxRegimen::class, 'tax_regimen_customer_id');
    }
}
