# Menü Uygulaması - Yonerge ve Yapı Özeti

Bu dosya, `poscloud` POS projesine entegre olan menü uygulamasının
geliştirilmesi için gerekli tüm teknik bilgileri icerir.

---

## 1. Mimari Yapi

- **POS Projesi:** `poscloud.apper` — Ana POS uygulamas (Laravel)
- **Menu Projesi:** `menu.apper.com.tr` — Apper proje catisi altnda ayri proje
- **Veritaban:** POS projesinin veritabanina remote baglanti yapilacak
- **Menu, POS veritabanndaki tablolari okuyarak/yazarak işlem gerceklestirir**

---

## 2. Menü Tipleri

### A - Dijital Menü

- Müşteriler QR kod yardımı ile işletme menüsüne erişim sağlarlar
- Sadece menü görüntüleme amaçlı
- Sipariş özelliği yok
- `menu_type = digital_menu`

### B - Sabit QR ile Sipariş

- Masalara yerleştirilen sabit QR kodlar ile sipariş
- QR okutulur → masa bilgisi gelir
- Kullanıcı ürünleri sepete ekler
- Sepet onaylandığında popup: **Masa No, İsim Soyisim, Cep Telefonu**
- Sipariş oluşturulur
- `menu_type = fixed_qr_order`

### C - Dinamik QR ile Doğrulamalı Sipariş

- Müşteri oluşturulur, QR kod yazdırılır
- QR'daki `verification_code` ile sistem bağlanılır
- Müştei QR ile sisteme bağlandığında popup: **Masa No** seçer (kullanıcı bilgileri zaten var)
- Kullanıcı ürünleri sepete ekler
- Sipariş oluşturulur
- `menu_type = dynamic_qr_verified`
- Masa kapatıldığında qr kod geçersiz kalır.

---

## 3. Tahsilat Tipleri

### 1 - Kasada Ödeme

- Ödemeler işletme tarafından kasada tahsil edilir
- `payment_collection = cash_register`
- `payment_type = 0` (UNPAID)

### 2 - Ön Ödeme (Bakiyeli Sistem)

- Müşteriler işletme girişinde hesaplarına bakiye yüklerler
- Sipariş tutarları bakiyeden düşer
- `payment_collection = prepayment`
- `payment_type = 5` (CREDIT)

### 3 - Dijital Ödeme

- Müşteriler kredi kartları ile dijital menü üzerinden ödeme yapabilirler
- `payment_collection = digital_payment`
- Entegrasyon: Paytr veya benzeri ödeme gateway

---

## 4. Mevcut Durum ve Kombinasyonlar

**Tamamlanan Özellikler:**

### ✓ Menü Tipi A - Dijital Menü (Sadece Görüntüleme)

- QR kod ile menüye erişim
- Sipariş özelliği yok (read-only)
- Bilgilendirme banner'ı gösterilir
- Uygulama Tarihi: Nisan 2026
- Dosyalar: `MenuController@index`, `resources/views/menu/digital.blade.php`

### ✓ Menü Tipi B + Tahsilat Tipi 1 - Sabit QR ile Sipariş + Kasada Ödeme

- Sabit QR ile sipariş + Kasada ödeme
- Müşteri bilgisi toplama (isim, soyisim, telefon)
- Çalışıyor ✓
- Uygulama Tarihi: Mart 2026

**Diğer olası kombinasyonlar (Gelecek Geliştirmeler):**

- B + 2: Sabit QR + Ön Ödeme (Bakiye Sistemi)
- B + 3: Sabit QR + Dijital Ödeme (Kredi Kartı)
- C + 1: Dinamik QR + Kasada Ödeme
- C + 2: Dinamik QR + Ön Ödeme
- C + 3: Dinamik QR + Dijital Ödeme

---

## 5. Veritaban Tabloları ve İlişkiler

### 3.1. PosSales `sales` (Adisyonlar)

| Kolon               | Tur                         | Aciklama                      |
| ------------------- | --------------------------- | ----------------------------- |
| `id`                | bigint                      |                               |
| `company_id`        | int                         | Firma ID                      |
| `destination_type`  | string                      | `'table'` veya `'address'`    |
| `destination_id`    | int                         | Masa veya adres ID            |
| `payer_id`          | int nullable                | Msteri ID (customers.id)      |
| `channel`           | enum                        | `'menu'` = menu siparisi      |
| `verification_code` | varchar(36) nullable unique | QR kodda tasnan benzersiz kod |
| `payment_type`      | tinyint                     | `0`=unpaid, `5`=CREDIT        |
| `status`            | enum                        | `'kitchen'` (mutfaq)          |
| `data`              | json nullable               | Ekstra meta veri              |

**Kullanm:**

- Siparis olusturmak icin `sales` tablosuna yeni satir eklenir
- `verification_code` ile sale bulunur (Senaryo 2-3)
- `tables.qr_code` ile masa bulunur → sale olusturulur (Senaryo 1)

### 3.2. Order `orders` (Urunler / Siparis Kalemleri)

| Kolon          | Tur             | Aciklama                            |
| -------------- | --------------- | ----------------------------------- |
| `id`           | bigint          |                                     |
| `company_id`   | int             |                                     |
| `sale_id`      | bigint nullable | Hangi adisyona ait                  |
| `product_id`   | int nullable    | Urun ID                             |
| `quantity`     | decimal         | Miktar                              |
| `price`        | decimal         | Birim fiyat                         |
| `total_price`  | decimal         | Toplam fiyat                        |
| `payment_type` | tinyint         | `0`=unpaid, `5`=CREDIT              |
| `status`       | string          | `'new'`, `'kitchen'`, `'completed'` |
| `specs`        | string (JSON)   | Ozelikler (secenekler)              |
| `note`         | string nullable | Not                                 |
| `channel`      | enum            | `'menu'`                            |

**Kullanm:**

- Her urun sepete eklendiginde `orders` tablosuna satir eklenir
- `sale_id` ile hangi adisyona ait oldugu belirlenir

### 3.3. PosCustomer `customers` (Musteriler)

| Kolon        | Tur    | Aciklama |
| ------------ | ------ | -------- |
| `id`         | int    |          |
| `name`       | string |          |
| `surname`    | string |          |
| `phone`      | string |          |
| `address`    | string |          |
| `channel`    | enum   |          |
| `channel_id` | string |          |

**Kullanm:**

- Senaryo 1'de: Popup'tan gelen isim/telefon ile yeni msteri olusturulur
- Senaryo 2-3'de: POS tarafinda msteri zaten olusturulmus olur
- `company_customer` pivot tablosu ile firmaya baglanir

### 3.4. PosTable `tables` (Masalar)

| Kolon        | Tur                         | Aciklama                  |
| ------------ | --------------------------- | ------------------------- |
| `id`         | int                         |                           |
| `company_id` | int                         |                           |
| `name`       | string                      | Masa adi                  |
| `qr_code`    | varchar(36) nullable unique | Sabit QR kodu (Senaryo 1) |
| `enabled`    | bool                        | Aktif mi                  |

**Kullanm:**

- Senaryo 1'de: QR kod ile masa bulunur

### 3.5. PosProduct `products` (Urunler)

| Kolon          | Tur           | Aciklama  |
| -------------- | ------------- | --------- |
| `id`           | int           |           |
| `company_id`   | int           |           |
| `name`         | string        | Urun adi  |
| `price`        | decimal       | Fiyat     |
| `category_id`  | int nullable  | Kategori  |
| `description`  | text nullable | Aciklama  |
| `available`    | bool          | Mevcut mu |
| `order_number` | int           | Siralama  |

**Kullanm:**

- Menu ekraninda urunler buradan listelenir
- `channel` filtresi uygulanabilir (menu'de gorunmesini istenen urunler)

### 3.6. PosCategory `categories` (Kategoriler)

| Kolon          | Tur    | Aciklama |
| -------------- | ------ | -------- |
| `id`           | int    |          |
| `company_id`   | int    |          |
| `name`         | string |          |
| `order_number` | int    | Siralama |

### 3.7. `specs` + `options` (Urun Ozelikleri)

- `specs`: Urun ozellik gruplari (orn: "Boyut", "Icecek")
- `options`: Her spece ait secenekler (orn: "Kucuk", "Buyuk", "Ayran")
- `options.price_diff`: Fiyat farki

### 3.8. `accounts` + `transactions` (Bakiye Sistemi)

**`accounts`:**
| Kolon | Tur | Aciklama |
|---|---|---|
| `first_party_type` | string | `'customer'` |
| `first_party_id` | int | Msteri ID |
| `second_party_type` | string | `'company'` |
| `second_party_id` | int | Firma ID |
| `balance` | decimal | Guncel bakiye |

**`transactions`:**
| Kolon | Tur | Aciklama |
|---|---|---|
| `account_id` | int | Hangi hesap |
| `amount` | decimal | Tutar (+yukleme, -harca) |
| `payment_type` | tinyint | `5` = CREDIT |
| `action_type` | string nullable | `'sale'` |
| `action_id` | int nullable | Sale ID |
| `description` | text | |

**Kullanm (Senaryo 3):**

1. POS'ta kredi yuklendiginde: `INSERT INTO transactions` (amount: +1000)
2. Siparis onaylandiginda: `INSERT INTO transactions` (amount: -350, action_type:'sale', action_id:42)
3. Balance otomatik guncellenir

---

## 6. ChannelTypes ve PaymentTypes

### ChannelTypes (`app/Types/ChannelTypes.php`)

```php
const SABEE = 'sabee';
const GETIR = 'getir';
const YEMEKSEPETI = 'yemeksepeti';
const MENU = 'menu';        // <-- Menü siparisleri icin kullanılacak
```

### PaymentTypes (`app/Types/PaymentTypes.php`)

```php
const UNPAID = 0;    // Henuz odememis (kasada odenecek)
const CREDIT = 5;    // Bakiyeden odenmis
```

---

## 7. Settings (POS Tarafı)

POS'un `config/settings.php` dosyasında company seviyesinde menü ayarları:

```php
'menu_module_enabled'   => false,  // Feature flag — kapalı başlıyor
'menu_type'             => 'fixed_qr_order',  // digital_menu | fixed_qr_order | dynamic_qr_verified
'payment_collection'    => 'cash_register',   // cash_register | prepayment | digital_payment
```

Menü uygulaması, POS API'sinden bu ayarları çekerek davranışı belirlemeli:

- `menu_type = 'digital_menu'` → Sadece menü gösterimi (sipariş yok)
- `menu_type = 'fixed_qr_order'` → Sabit QR ile sipariş akışı
- `menu_type = 'dynamic_qr_verified'` → Dinamik QR doğrulamalı sipariş akışı

- `payment_collection = 'cash_register'` → Kasada ödeme (UNPAID)
- `payment_collection = 'prepayment'` → Bakiyeden ödeme (CREDIT)
- `payment_collection = 'digital_payment'` → Online ödeme gateway

---

## 8. Veri Akış Diyagramları

### Menü Tipi A: Dijital Menü (TAMAMLANDI ✓)

**URL Yapısı:**

```
/menu/digital/{firma-slug}
```

**Örnekler:**

- `https://menu.apper.com.tr/menu/digital/lakeside-hotel`
- `https://menu.apper.com.tr/menu/digital/kafe-istanbul`
- `https://menu.apper.com.tr/menu/digital/restoran-ankara`

**Akış:**

```
QR kod → /menu/digital/{slug} URL'ine yönlendirir
→ MenuController@digital metodu çağrılır
→ PosCompany.slug ile firma bulunur
→ digital_menu_enabled kontrolü yapılır
  - Aktif (1) → digital.blade.php gösterilir
  - Pasif (0) → "Dijital menü kullanılamıyor" mesajı
→ selected_pos_service_id session'a kaydedilir
→ digital.blade.php gösterilir
  - Sale oluşturma YOK
  - Sepet özelliği YOK
  - Bilgilendirme banner'ı görünür
  - Accordion ile kategori/ürün listesi
  - "Sepete Ekle" butonları YOK
```

**Uygulama Detayları:**

- Route: `Route::get('/digital/{slug}', [MenuController::class, 'digital'])`
- Controller: `MenuController@digital` - Firma slug ile company bulur
- View: `resources/views/menu/digital.blade.php` - Read-only menü görünümü
- JavaScript: Sepete ekleme tamamen devre dışı
- Ayar: POS'ta `settings` tablosunda `digital_menu_enabled = '1'` (aktif) veya `'0'` (pasif)

**Özellikler:**

- ✅ `menu_type` ayarından BAĞIMSIZ çalışır
- ✅ `digital_menu_enabled` ile aktif/pasif kontrolü
- ✅ Tip B/C ile AYNI ANDA kullanılabilir
- ✅ Firma bazlı, masa bağımsız

**QR Kod Oluşturma:**
Firma için QR kod oluşturulurken şu URL kullanılır:

```
https://menu.apper.com.tr/menu/digital/{firma-slug}
```

Örnek: Lakeside Hotel için

- Firma slug: `lakeside-hotel`
- QR URL: `https://menu.apper.com.tr/menu/digital/lakeside-hotel`

**Avantajlar:**

- ✓ Masa bazlı değil, firma bazlı
- ✓ Tek QR kod tüm restoran için geçerli
- ✓ Masalara yerleştirilebilir veya girişte asılabilir
- ✓ Değişmez, kalıcı QR kod
- ✓ PosCompany.slug değeri sabit ve unique
- ✓ İstendiğinde kolayca açılıp kapatılabilir

### Menü Tipi B: Sabit QR ile Sipariş + Kasada Ödeme (MEVCUT)

```
QR kod (tables.qr_code) → Masa bulunur → Sale oluşturulur
→ Menü gösterilir → Ürün seçilir → orders eklenir
→ Popup (İsim, Telefon, Masa No) → Customer oluşturulur
→ sales.payer_id = customer_id → Sipariş tamamlandı (payment_type: 0/UNPAID)
```

### Menü Tipi C: Dinamik QR ile Doğrulamalı Sipariş + Kasada Ödeme

```
POS → Customer + Sale oluşturur (verification_code: 'x7k2m9p1')
→ QR üretilir: menu.site/sale/x7k2m9p1
→ Müşteri QR tarar → sale bulunur (verification_code ile)
→ Menü gösterilir → Ürün seçilir → orders eklenir
→ Popup (Masa No) → Sipariş tamamlandı (payment_type: 0/UNPAID)
```

### Menü Tipi B/C + Ön Ödeme (Bakiyeli)

```
POS → Customer + Sale + Kredi yükleme
→ accounts.balance = 1000
→ QR üretilir → Müşteri bağlanır → Bakiye gösterilir
→ Ürün seçilir (sepet: 350 TL)
→ Bakiye kontrolü: 1000 >= 350 → OK
→ transactions eklenir (amount: -350, action_type:'sale', action_id:42)
→ sales.payment_type = 5 (CREDIT) → Sipariş tamamlandı
```

### Menü Tipi B/C + Dijital Ödeme

```
QR kod → Menü gösterilir → Ürün seçilir → Sepet onayı
→ Paytr ödeme sayfasına yönlendirme
→ Ödeme başarılı → sales.payment_type güncellenir
→ Sipariş tamamlandı
```

---

## 9. Menü Uygulamasında Gereken API Endpoint'leri

POS projesinde asagidaki endpoint'lerin olusturulmasi gerekir:

### Auth / Session

| Metod | Yol                         | Aciklama                                               |
| ----- | --------------------------- | ------------------------------------------------------ |
| GET   | `/api/menu/verify/{code}`   | verification_code ile sale bul, msteri bilgilerini don |
| GET   | `/api/menu/table/{qr_code}` | Sabit QR ile masa bul, sale olustur                    |

### Menu Verisi

| Metod | Yol                    | Aciklama                                           |
| ----- | ---------------------- | -------------------------------------------------- |
| GET   | `/api/menu/products`   | Menu urunlerini listele (kategori, ozellik, fiyat) |
| GET   | `/api/menu/categories` | Kategorileri listele                               |

### Siparis

| Metod | Yol                     | Aciklama                        |
| ----- | ----------------------- | ------------------------------- |
| POST  | `/api/menu/cart`        | Sepete urun ekle                |
| POST  | `/api/menu/cart/remove` | Sepetten urun cikar             |
| GET   | `/api/menu/cart`        | Sepet icerigini getir           |
| POST  | `/api/menu/checkout`    | Sepeti onayla, siparisi tamamla |

### Bakiye (Senaryo 3)

| Metod | Yol                 | Aciklama                |
| ----- | ------------------- | ----------------------- |
| GET   | `/api/menu/balance` | Msteri bakiyesini getir |

### Settings

| Metod | Yol                  | Aciklama                      |
| ----- | -------------------- | ----------------------------- |
| GET   | `/api/menu/settings` | Company menu ayarlarini getir |

---

## 10. Uygulama Sırası

1. **API Endpoint'leri** — POS tarafında endpoint'leri oluştur
2. **Veritaban ilişkileri** — `Sale`, `Order`, `Customer` modellerinde menü ilişkilerini kur
3. **Menü arayüzü** — Ürün listesi, kategori navigasyonu, sepet
4. **Sipariş akışı** — Sepet onay, popup, sipariş tamamlama
5. **Ön ödeme sistemi** — Bakiye kontrolü ve düşme (Tip 2)
6. **Dijital ödeme entegrasyonu** — Paytr veya benzeri gateway (Tip 3)

---

## 11. Dikkat Edilmesi Gereken Noktalar

- `menu_module_enabled = false` ise menü uygulaması erişime kapalı olmalı
- `verification_code` unique kısıtı — aynı kod 2 kere kullanılamamalı
- Menü Tipi A'da sipariş özelliği devre dışı
- Menü Tipi B'de `sales.verification_code = NULL`, `sales.channel = 'menu'`
- Menü Tipi C'de `sales.channel = 'menu'` ve `sales.verification_code` set edilmeli
- `payment_type`:
    - Kasada Ödeme (Tip 1) → `0` (UNPAID)
    - Ön Ödeme (Tip 2) → `5` (CREDIT)
    - Dijital Ödeme (Tip 3) → Gateway response'a göre güncellenir
- `transactions.action_type = 'sale'` + `action_id` ile sale bağlantısı kurulmalı (Tip 2 için)

---

## 12. POS Tarafında Yapılan Değişiklikler (Tamamlandı)

### Migration'lar

- `2026_04_09_000001_add_verification_code_to_sales_table.php`
- `2026_04_09_000002_add_qr_code_to_tables_table.php`
- `2026_04_09_000003_add_menu_to_channel_types.php`

### Config

- `config/settings.php` → `menu_module_enabled`, `menu_type`, `payment_collection` eklendi

### Types

- `app/Types/ChannelTypes.php` → `const MENU = 'menu'` eklendi

### Mevcut Implementasyon

✓ Menü Tipi A (Dijital Menü) - Nisan 2026
✓ Menü Tipi B (Sabit QR ile Sipariş) + Tahsilat Tipi 1 (Kasada Ödeme) - Mart 2026

---

## 13. Dijital Menü (Tip A) Uygulama Notları

### Yapılan Değişiklikler

#### 1. Yeni Route Eklendi

- `Route::get('/digital/{slug}', [MenuController::class, 'digital'])`
- URL yapısı: `/menu/digital/{firma-slug}`
- Örnek: `/menu/digital/lakeside-hotel`

#### 2. MenuController Güncellemeleri

- `digital()` metodu eklendi - Firma slug ile erişim sağlar
- `digital_menu_enabled` kontrolü eklendi (aktif/pasif)
- `index()` metodundan `menu_type=digital_menu` kontrolü KALDIRILDI
- `getMenuSetting()` private metodu eklendi - POS ayarlarını remote DB'den çeker
- Tip A ve Tip B artık AYNI ANDA kullanılabilir

#### 3. Yeni View Dosyası

- `resources/views/menu/digital.blade.php` oluşturuldu
- Accordion (kategori aç/kapa) özelliği var
- "Sepete Ekle" butonları YOK
- Navbar (sepet badge) YOK
- Mavi bilgilendirme banner'ı eklendi
- Firma bilgisi: `web` field'ı kullanılır

#### 4. PosCompany Model

- `web` field'ı fillable ve casts'te tanımlı

### QR Kod URL Yapısı

**Dijital Menü (Tip A):**

```
https://menu.apper.com.tr/menu/digital/{firma-slug}
```

**Sabit QR ile Sipariş (Tip B):**

```
https://menu.apper.com.tr/menu/{masa-qr-kodu}
```

**Örnekler:**

| Firma           | Slug              | Dijital Menü URL                |
| --------------- | ----------------- | ------------------------------- |
| Lakeside Hotel  | `lakeside-hotel`  | `/menu/digital/lakeside-hotel`  |
| Kafe İstanbul   | `kafe-istanbul`   | `/menu/digital/kafe-istanbul`   |
| Restoran Ankara | `restoran-ankara` | `/menu/digital/restoran-ankara` |

### POS Ayarları

**Dijital Menü Aktif/Pasif Kontrolü:**

POS sisteminde `settings` tablosunda:

```sql
-- Dijital menüyü aktif et
INSERT INTO settings (relation_type, relation_id, key, value)
VALUES ('company', {company_id}, 'digital_menu_enabled', '1');

-- Veya güncelle
UPDATE settings
SET value = '1'  -- '1' = Aktif, '0' = Pasif
WHERE relation_type = 'company'
  AND relation_id = {company_id}
  AND key = 'digital_menu_enabled';
```

**Diğer Ayarlar:**

```sql
-- Payment collection tipi (Tip B/C için)
UPDATE settings
SET value = 'cash_register'  -- veya 'prepayment', 'digital_payment'
WHERE relation_type = 'company'
  AND relation_id = {company_id}
  AND key = 'payment_collection';
```

**Not:**

- `digital_menu_enabled` → Sadece Tip A için (aktif/pasif)
- `menu_type` → Kullanılmıyor (kaldırıldı)
- `payment_collection` → Tip B/C için ödeme tipi

### Test Senaryosu

**Senaryo 1: Dijital Menü Aktif**

1. `digital_menu_enabled = '1'` olarak ayarla
2. Firma slug'ını belirle (örn: `lakeside-hotel`)
3. QR kodu oluştur: `https://menu.apper.com.tr/menu/digital/lakeside-hotel`
4. QR kodu okut
5. Beklenen davranış:
    - ✓ Firma logosu ve bilgileri görünür
    - ✓ Mavi bilgilendirme banner'ı görünür
    - ✓ Kategoriler accordion ile listelenir
    - ✓ Ürünler ve fiyatlar görünür
    - ✗ "Sepete Ekle" butonları YOK
    - ✗ Alt navbar (sepet simgesi) YOK
    - ✗ Sipariş verme özelliği YOK

**Senaryo 2: Dijital Menü Pasif**

1. `digital_menu_enabled = '0'` olarak ayarla
2. QR kodu okut
3. Beklenen davranış:
    - ✓ Hata mesajı: "Dijital menü şu anda kullanılamıyor. Lütfen garsonumuzdan menüyü isteyiniz."
    - ✓ Firma logosu görünür (opsiyonel)

**Senaryo 3: Tip A + Tip B Aynı Anda**

1. `digital_menu_enabled = '1'`
2. Girişte Tip A QR: `/menu/digital/lakeside-hotel`
3. Masalarda Tip B QR: `/menu/{masa-qr-kodu}`
4. Beklenen davranış:
    - ✓ Tip A: Sadece görüntüleme
    - ✓ Tip B: Sipariş verme aktif
    - ✓ İkisi de aynı firma için çalışır

### Kullanım Senaryoları

**Senaryo 1: Girişte Büyük QR Poster**

- Restoran girişine büyük QR kod poster asılır
- Müşteriler içeri girerken menüyü inceleyebilir
- Garson gelip siparişi alır

**Senaryo 2: Masalarda Sabit QR**

- Her masaya aynı QR kod yerleştirilir
- Müşteriler menüyü görüntüler
- Garson ile sipariş verirler

**Senaryo 3: Hijyenik Menü**

- Fiziksel menü kullanılmaz
- Müşteriler kendi telefonlarından bakar
- COVID-19 gibi durumlarda ideal

### Gelecek İyileştirmeler

- [ ] Çok dilli menü desteği (TR/EN/AR)
- [ ] Ürün fotoğrafları gösterimi
- [ ] Ürün filtreleme (vegan, glütensiz vb.)
- [ ] Arama özelliği
- [ ] Popüler ürünler bölümü
- [ ] Fiyat aralığı filtresi
- [ ] Kategoriye göre hızlı navigasyon

---

> Bu dokuman menu.apper.com.tr projesinde calisan gelistirici icin referanstir.
> POS projesindeki herhangi bir degisiklik bu dokumani da guncelleyecektir.
