✏️ 正在编辑: Lead.php
路径:
/srv/systems_dir/oakberry/application/models/Lead.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php class Model_Lead extends Core_Model { public function getEmpresa() { $leadEmpresa = Model_Container::getLeadEmpresa()->findByLeadId($this->id, Yuppie_Auth::getIdentity()->empresa_id); return $leadEmpresa->getEmpresa(); } public function setCelular($celular) { return $this->setFilterDigits('celular', $celular); } public function setNome($nome) { $this->setAttribute('nome', ucwords(strtolower(trim($nome)))); } public function setCpf($cpf) { if (!empty($cpf)) { $this->setAttribute('cpf', String_Refatorar::formatarCpf($cpf)); } } public function getTicketMedio() { $empresa = Model_Container::getEmpresa()->findById(Yuppie_Auth::getIdentity()->empresa_id); $dtInicial = Zend_Date::now()->subDay($empresa->dias_ticket_medio ?: 0)->get('yyyy-MM-dd'); $dtFinal = Zend_Date::now()->get('yyyy-MM-dd'); $pedidos = Model_Container::getPedido()->getQtdAndTm($this->id, $empresa->id, $dtInicial, $dtFinal); if ($pedidos->count() == 0) { return 0; } $pedidos = current($pedidos); if (!$pedidos) { return 0; } return round(($pedidos->valor_total/$pedidos->qtd), 2); } public function getMonetario() { $empresa = Model_Container::getEmpresa()->findById(Yuppie_Auth::getIdentity()->empresa_id); $tm = $this->getTicketMedio(); $monetario = 0; if ($tm <= $empresa->ticket_medio) { $monetario = 1; } elseif ($tm <= ($empresa->ticket_medio * 2)) { $monetario = 2; } elseif ($tm <= ($empresa->ticket_medio * 3)) { $monetario = 3; } elseif ($tm <= ($empresa->ticket_medio * 4)) { $monetario = 4; } elseif ($tm > ($empresa->ticket_medio * 4)) { $monetario = 5; } return $monetario; } /** * Nota calculada pelo número de dias desde o último pedido * Quanto mais recente, maior a nota */ public function getRecencia() : int { $empresa = Model_Container::getEmpresa()->findById(Yuppie_Auth::getIdentity()->empresa_id); $ultimoPedido = Model_Container::getPedido()->getLastOrderByLead($this->id, $empresa->id); if (!$ultimoPedido) { return 0; } $dataUltimoPedido = new Zend_Date($ultimoPedido['data_pedido'], 'yyyy-MM-dd'); $diff = Zend_Date::now()->sub($dataUltimoPedido)->toValue(); $dias = ceil($diff/60/60/24); $recencia = 0; if ($dias <= $empresa->dias_recencia) { $recencia = 5; } elseif ($dias < ($empresa->dias_recencia * 2)) { $recencia = 4; } elseif ($dias < ($empresa->dias_recencia * 3)) { $recencia = 3; } elseif ($dias < ($empresa->dias_recencia * 4)) { $recencia = 2; } elseif ($dias < ($empresa->dias_recencia * 5)) { $recencia = 1; } return $recencia; } /** * Frequência do cliente calculada em quartis * Quanto mais frequente, maior a nota */ public function getFrequencia() : int { $empresa = Model_Container::getEmpresa()->findById(Yuppie_Auth::getIdentity()->empresa_id); $dtInicial = Zend_Date::now()->subDay($empresa->dias_frequencia ?: 0)->get('yyyy-MM-dd'); $dtFinal = Zend_Date::now()->get('yyyy-MM-dd'); $pedidos = Model_Container::getPedido()->findByInterval($this->id, $dtInicial, $dtFinal, false, false); $qtdPedidos = $pedidos->count(); $frequencia = 0; if ($qtdPedidos == 0) { return $frequencia; } $calculo = $qtdPedidos*$empresa->dias_frequencia/100; if ($calculo > 0.20 && $calculo <= 0.40) { $frequencia = 1; } elseif ($calculo <= 0.60) { $frequencia = 2; } elseif ($calculo <= 0.80) { $frequencia = 3; } elseif ($calculo <= 1) { $frequencia = 4; } elseif ($calculo >= 1) { $frequencia = 5; } return $frequencia; } public function getPrimeiroNome() { $pedacosNome = explode(" ", trim($this->nome)); $primeiroNome = $this->nome; foreach ($pedacosNome as $nome) { if (!empty($nome)) { $primeiroNome = ucfirst(strtolower($nome)); break; } } return $primeiroNome; } public function setDdi($ddi) { if (stristr($ddi, "|")) { $separa = explode("|", $ddi); $ddi = trim($separa[0]); } $this->setAttribute('ddi', $ddi); } public function save() { if (!(new Core_Service_Sms())->isValidPhone($this->_data['celular'])) { throw new Core_Exception("Telefone inválido! Informe um celular válido para receber seu cupom."); } if (empty($this->_data['empresa_id'])) { $this->setAttribute("empresa_id", Yuppie_Auth::getIdentity() ? Yuppie_Auth::getIdentity()->empresa_id : 1); } /** * @todo e seu eu quiser alterar o grupo de um cliente? * Perguntar, antes, qual o grupo do cliente */ if (empty($this->_data['id']) && ($existWa = $this->getDbTable()->existeCelular($this->_data['celular'], $this->_data['ddi'])) != null) { return $existWa; } if (empty($this->_data['id']) && !empty($this->_data['cpf']) && ($existCpf = $this->getDbTable()->findByCpf($this->_data['cpf'], $this->_data['cpf'])) != null) { return $existCpf; } return parent::save(); } public function notificaBoasVindas(int $id, ?int $empresaId = 1) { if (empty($id)) { return; } if (empty($empresaId)) { $empresaId = Yuppie_Auth::getIdentity() ? Yuppie_Auth::getIdentity()->empresa_id : 1; } $lead = $this->getDbTable()->findById($id); $empresa = (new Model_DbTable_Empresa())->findById($empresaId); $leadCupom = null; $grupoId = (int)Model_Container::getLeadEmpresa()->findByLeadId($lead->id, $empresa->id)->grupo_id; $grupoLead = Model_Container::getGrupoLead()->findById($grupoId); if (!empty($empresa->cupom_cadastro_inicial)) { $cupom = Model_Container::getCupom()->findById($empresa->cupom_cadastro_inicial); $prefixo = $empresa->prefixo_cupom ?: ""; $leadCupom = (new Model_DbTable_LeadCupom())->createRow(); $cupomGerado = $cupom->gerarCupomInicial($id, $lead->celular, $prefixo); $leadCupom->setFromArray([ 'lead_id' => $lead->id, 'empresa_id' => $empresa->id, 'cupom' => $cupomGerado, 'descricao' => $cupom->descricao ]); $leadCupom->save(); } try { $whatsapp = \Yuppie_Service_Whatsapp_Factory::load($empresa); } catch (\Throwable $e) { $whatsapp = null; Yuppie_Log::write($e->getMessage() . $e->getTraceAsString(), $this); } if ($whatsapp) { $mensagem = $this->_prepareMensagem("whatsapp", $lead, $empresa, $leadCupom, $grupoLead); $celular = !empty($lead->ddi) ? $lead->ddi . $lead->celular : '55' . $lead->celular; $whatsapp->sendMessage($celular, $mensagem); } else { $sms = new Core_Service_Sms(); $mensagem = $this->_prepareMensagem("sms", $lead, $empresa, $leadCupom, $grupoLead); $sms->sendMessage($lead->celular, $mensagem); } return $cupomGerado; } protected function _prepareMensagem($tipo = "whatsapp", Model_Lead $lead, Model_Empresa $empresa, ?Model_LeadCupom $cupom = null, ?Model_GrupoLead $grupoLead = null) { $modelMensagem = Model_Container::getMensagem()->findById($empresa->mensagem_boas_vindas); if ($tipo == "whatsapp") { $modelMensagem->prepareToSend($lead); $mensagem = $modelMensagem->texto; if ($cupom) { $mensagem .= "\n\n *TEMOS UM CUPOM PRA VC:* _" . $cupom->cupom . "_ (" . $cupom->descricao . ")\n\n"; } if ($grupoLead && $grupoLead->notificar_beneficios) { $mensagem .= "*Por fazer parte do grupo :* _" . $grupoLead->descricao . "_ você tem o(s) seguinte(s) benefício(s):\n" . $grupoLead->beneficios; } } return $mensagem; } public function reEnviarCupom(int $leadCumpomId) { /** * @todo Puxar a mensagem personalizada do cadastro da empresa ou de uma área de configurações */ $cupom = Model_Container::getLeadCupom()->findById($leadCumpomId); $lead = $cupom->getLead(); $empresa = Model_Container::getEmpresa()->findById(Yuppie_Auth::getIdentity()->empresa_id); $mensagem = "Oiii! Tudo bem?!\n\n" . "Passando só pra lembrar que você ainda não usou o seu cupom aqui na *{$empresa->nome}!* 😃\n\n" . "Vá até a nossa loja e informe o *CUPOM:* _" . $cupom->cupom . "_ (" . $cupom->descricao . ")\n\n" . "Ah! E não esquece de salvar o nosso número aí na sua agenda! 😉\n\n" . "_" . $empresa->nome . "*_"; try { $whatsapp = \Yuppie_Service_Whatsapp_Factory::load($empresa); } catch (\Throwable $e) { $whatsapp = null; Yuppie_Log::write($e->getMessage() . $e->getTraceAsString(), $this); } if ($whatsapp) { return $whatsapp->sendMessage($lead->ddi . $lead->celular, $mensagem); } return false; } /** * Retorna a quantidade de pedidos válidos */ public function getQtdPedidosRestantes() { $empresa = $this->getEmpresa(); $diasResgate = (int) ($empresa->fidelidade_intervalo+$empresa->fidelidade_tolerancia_resgate); $date1 = $diasResgate == 0 ? Zend_Date::now()->setYear(2000)->get('yyyy-MM-dd') : Zend_Date::now()->subDay($diasResgate)->get('yyyy-MM-dd'); $date2 = Zend_Date::now()->get('yyyy-MM-dd'); $qtdPedidos = Model_Container::getPedido()->findByInterval($this->id, $date1, $date2, true)->count(); if (!$qtdPedidos) { return 0; } // $resgatePeriodo = Model_Container::getResgate()->findByInterval($this->id, $date1, $date2); // $pedidosRestantes = $qtdPedidos - ($resgatePeriodo*$empresa->fidelidade_pedidos); // if ($pedidosRestantes > $empresa->fidelidade_pedidos) { // return $empresa->fidelidade_pedidos; // } return $qtdPedidos; } public function getBolinhas() { $pedidos = $this->getQtdPedidosRestantes(); $pedidosEmpresa = $this->getEmpresa()->fidelidade_pedidos; $bolinhas = ""; if ($pedidos <= 0) { return $bolinhas; } for ($i=1; $i <= $pedidos; $i++) { if (($i%$pedidosEmpresa) == 0) { $bolinhas .= "🟡\n\n"; } else { $bolinhas .= "🔵 "; } } return $bolinhas; } public function getQtdResgatesPermitidos() { $empresa = $this->getEmpresa(); $diasResgate = (int) ($empresa->fidelidade_intervalo+$empresa->fidelidade_tolerancia_resgate); $date1 = $diasResgate == 0 ? Zend_Date::now()->setYear(2000)->get('yyyy-MM-dd') : Zend_Date::now()->subDay($diasResgate)->get('yyyy-MM-dd'); $date2 = Zend_Date::now()->get('yyyy-MM-dd'); $resgatePeriodo = $this->findByInterval($this->id, $date1, $date2); $maxResgate = intdiv($this->getQtdPedidos(), $empresa->fidelidade_pedidos); return abs($maxResgate-$resgatePeriodo); } public function getScore() { $score = Core_Combos::getListScore(); return "<span class='label score-$this->score'>" . $score[$this->score] . "</span>"; } public function lancarScore(Model_Lead $lead, Model_Empresa $empresa) { $leadEmpresa = Model_Container::getLeadEmpresa()->findByLeadId($lead->id, $empresa->id); if ((new DateTime('now'))->diff(new DateTime($leadEmpresa->data_cadastro))->days <= 30) { return 'novo'; } $pedido = Model_Container::getPedido()->getLastOrderByLead($lead->id, $empresa->id); $scoreAtual = $leadEmpresa->score; $scoreNovo = 'sem pedido'; //se estava como perdido e o último pedido tem no máximo 1 dia, considera como recuperado if ($scoreAtual == 'perdido' && $pedido && (new DateTime('now'))->diff(new DateTime($pedido['data_pedido']))->days <= $empresa->dias_score_habitual ) { return 'recuperado'; } if (empty($pedido)) { return $scoreNovo; } $this->checkHabitual($empresa, $lead, $pedido, $scoreNovo); $this->checkFiel($empresa, $lead, $scoreNovo); $this->checkVip($empresa, $lead, $scoreNovo); $this->checkEmRisco($empresa, $lead, $pedido, $scoreNovo); $this->checkPerdido($empresa, $lead, $pedido, $scoreNovo); return $scoreNovo ? $scoreNovo : $scoreAtual; } public function checkHabitual($empresa, $lead, $pedido, &$scoreNovo) { $lastOrders = Model_Container::getPedido()->fetchAll("lead_id = {$lead->id} AND empresa_id = {$empresa->id}", "id DESC", 10); if ($lastOrders->count() < 10) { $scoreNovo = 'esporadico'; return; } $leadEmpresa = Model_Container::getLeadEmpresa()->findByLeadId($lead->id, $empresa->id); $dateLastOrder = new DateTime($lastOrders[0]->data_cadastro); $datePrevLastOrder = new DateTime($lastOrders[1]->data_cadastro); if ($leadEmpresa->score == 'recuperado' && $dateLastOrder->diff($datePrevLastOrder)->days > $empresa->dias_score_habitual) { $scoreNovo = 'recuperado'; return; } $diff = (new DateTime('now'))->diff(new DateTime($pedido['data_pedido'])); $diasUltimoPedido = $diff->days; if ($diasUltimoPedido <= $empresa->dias_score_habitual) { $scoreNovo = 'habitual'; } else { $scoreNovo = 'esporadico'; } } public function checkFiel($empresa, $lead, &$scoreNovo) { $leadEmpresa = Model_Container::getLeadEmpresa()->findByLeadId($lead->id, $empresa->id); $daysCreated = (new DateTime('now'))->diff(new DateTime($leadEmpresa->data_cadastro))->days; //só pode ser fiel se tiver mais de 30 dias de cadastro if ($daysCreated < 30) { return; } $lastOrders = Model_Container::getPedido()->fetchAll("lead_id = {$lead->id} AND empresa_id = {$empresa->id}", "id DESC", 10); //se não tiver 10 pedidos não faz a verificação, talvez seja um habitual if ($lastOrders->count() < 10) { return; } $fiel = false; $prev = null; //precisa manter uma frequencia dentro dos 10 pedidos com um intervalo máximo de $empresa->dias_score_fiel foreach ($lastOrders as $key => $p) { if ($key == 0) { $diff = (new DateTime('now'))->diff(new DateTime($p->data_cadastro)); } elseif ($key > 0 && $prev) { $diff = (new DateTime($prev->data_cadastro))->diff(new DateTime($p->data_cadastro)); } if ($diff) { $fiel = $diff <= $empresa->dias_score_fiel ? true : false; } $prev = $p; $diff = null; } if ($fiel) { $scoreNovo = 'fiel'; } } public function checkVip($empresa, $lead, &$scoreNovo) { $leadEmpresa = Model_Container::getLeadEmpresa()->findByLeadId($lead->id, $empresa->id); $list = ['fiel', 'vip']; if (!in_array($leadEmpresa->score, $list) || $scoreNovo != 'fiel') { return; } $date1 = Zend_Date::now()->subDay($empresa->score_vip_periodo)->get('yyyy-MM-dd'); $date2 = Zend_Date::now()->get('yyyy-MM-dd'); $pedidos = Model_Container::getPedido()->getQtdAndTm($lead->id, $empresa->id, $date1, $date2); if ($pedidos->count() == 0) { return; } $pedidos = current($pedidos); if (empty($pedidos->qtd)) { return; } $ticketMedio = round($pedidos->valor_total/$pedidos->qtd, 2); if ($pedidos->qtd >= $empresa->score_vip_frequencia && $ticketMedio >= $empresa->score_vip_ticket_medio) { $scoreNovo = 'vip'; } } public function checkEmRisco($empresa, $lead, $pedido, &$scoreNovo) { $dataEmRisco = Zend_Date::now()->subDay($empresa->dias_score_risco)->get('yyyy-MM-dd'); if ($pedido['data_pedido'] < $dataEmRisco) { $scoreNovo = 'risco'; } } public function checkPerdido($empresa, $lead, $pedido, &$scoreNovo) { $dataPerdido = Zend_Date::now()->subDay($empresa->dias_score_perdido)->get('yyyy-MM-dd'); if ($pedido['data_pedido'] < $dataPerdido) { $scoreNovo = 'perdido'; } } public static function checkScoreLeads(Model_Empresa $empresa) { $leads = Model_Container::getLead()->fetchAll('empresa_id = ' . $empresa->id); foreach ($leads as $lead) { $score = $lead->lancarScore($lead, $empresa); if (!empty($score)) { Model_Container::getLeadEmpresa()->update([ 'score' => $score, 'data_score' => (new Zend_Date())->now()->get('yyyy-MM-dd HH:mm:ss') ], 'lead_id = ' . $lead->id . " AND empresa_id = " . $empresa->id . " AND score <> '{$score}'"); } } } }
💾 保存文件
← 返回文件管理器