/v1/offers kaynağı, bir hasta veya lead için hazırlanan fiyat teklifini yönetir. Teklif; tedavi ve ürün kalemlerinden, para biriminden, geçerlilik tarihinden ve bir durumdan oluşur. Kabul edilen teklifi tek çağrıyla taslak satışa dönüştürebilir, teklifin PDF’ini üretebilirsiniz.
Tüm istekler https://app.flextell.ai/api/v1 altındadır ve Authorization: Bearer <access_token> ile X-Tenant: <tenant_id> başlıklarını gerektirir. Bkz. Klinikler ve X-Tenant.
Bu modül teklifi hastaya e-posta, WhatsApp veya SMS ile göndermez.
sent durumu yalnızca elle işaretlenen bir bayraktır. Teklif şablonlarını yöneten bir API de yoktur; PDF her zaman kliniğin şablonuyla üretilir.Endpoint özeti
Her endpoint için scope ve izin birlikte gerekir. Kalıcı silme (
force) endpoint’i yoktur. İzin modeli için İzinler ve görünürlük sayfasına bakın.
Görünürlük
ViewAllOffers:Offer iznine sahip kullanıcı kliniğin tüm tekliflerini görür. İzni olmayan kullanıcı yalnızca sahibi olduğu teklifleri ve kendisine atanmış lead’lerin tekliflerini görür. salesperson rolündeki kullanıcı ayrıca lead aşamasını geçmiş hastaların tüm tekliflerini görür. Görünmeyen teklif için 404 RESOURCE_NOT_FOUND döner, 403 dönmez.
Listeleme
GET /v1/offers sayfalı döner. Liste yanıtında items yer almaz, yalnızca total_price gelir. Sayfalama için Sayfalama, genel sıralama kuralları için Filtreleme ve sıralama sayfasına bakın.
Teklif nesnesi
Her kalemde (
items[]) şu alanlar döner: id, offer_id, order, itemable_type (Treatment veya Product), itemable_id, quantity, tax_rate, unit_price, discount_amount, discount_percentage, sub_total, total_discount, total_tax, total_price ve itemable (id, name; kayıt silinmişse null).
Durum akışı
Tipik akış aşağıdadır. Zorunlu bir sıra yoktur.
- Oluştururken ve güncellerken
draft,sent,accepted,rejecteddeğerlerini verebilirsiniz.converteddeğerini API’ye veremezsiniz; yalnızca dönüştürme işlemi bu duruma geçirir. - Geçişler arasında bir doğrulama yoktur. Kilitli değilken
rejecteddurumundandraftdurumuna da dönebilirsiniz. acceptedveconvertedteklifler kilitlidir.PUTveDELETEistekleri422 OFFER_LOCKEDdöner. Kabul edilmiş bir teklifi API ile kilitten çıkaramazsınız.
Oluşturma
POST /v1/offers başarılı olunca 201 ve kalemleriyle birlikte teklifi döner.
integer
Hasta.
lead_id göndermiyorsanız zorunludur ve lead_id ile birlikte gönderilemez. Hasta kliniğe ait olmalıdır.integer
Lead.
customer_id göndermiyorsanız zorunludur. Görebildiğiniz bir lead olmalıdır. Lead dönüştürülmez; gerekirse lead aşamasında bir kişi kaydı oluşturulur ya da telefon numarasıyla mevcut kayıt kullanılır.integer
gerekli
Para birimi.
number
gerekli
Kur. 0 veya daha büyük olmalıdır.
string
gerekli
Geçerlilik tarihi. Saat dilimi vermezseniz kliniğin saat dilimi kabul edilir; yalnızca tarih verirseniz gün başlangıcı (
00:00) alınır.string
gerekli
draft, sent, accepted veya rejected.integer
Teklif sahibi. Kliniğin bir kullanıcısı olmalıdır.
string
Serbest not.
array
gerekli
En az bir kalem.
Kalemler
order, sub_total, total_discount, total_tax ve total_price alanlarını göndermeniz gerekmez. Gönderirseniz yok sayılır; sıra, istekteki kalem sırasına göre 0’dan başlar.
Toplamlar
Sunucu toplamları her yazmada yeniden hesaplar:sub_total = quantity × unit_pricetotal_discount = discount_amount + sub_total × discount_percentage / 100total_tax = (sub_total − total_discount) × tax_rate / 100. İndirim ara toplamı aşarsa vergi tabanı 0 olur.total_price = (sub_total − total_discount) + total_tax
Kalem seçenekleri
GET /v1/offers/options/products ve GET /v1/offers/options/treatments, teklif formundaki seçim listelerini besler. Yalnızca aktif kayıtları döndürür. Bu endpoint’ler View:Product veya View:Treatment izni gerektirmez; Create:Offer ya da Update:Offer yeterlidir. Parametreler: search, per_page (1–100, varsayılan 15), page ve ids[] (en fazla 100). ids[] verdiğinizde arama ve aktiflik süzgeci uygulanmaz; kayıtlı kalemleri etiketlemek için pasif kayıtlar da döner.
Katalog fiyatları vergi dahildir. Yanıttaki unit_price_excl_tax ve tax_rate değerlerini kalemde unit_price ve tax_rate olarak gönderin.
sub_total 1000, total_discount 100, total_tax 180 ve total_price 1080 olur.
Güncelleme
PUT /v1/offers/{id} kısmi güncellemedir; göndermediğiniz alanlar değişmez. items gönderirseniz mevcut kalemlerin tamamı yeni listeyle değiştirilir ve liste en az bir kalem içermelidir. items göndermezseniz kalemler korunur. notes ve user_id alanlarını null göndererek temizleyemezsiniz.
Teklifi çoğaltma
Çoğaltma için ayrı bir endpoint yoktur. Kopyayı kendiniz oluşturun: kaynak teklifiGET /v1/offers/{id} ile okuyun, kalemleri ve alanları POST /v1/offers gövdesine taşıyın ve status değerini draft yapın. Kopyaya valid_until için yeni bir tarih vermeniz iyi olur. Kaynak teklifi okumak için View:Offer, kopyayı oluşturmak için Create:Offer izni gerekir.
Silme
DELETE /v1/offers/{id} teklifi ve kalemlerini Geri Dönüşüm Kutusu’na taşır. Kilitli (accepted, converted) teklif silinemez. Bekleme süresi ve geri yükleme için Silme yaşam döngüsü sayfasına bakın.
POST /v1/offers/{id}/generate-pdf isteği işi kuyruğa alır ve hemen 202 döner. PDF A4 boyutundadır.
integer
İsteğe bağlı teklif şablonu kimliği. Vermezseniz kliniğin aktif şablonlarından varsayılan olanı kullanılır. Her yeni klinikte
Varsayılan Teklif Şablonu hazır gelir.curl
{"message": "Teklif PDF dosyası oluşturma işi kuyruğa alındı."}
Her üretim yeni bir dosya kaydı ekler; eski PDF’ler silinmez. Dosya adı offer - <hasta adı> - <teklif id> - <tarih_saat>.pdf biçimindedir. İş bitince isteği yapan kullanıcıya Dosya Yüklendi bildirimi gider. Üretim başarısız olursa bildirim gelmez, bu yüzden sonucu GET /v1/offers/{id}/pdfs ile kontrol edin.
GET /v1/offers/{id}/pdfs sayfalı döner (per_page 1–100, varsayılan 15; sort_order, created_at_from, created_at_to). Her kayıtta id, name, description, mime_type, size, source, created_at ve updated_at bulunur.
GET /v1/offers/{id}/pdfs/{fileId}/download-url kısa ömürlü bir bağlantı üretir.
Yanıt
url, expires_at (ISO 8601), disposition ve file alanlarını içerir. Dosya depolamadan kaybolmuşsa 404 OFFER_PDF_FILE_MISSING döner. DELETE /v1/offers/{id}/pdfs/{fileId} PDF’i kalıcı siler; teklif kilitli olsa bile çalışır.
Satışa dönüştürme
POST /v1/offers/{id}/convert teklifi, aynı kalemlerle yeni bir taslak satışa çevirir. İsteğin gövdesi yoktur. Token’ınızda hem offers:write hem sales:write scope’u, rolünüzde Convert:Offer izni olmalıdır. Update:Offer bu işlem için yeterli değildir.
Dönüştürme draft, sent ve accepted tekliflerde çalışır. Başarılı olunca 201 ve satış nesnesi döner; satışın status değeri draft olur. Teklif converted durumuna geçer ve sale_id alanı dolar.
- Satışa hasta, para birimi, kur ve notlar taşınır. Satışın sahibi, isteği yapan kullanıcı değil teklifin sahibidir.
- Her kalem sırası, miktarı, vergi oranı, fiyatı, indirimleri ve toplamlarıyla birebir kopyalanır. Ürün kalemlerinin maliyet fiyatı üründen alınır; tedavi kalemlerinde 0’dır.
- İkinci çağrı
422döner. Satış nesnesi için Satışlar sayfasına bakın.
curl
Hata kodları
Ortak kodlar için Hata kodları sayfasına bakın.