← Înapoi

⚙️ Documentație Tehnică

Flow Închiriere Domeniu - Sistem Licitații

Prezentare Generală

Sistemul de închiriere domenii funcționează pe baza unui mecanism de licitație în care brokerii licitează pentru dreptul de a închiria un domeniu pentru o perioadă specificată.

🎯 Actori Principali

  • Administrator - Gestionează domenii și licitații
  • Broker - Licitează pentru domenii
  • Subscriber (Abonat) - Folosește domeniul după închiriere
  • Sistem Automat (Cron Jobs) - Procesează licitații și facturi

Flux Complet - 7 Faze

FAZA 1

Pregătire Licitație

1.1. Administrator Adaugă Domeniu

Backend → Domenii → Adaugă Domeniu
// Câmpuri obligatorii Domain: - name: "exemplu" - extension: ".ro" - full_name: "exemplu.ro" - price: 100.00 - expire_at: "2026-12-31" - status: ACTIVE

1.2. Administrator Creează Licitație

Backend → Licitații → Adaugă Licitație
Parametru Tip Exemplu Descriere
domain_id integer 1 ID-ul domeniului pentru care se licitează
start_at datetime 2025-12-05 00:00:00 Data început licitație
end_at datetime 2025-12-20 23:59:59 Data sfârșit licitație
start_price decimal(10,2) 100.00 Prețul minim de pornire
step decimal(10,2) 5.00 Pas de incrementare
valid_from datetime 2026-01-01 00:00:00 Început perioadă validitate
valid_to datetime 2026-01-31 23:59:59 Sfârșit perioadă validitate
period integer 1 Perioada de închiriere (1, 3, 6, 12)
cycle string MONTHLY Ciclul (MONTHLY, YEARLY)
currency string RON Moneda (RON, EUR, USD)
FAZA 2

Procesul de Licitație

2.1. Broker Vizualizează Licitații Active

Frontend → Domenii cu Licitații Active
// Query pentru licitații active SELECT * FROM auction WHERE status = ACTIVE AND start_at <= NOW() AND end_at >= NOW()

2.2. Broker Plasează Licitație

Frontend → Click domeniu → Modal "Bid on Domain"

Validări Automate (BidForm.php)

// frontend/modules/domain/models/BidForm.php // frontend/modules/bid/models/BidForm.php public function validateBidAmount($attribute, $params) { $auction = $this->auction; $bidAmount = $this->$attribute; $startPrice = (float)$auction->start_price; $step = (float)$auction->step; // Validare 1: Bid >= start_price if ($bidAmount < $startPrice) { $this->addError($attribute, "Minimum bid: {$startPrice}"); return; } // Validare 2: Pentru bid-uri ulterioare $highestBid = Bid::find() ->where(['auction_id' => $auction->id]) ->orderBy(['price' => SORT_DESC]) ->one(); if ($highestBid && $bidAmount < $highestBid->price + $step) { $this->addError($attribute, "Minimum: {$highestBid->price + $step}"); return; } // Validare 3: Diferența trebuie să fie multiplu de step $difference = $bidAmount - $startPrice; if (fmod($difference, $step) > 0.01) { $this->addError($attribute, "Bid must be multiple of step: {$step}"); } }

✅ Reguli Validare

  • Prima licitație: bid >= start_price
  • Licitații ulterioare: bid >= current_price + step
  • Toate: (bid - start_price) % step == 0
FAZA 3

Închidere Licitație (Automată)

3.1. Cron Job - Închidere Licitații

php yii auction/run

Frecvență: Zilnic (ex: 00:05)

// console/controllers/AuctionController.php public function actionRun() { $count = 0; $this->stdout("[" . date('Y-m-d H:i:s') . "] Processing auctions...\n"); // Găsește licitații expirate $auctions = Auction::find() ->where(['status' => Auction::STATUS_ACTIVE]) ->andWhere(['<=', 'end_at', date('Y-m-d H:i:s')]) ->all(); foreach ($auctions as $auction) { // Găsește bid-ul câștigător $highestBid = Bid::find() ->where(['auction_id' => $auction->id]) ->orderBy(['price' => SORT_DESC]) ->one(); if ($highestBid) { // Generează factura proforma $this->saveProformaInvoice($highestBid, $auction->domain_id); // Trimite email câștigător $this->sendBrokerWinnerEmail($highestBid, $auction); // Update status-uri $auction->status = Auction::STATUS_PROCESSING; $auction->save(false); $highestBid->status = Bid::STATUS_PROCESSING; $highestBid->save(false); $count++; } } $this->stdout("[" . date('Y-m-d H:i:s') . "] Processed {$count} auction(s).\n"); }

3.2. Generare Factură Proforma

Câmp Invoice Valoare Descriere
broker_id ID broker câștigător Legătură cu brokerul
type TYPE_PROFORMA (11) Tip factură
status STATUS_UNPAID (1) Status inițial
amount Prețul licitat Suma de plată
currency RON / EUR / USD Moneda
issued_at NOW() Data emitere

3.3. Email Notificare Câștigător

Template: EMAIL_VARIANT_DOMAIN_WIN

ShortCodes disponibile:

  • {{DOMAIN_FULL_NAME}} - Numele complet al domeniului
  • {{PRICE}} - Prețul licitat
  • {{DAYS_TO_RESPOND}} - Numărul de zile pentru plată (default: 2)
  • {{INVOICE_URL_LINK}} - Link către factura proforma
FAZA 4

Plata Facturii Proforma

4.1. Broker Accesează Factura

Frontend → My Account → Invoices
  • Vizualizează factura proforma
  • Descarcă PDF (cu watermark "UNPAID")
  • Vede detalii: domeniu, preț, TVA, total

4.2. Confirmare Plată

// Manual (Admin confirmă) Backend → Invoices → Marchează ca plătită // Automat (Webhook procesator plată) $invoice->status = Invoice::STATUS_PAID; $invoice->paid_at = date('Y-m-d H:i:s'); $invoice->save();
FAZA 5

Transfer la Următorul Broker

5.1. Cron Job - Verificare Plăți

php yii next-broker/run

Frecvență: Zilnic (ex: 00:10)

// console/controllers/NextBrokerController.php public function actionRun() { $count = 0; $transferredCount = 0; $noOfDays = 2; // Configurabil $this->stdout("[" . date('Y-m-d H:i:s') . "] Checking unpaid auctions...\n"); // Găsește licitații cu facturi neplătite > 2 zile $auctions = Auction::find() ->where(['status' => Auction::STATUS_PROCESSING]) ->all(); foreach ($auctions as $auction) { $bid = Bid::find() ->where([ 'auction_id' => $auction->id, 'status' => Bid::STATUS_PROCESSING ]) ->one(); if (!$bid) continue; // Verifică factura $invoice = Invoice::findOne([ 'broker_id' => $bid->broker_id, 'status' => Invoice::STATUS_UNPAID ]); if (!$invoice) continue; // Verifică dacă au trecut 2 zile $issuedDate = new DateTime($invoice->issued_at); $currentDate = new DateTime(); $daysPassed = $currentDate->diff($issuedDate)->days; if ($daysPassed >= $noOfDays) { $count++; // Dezactivează bid-ul curent $bid->status = Bid::STATUS_INACTIVE; $bid->save(false); // Găsește următorul bid $nextBid = Bid::find() ->where([ 'auction_id' => $auction->id, 'status' => Bid::STATUS_ACTIVE ]) ->orderBy(['price' => SORT_DESC]) ->one(); if ($nextBid) { // Generează nouă factură proforma $this->saveProformaInvoice($nextBid, $auction->domain_id); // Trimite email $this->sendBrokerWinnerEmail($nextBid, $auction); // Update status $nextBid->status = Bid::STATUS_PROCESSING; $nextBid->save(false); $transferredCount++; } } } $this->stdout("[" . date('Y-m-d H:i:s') . "] Processed {$count} unpaid auction(s), transferred {$transferredCount} to next broker(s).\n"); }
FAZA 6

Activare Închiriere

6.1. Creare Abonament (După Plată)

// Creare subscription după confirmare plată $subscription = new Subscription(); $subscription->subscriber_id = $broker->id; $subscription->domain_id = $auction->domain_id; $subscription->start_at = $auction->valid_from; $subscription->end_at = $auction->valid_to; $subscription->price = $bid->price; $subscription->currency = $auction->currency; $subscription->status = Subscription::STATUS_ACTIVE; $subscription->save();

6.2. Email Confirmare Plată

Template: EMAIL_VARIANT_INVOICE_PAYMENT_CONFIRMATION

Conține:

  • Confirmare plată primită
  • Detalii domeniu și perioadă
  • Factura finală (PDF fără watermark)
  • Instrucțiuni acces domeniu
FAZA 7

Monitorizare și Reînnoire

7.1. Cron Job - Verificare Abonamente

php yii payment/run

Frecvență: Zilnic (ex: 00:15)

  • Verifică abonamente care se apropie de expirare
  • Generează facturi pentru reînnoire
  • Trimite notificări (X zile înainte)
  • Suspendă abonamente neplătite

Statusuri și Tranzițiile Lor

Auction (Licitație)

STATUS_ACTIVE (0)
↓ (când end_at <= NOW)
↓ [php yii auction/run]
STATUS_PROCESSING (2)
↓ (după plată și creare subscription)
STATUS_INACTIVE (1)

Bid (Licitație Broker)

STATUS_ACTIVE (0)
↓ (când auction se închide și este câștigător)
↓ [php yii auction/run]
STATUS_PROCESSING (2)
↓ (dacă NU plătește în 2 zile)
↓ [php yii next-broker/run]
STATUS_INACTIVE (1)

Invoice (Factură)

TYPE_PROFORMA (11) + STATUS_UNPAID (1)
↓ (broker plătește)
STATUS_PAID (2)
↓ (sistem generează factura finală)
TYPE_INVOICE (10) + STATUS_PAID (2)

Comenzi Console (Cron Jobs)

Comandă Frecvență Descriere Output
php yii auction/run Zilnic 00:05 Închide licitații expirate
Generează proforma
Trimite emailuri
[timestamp] Processed X auction(s).
php yii next-broker/run Zilnic 00:10 Verifică facturi neplătite
Transferă la următorul broker
[timestamp] Processed X unpaid, transferred Y.
php yii payment/run Zilnic 00:15 Verifică abonamente
Generează facturi reînnoire
[timestamp] Processed X subscription(s).
php yii subscription/renew-features-quota Lunar (1 ale lunii) Resetează quota features [timestamp] Renewed features quota.

Setup Cron Jobs (Recomandări)

# Închidere licitații 5 0 * * * cd /path/to/app && php yii auction/run >> /var/log/auction.log 2>&1 # Transfer la următorul broker 10 0 * * * cd /path/to/app && php yii next-broker/run >> /var/log/next-broker.log 2>&1 # Verificare plăți abonamente 15 0 * * * cd /path/to/app && php yii payment/run >> /var/log/payment.log 2>&1 # Reînnoire quota features (lunar) 0 0 1 * * cd /path/to/app && php yii subscription/renew-features-quota >> /var/log/subscription.log 2>&1

Structura Bazei de Date

Tabele Principale

Tabelă Câmpuri Cheie Relații
domain id, name, extension, full_name, price, expire_at, status hasMany Auction, hasMany Subscription
auction id, domain_id, start_at, end_at, start_price, step, valid_from, valid_to, status belongsTo Domain, hasMany Bid
bid id, auction_id, broker_id, price, currency, status belongsTo Auction, belongsTo Broker
invoice id, broker_id, type, status, amount, issued_at, paid_at belongsTo Broker, hasMany Item
item id, invoice_id, item_id, type, quantity, price belongsTo Invoice
subscription id, subscriber_id, domain_id, start_at, end_at, price, status belongsTo Domain, belongsTo Subscriber

Troubleshooting

⚠️ Problema: Factura nu se generează

  • Verifică template-ul de factură în backend
  • Verifică că există Template::TYPE_INVOICE
  • Check logs pentru erori SQL: @runtime/logs/app.log

⚠️ Problema: Email-ul nu se trimite

  • Verifică configurarea SMTP în common/config/main-local.php
  • Verifică template-ul email în backend
  • Test SMTP: php yii test/email
  • Check mailer component configuration

⚠️ Problema: Cron job nu rulează

  • Verifică crontab: crontab -l
  • Check permissions: chmod +x yii
  • Verifică path-ul către PHP: which php
  • Check logs: tail -f /var/log/auction.log

API Endpoints (Dacă există)

📡 REST API (Opțional)

// Listare licitații active GET /api/v1/auctions?status=active // Plasare bid POST /api/v1/bids { "auction_id": 1, "price": 150.00, "currency": "RON" } // Verificare status licitație GET /api/v1/auctions/{id}/status // Istoric bid-uri GET /api/v1/auctions/{id}/bids

📞 Suport Tehnic

Pentru probleme tehnice sau întrebări despre implementare, contactează echipa de dezvoltare.

📅 Generat: 17 Decembrie 2025 | ⚙️ Yii2 Advanced Framework