/** * Пересчитывает даты начала и окончания закрепления по операции * @param type $operation * @param type $uid * @return type */ private function recalcBindDates($operation, $uid) { //Получаем коды операций, которые могли быть применены по данному закреплению $op_codes_allow = array(); foreach ($this->op_code_groups as $group) { $op_codes_in_group = billing::extendOpCodes($group); if (in_array($operation['op_code'], $op_codes_in_group)) { $op_codes_allow = $op_codes_in_group; } } //Получаем информацию об остальных платежах по данному закреплению $sql2 = "SELECT bq.op_code, bq.op_count, br.complete_time::timestamp as date\n FROM bill_queue bq\n INNER JOIN bill_reserve br ON bq.reserve_id = br.id\n INNER JOIN account_operations ao ON br.ammount = -(ao.ammount) \n AND br.complete_time::timestamp = ao.op_date::timestamp\n AND ao.billing_id = (SELECT id FROM account WHERE uid = ?i)\n WHERE bq.uid = ?i AND bq.service IN ('frlbind', 'frlbindup')\n AND bq.src_id = ?i AND bq.op_code IN (?l)\n AND bq.status = 'complete' AND bq.id != ?i\n ORDER BY br.complete_time ASC;"; $operations = $this->db->rows($sql2, $uid, $uid, $operation['src_id'], $op_codes_allow, $operation['id']); foreach ($operations as $operation) { //Устанавливаем даты начала при любой операции $date_start = DateTime::createFromFormat("Y-m-d H:i:s.u", $operation['date']); $operation['op_code'] = billing::getOpCodeByDiscount($operation['op_code']); if (in_array($operation['op_code'], array(self::OP_CODE_CATALOG, self::OP_CODE_PROFGROUP, self::OP_CODE_PROF)) || !isset($date_stop)) { //Если покупка, то дату окончания считаем от даты покупки $date_stop = clone $date_start; $date_stop->add(new DateInterval('P' . $operation['op_count'] * 7 . 'D')); } else { //Если продление - продляем дату окончания if (in_array($operation['op_code'], array(self::OP_CODE_PROLONG_CATALOG, self::OP_CODE_PROLONG_PROFGROUP, self::OP_CODE_PROLONG_PROF))) { $date_stop->add(new DateInterval('P' . $operation['op_count'] * 7 . 'D')); } } } if (!isset($date_start)) { $date_start = new DateTime('NOW'); } if (!isset($date_stop)) { $date_stop = clone $date_start; } return array('start' => $date_start->format('Y-m-d H:i:s'), 'stop' => $date_stop->format('Y-m-d H:i:s')); }
/** * Получить наименование операции для вывода в таблице истории * * @param integer $bill_id идентификатор операции * @param integer $uid ID Пользователя * @return string текстовое описание операции */ public static function GetHistoryText(&$val) { require_once $_SERVER['DOCUMENT_ROOT'] . "/classes/billing.php"; //Входной опкод может быть для скидки поэтому пробуем получить его оригинал услуги $original_op_code = $val['op_code']; $val['op_code'] = billing::getOpCodeByDiscount($val['op_code']); $html = $val['op_name']; if ($val['op_code'] == billing::RESERVE_OP_CODE) { $html .= '    <a class="b-layout__link b-layout__link_fontsize_11 b-layout__link_bordbot_dot_80 b-layout__link_inline-block b-layout__link_lineheight_1" href="javascript:void(0);" onclick="xajax_ShowReserveOrders(' . $val['id'] . ');">подробнее</a>'; } if ($val['op_code'] == 16) { $html .= '(EMP)'; } if ($val['op_code'] == 52) { $html .= '(FL)'; } if ($val['op_code'] < 7 || in_array($val['op_code'], array(8, 11, 15, 16, 17, 18, 23, 24, 25, 33, 52, 63, 64, 66, 67, 68, 12, 38, 45, 47, 114, 131, 132, 48, 49, 50, 51, 69, 76, 80, 84, 83, 85, 118, 119, 120, 163, 164))) { $html .= '    <a class="b-layout__link b-layout__link_fontsize_11 b-layout__link_bordbot_dot_80 b-layout__link_inline-block b-layout__link_lineheight_1" href="javascript:void(0);" onclick="xajax_ShowBillComms(' . $val['id'] . ', 0, 1);">подробнее</a>'; } /** * Платные опции проектов * @TODO Конструкция монструозная, конечно. Хотя делает простую вещь. Вынести в метод? * @todo Почему она вообще здесь и отрабатывает на каждую итерацию? * @todo Зачем вообще нужен этот метод? */ if (in_array($val['op_code'], array(9, 53, 86, 106, 138, 139, 140, 141, 113, 192))) { //Если нет ИД проекта, парсим его из строки //Старые операции - с пробелом после № if (!$val['project_id']) { preg_match('~№ (\\d+)~', $val['comments'], $match); $val['project_id'] = $match[1]; } //Не нашли, тогда новые - без пробела if (!$val['project_id']) { preg_match('~№(\\d+)~', $val['comments'], $match); $val['project_id'] = $match[1]; } $parts = explode(' & ', $val['comments']); if (count($parts) == 2) { $words = explode(' ', $parts[0]); $projectNumber = false; foreach ($words as $key => &$word) { if (strpos($word, '№') === false) { continue; } $projectNumber = $key; //Номер мог не записался в операцию, если покупка была при создании if ($word == '№') { $word .= $val['project_id']; } } $html = ''; $words[$projectNumber - 1] = '<a class="b-layout__link" href="/projects/' . $val['project_id'] . '">' . $words[$projectNumber - 1]; $words[$projectNumber] .= '</a>'; $html = implode(' ', $words); $val['comments'] = $parts[1]; } else { $html = '<a class="b-layout__link" href="/projects/' . $val['project_id'] . '">' . $val['op_name'] . '</a>'; } } //Платные места в каталоге if (in_array($val['op_code'], array(142, 143, 144))) { $html = $val['descr']; } //Поднятие платного места if (in_array($val['op_code'], array(10, 20, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162))) { $html = $val['descr']; } //Поднятие платного места if (in_array($val['op_code'], array(10, 19, 20))) { if ($val['descr']) { $html = $val['descr']; } else { //У старых платежей описание не заполнено $html = $val['op_name'] . '    <a class="b-layout__link b-layout__link_fontsize_11 b-layout__link_bordbot_dot_80 b-layout__link_inline-block b-layout__link_lineheight_1" href="javascript:void(0);" onclick="xajax_ShowBillComms(' . $val['id'] . ', 0, 1);">подробнее</a>'; } } //Услуга по скидке, пока у нас только для PROFI //поэтому дописываем пометку if ($original_op_code != $val['op_code'] && !in_array($original_op_code, array(165, 166))) { $html .= ' (для profi)'; } return $html; }
/** Удаление закрепления по id в account_operations * @see account::DelByOpid() * * @param intr $uid uid пользователя * @param int $opid id операции в биллинге * * @return int */ public function DelByOpid($uid, $opid) { $sql = 'SELECT bq.id, bq.op_count, bq.option, bq.service, bq.src_id, ao.op_code FROM account_operations ao INNER JOIN bill_reserve br ON br.uid = ?i AND br.ammount = -(ao.ammount) AND br.complete_time::timestamp = ao.op_date::timestamp INNER JOIN bill_queue bq ON bq.reserve_id = br.id AND bq.op_code = ao.op_code WHERE ao.id = ?i AND ao.billing_id = (SELECT id FROM account WHERE uid = ?i);'; $operation = $this->db()->row($sql, $uid, $opid, $uid); if (!$operation) { return 0; } $is_up = $operation['service'] == 'tservicebindup'; if ($is_up) { $origOpCode = billing::getOpCodeByDiscount($operation['op_code']); $this->kind = array_search($origOpCode, $this->op_codes_up); $bindInfo = $this->getItemById($operation['src_id']); } else { $origOpCode = billing::getOpCodeByDiscount($operation['op_code']); $this->kind = array_search($origOpCode, $this->op_codes); $options = mb_unserialize($operation['option']); $is_prolong = isset($options['is_prolong']) && $options['is_prolong'] == 1; if ($is_prolong) { $bindInfo = $this->getItem($uid, (int) $options['tservice_id'], $operation['src_id']); } else { $this->db()->query("DELETE FROM {$this->TABLE} WHERE user_id = ?i AND tservice_id = ?i AND kind = ? AND prof_id = ?i", $uid, (int) $options['tservice_id'], $this->kind, $operation['src_id']); } } if (isset($bindInfo['id']) && $bindInfo['id'] > 0) { $dates = $this->recalcBindDates($uid, array('bind_id' => $bindInfo['id'], 'op_code' => $operation['op_code'], 'op_id' => $operation['id'], 'tservice_id' => $bindInfo['tservice_id'], 'prof_id' => $bindInfo['prof_id'])); $this->db()->update($this->TABLE, array('date_start' => $dates['start'], 'date_stop' => $dates['stop']), 'id = ?i', $bindInfo['id']); } return 0; }