@@ -1,49 +1,40 @@
< template >
< q-page class = "ol-page" >
<!-- 🔍 Sticky Filter -- >
< q-page v-if = "canReadOrder" class= "ol-page">
< div class = "ol-filter-bar" >
<!-- 🔹 TEK SATIR FLEX -- >
< div class = "ol-filter-row" >
<!-- 🔍 Arama -- >
< q-input
v-model = "store.filters.search"
class = "ol-filter-input ol-search"
dense
filled
v-model = "store.filters.search"
label = "Arama (Sipariş No / Cari / Açı klama)"
debounce = "300"
clearable
label = "Arama (Sipariş No / Cari / Açı klama)"
>
< template # append >
< q-icon name = "search" / >
< / template >
< / q-input >
<!-- 🧾 Cari Kodu -- >
< q-input
class = "ol-filter-input"
dense
filled
v-model = "store.filters.CurrAccCode"
label = "Cari Kodu"
clearable
/ >
<!-- 📅 Sipariş Tarihi -- >
< q-input
class = "ol-filter-input"
dense
filled
v-model = "store.filters.OrderDate"
label = "Sipariş Tarihi "
type = "date"
clearable
label = "Cari Kodu "
/ >
<!-- 🔘 Butonlar -- >
< div class = "ol-filter-actions" >
< q-input
v-model = "store.filters.OrderDate"
class = "ol-filter-input"
dense
filled
type = "date"
label = "Sipariş Tarihi"
/ >
< div class = "ol-filter-actions" >
< q-btn
label = "Temizle"
icon = "clear"
@@ -52,9 +43,7 @@
:disable = "store.loading"
@click ="clearFilters"
>
< q-tooltip >
Tüm filtreleri temizle
< / q-tooltip >
< q-tooltip > Tüm filtreleri temizle < / q-tooltip >
< / q-btn >
< q-btn
@@ -73,25 +62,31 @@
: disable = "store.loading || store.filteredOrders.length === 0"
@click ="exportExcel"
/ >
< / div >
<!-- 💰 Toplam -- >
< div class = "ol-filter-total" >
Toplam Görünen Sipariş Tutarı ( USD ) :
< strong >
{ { store . totalVisibleUSD . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) } }
USD
< / strong >
< div class = "ol-total-line" >
< span class = "ol-total-label" > Toplam USD : < / span >
< strong class = "ol-total-value" >
{ { store . totalVisibleUSD . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 , maximumFractionDigits : 2 } ) } }
< / strong >
< / div >
< div class = "ol-total-line" >
< span class = "ol-total-label" > Paketlenen USD : < / span >
< strong class = "ol-total-value" >
{ { store . totalPackedVisibleUSD . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 , maximumFractionDigits : 2 } ) } }
< / strong >
< / div >
< div class = "ol-total-line" >
< span class = "ol-total-label" > Paketlenme % : < / span >
< strong class = "ol-total-value" :class = "packRateClass(store.packedVisibleRatePct)" >
{ { store . packedVisibleRatePct . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 , maximumFractionDigits : 2 } ) } }
< / strong >
< / div >
< / div >
< / div >
< / div >
<!-- 📋 ORDER LIST TABLE -- >
< q-table
title = "Mevcut Siparişler"
class = "ol-table"
@@ -107,11 +102,8 @@
:rows-per-page-options = "[0]"
hide -bottom
>
<!-- 📄 PDF + DURUM -- >
< template # body -cell -IsCreditableConfirmed = " props " >
< q-td :props = "props" class = "text-center q-gutter-sm" >
< q-btn
icon = "picture_as_pdf"
color = "red"
@@ -132,11 +124,9 @@
{ { props . row . IsCreditableConfirmed ? 'Onaylı ' : 'Onaysı z' } }
< / q-tooltip >
< / q-icon >
< / q-td >
< / template >
<!-- 📅 Tarih -- >
< template # body -cell -OrderDate = " props " >
< q-td :props = "props" class = "text-center" >
{ { formatDate ( props . row . OrderDate ) } }
@@ -149,27 +139,65 @@
< / q-td >
< / template >
<!-- 🧾 Cari Adı — 2 Satı r -- >
< template # body -cell -PackedAmount = " props " >
< q-td :props = "props" class = "text-right text-weight-medium" >
{ { Number ( props . row . PackedAmount || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) } }
{ { props . row . DocCurrencyCode } }
< / q-td >
< / template >
< template # body -cell -PackedUSD = " props " >
< q-td :props = "props" class = "text-right text-weight-medium" >
{ { Number ( props . row . PackedUSD || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) } } USD
< / q-td >
< / template >
< template # body -cell -PackedRatePct = " props " >
< q-td
:props = "props"
class = "text-right text-weight-bold ol-pack-rate-cell"
:class = "packRateClass(props.row.PackedRatePct)"
>
{ { Number ( props . row . PackedRatePct || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) } } %
< / q-td >
< / template >
< template # body -cell -CurrAccDescription = " props " >
< q-td :props = "props" class = "ol-col-cari ol-col-multiline " >
{ { props . value } }
< q-td :props = "props" class = "ol-col-cari" >
< div class = "ol-col-multiline" > {{ props . value } } < / div >
< q-tooltip v-if = "props.value" >
{{ props.value }}
< / q -tooltip >
< / q-td >
< / template >
< template # body -cell -MusteriTemsilcisi = " props " >
< q-td :props = "props" class = "ol-col-short" >
< div class = "ol-col-multiline" > { { props . value } } < / div >
< q-tooltip v-if = "props.value" >
{{ props.value }}
< / q -tooltip >
< / q-td >
< / template >
< template # body -cell -Piyasa = " props " >
< q-td :props = "props" class = "ol-col-short" >
< div class = "ol-col-multiline" > { { props . value } } < / div >
< q-tooltip v-if = "props.value" >
{{ props.value }}
< / q -tooltip >
< / q-td >
< / template >
<!-- 📝 Açı klama — 5 Satı r -- >
< template # body -cell -Description = " props " >
< q-td :props = "props" class = "ol-col-desc ol-col-multiline " >
{ { props . value } }
< q-td :props = "props" class = "ol-col-desc" >
< div class = "ol-col-multiline" > {{ props . value } } < / div >
< q-tooltip v-if = "props.value" >
{{ props.value }}
< / q -tooltip >
< / q-td >
< / template >
<!-- 🔗 Aç -- >
< template # body -cell -select = " props " >
< q-td :props = "props" class = "text-center" >
< q-btn
@@ -184,14 +212,17 @@
< / q-btn >
< / q-td >
< / template >
< / q-table >
<!-- ❌ HATA -- >
< q-banner v-if = "store.error" class="bg-red text-white q-mt-sm" >
❌ {{ store.error }}
Hata : {{ store.error }}
< / q -banner >
< / q-page >
< q-page v-else class = "q-pa-md flex flex-center" >
< div class = "text-negative text-subtitle1" >
Bu modüle erişim yetkiniz yok .
< / div >
< / q-page >
< / template >
@@ -199,47 +230,28 @@
import { onMounted , watch } from 'vue'
import { useRouter } from 'vue-router'
import { useQuasar } from 'quasar'
import { useOrderListStore } from 'src/stores/OrdernewListStore'
import { useAuthStore } from 'src/stores/authStore'
import { usePermission } from 'src/composables/usePermission'
const { canRead , canWrite , canUpdate } = usePermission ( )
const canReadOrder = canRead ( 'order' )
const canWriteOrder = canWrite ( 'order' )
const canUpdateOrder = canUpdate ( 'order' )
/* =========================
INIT
========================= */
const { canRead } = usePermission ( )
const canReadOrder = canRead ( 'order' )
const router = useRouter ( )
const $q = useQuasar ( )
// ⚠️ ÖNCE store tanı mlanı r
const store = useOrderListStore ( )
/* =========================
SEARCH DEBOUNCE
========================= */
let searchTimer = null
watch (
( ) => store . filters . search ,
( ) => {
clearTimeout ( searchTimer )
searchTimer = setTimeout ( ( ) => {
store . fetchOrders ( )
} , 400 )
}
)
/* =========================
HELPERS
========================= */
function exportExcel ( ) {
const auth = useAuthStore ( )
@@ -276,80 +288,85 @@ function exportExcel () {
function formatDate ( s ) {
if ( ! s ) return ''
const [ y , m , d ] = s . split ( '-' )
const [ y , m , d ] = String ( s ) . split ( '-' )
if ( ! y || ! m || ! d ) return s
return ` ${ d } . ${ m } . ${ y } `
}
/* =========================
TABLE COLUMNS
========================= */
function packRateClass ( value ) {
const pct = Number ( value || 0 )
if ( pct <= 50 ) return 'pack-rate-danger'
if ( pct < 100 ) return 'pack-rate-warn'
return 'pack-rate-ok'
}
const columns = [
{ name : 'select' , label : '' , field : 'select' , align : 'center' , sortable : false } ,
{ name : 'OrderNumber ' , label : 'Sipariş No ' , field : 'OrderNumber ' , align : 'left ' , sortable : true } ,
{ name : 'OrderDat e' , label : 'T arih ' , field : 'OrderDat e' , align : 'center ' , sortable : true } ,
{ name : 'CurrAccCode ' , label : 'Cari Kod ' , field : 'CurrAccCode ' , align : 'left' , sortable : true } ,
{
name : 'CurrAccDescription' ,
label : 'Cari Adı ' ,
field : 'CurrAccDescription' ,
align : 'left' ,
sortable : true ,
classes : 'ol-col-cari' ,
headerClasses : 'ol-col-cari' ,
style : 'max-width:200px'
} ,
{ name : 'MusteriTemsilcisi' , label : 'Temsilci' , field : 'MusteriTemsilcisi' , align : 'left' , sortable : true } ,
{ name : 'Piyasa' , label : 'Piyasa' , field : 'Piyasa' , align : 'left' , sortable : true } ,
{ name : 'CreditableConfirmedDate' , label : 'Onay' , field : 'CreditableConfirmedDate' , align : 'center' , sortable : true } ,
{ name : 'DocCurrencyCode' , label : 'PB' , field : 'DocCurrencyCode' , align : 'center' , sortable : true } ,
{ name : 'OrderNumber' , label : 'Sipariş No' , field : 'OrderNumber' , align : 'left' , sortable : true , style : 'min-width:108px;white-space:nowrap' , headerStyle : 'min-width:108px;white-space:nowrap' } ,
{ name : 'OrderDate ' , label : 'Tarih ' , field : 'OrderDate ' , align : 'center ' , sortable : true , style : 'min-width:82px;white-space:nowrap' , headerStyle : 'min-width:82px;white-space:nowrap' } ,
{ name : 'CurrAccCod e' , label : 'C ari Kod ' , field : 'CurrAccCod e' , align : 'left ' , sortable : true , style : 'min-width:82px;white-space:nowrap' , headerStyle : 'min-width:82px;white-space:nowrap' } ,
{ name : 'CurrAccDescription' , label : 'Cari Adı ' , field : 'CurrAccDescription' , align : 'left' , sortable : true , classes : 'ol-col-cari' , headerClasses : 'ol-col-cari' , style : 'width:160px;max-width:160px' , headerStyle : 'width:160px;max-width:160px' } ,
{ name : 'MusteriTemsilcisi ' , label : 'Temsilci ' , field : 'MusteriTemsilcisi ' , align : 'left' , sortable : true , classes : 'ol-col-short' , headerClasses : 'ol-col-short' , style : 'width:88px;max-width:88px' , headerStyle : 'width:88px;max-width:88px' } ,
{ name : 'Piyasa' , label : 'Piyasa' , field : 'Piyasa' , align : 'left' , sortable : true , classes : 'ol-col-short' , headerClasses : 'ol-col-short' , style : 'width:72px;max-width:72px' , headerStyle : 'width:72px;max-width:72px' } ,
{ name : 'CreditableConfirmedDate' , label : 'Onay' , field : 'CreditableConfirmedDate' , align : 'center' , sortable : true , style : 'min-width:86px;white-space:nowrap' , headerStyle : 'min-width:86px;white-space:nowrap' } ,
{ name : 'Doc CurrencyCode' , label : 'PB' , field : 'DocCurrencyCode' , align : 'center' , sortable : true , style : 'min-width:46px;white-space:nowrap' , headerStyle : 'min-width:46px;white-space:nowrap' } ,
{
name : 'TotalAmount' ,
label : 'Tutar' ,
field : 'TotalAmount' ,
align : 'right' ,
sortable : true ,
format : ( val , row ) =>
Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) +
' ' + row . DocCurrencyCode
style : 'min-width:120px;white-space:nowrap' ,
headerStyle : 'min-width:120px;white-space:nowrap' ,
format : ( val , row ) => Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) + ' ' + row . DocCurrencyCode
} ,
{
name : 'TotalAmountUSD' ,
label : 'Tutar (USD)' ,
field : 'TotalAmountUSD' ,
align : 'right' ,
sortable : true ,
format : val =>
Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) + ' USD'
style : 'min-width:120px;white-space:nowrap' ,
headerStyle : 'min-width:120px;white-space:nowrap' ,
format : val => Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) + ' USD'
} ,
{ name : 'IsCreditableConfirmed' , label : 'Durum' , field : 'IsCreditableConfirmed' , align : 'center' , sortable : true } ,
{
name : 'Description ' ,
label : 'Açı klama ' ,
field : 'Description ' ,
align : 'lef t' ,
sortable : fals e,
classes : 'ol-col-desc ',
headerClasses : 'ol-col-desc ' ,
style : 'max-width:220px'
name : 'PackedAmount ' ,
label : 'Paketlenen ' ,
field : 'PackedAmount ' ,
align : 'righ t' ,
sortable : tru e,
style : 'min-width:120px;white-space:nowrap ',
headerStyle : 'min-width:120px;white-space:nowrap ' ,
format : ( val , row ) => Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) + ' ' + row . DocCurrencyCode
} ,
{
name : 'PackedUSD' ,
label : 'Paketlenen (USD)' ,
field : 'PackedUSD' ,
align : 'right' ,
sortable : true ,
style : 'min-width:120px;white-space:nowrap' ,
headerStyle : 'min-width:120px;white-space:nowrap' ,
format : val => Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) + ' USD'
} ,
{
name : 'PackedRatePct' ,
label : 'Paketlenme %' ,
field : 'PackedRatePct' ,
align : 'right' ,
sortable : true ,
classes : 'ol-pack-rate-cell' ,
headerClasses : 'ol-pack-rate-cell' ,
style : 'min-width:96px;white-space:nowrap' ,
headerStyle : 'min-width:96px;white-space:nowrap' ,
format : val => Number ( val || 0 ) . toLocaleString ( 'tr-TR' , { minimumFractionDigits : 2 } ) + ' %'
} ,
{ name : 'IsCreditableConfirmed' , label : 'Durum' , field : 'IsCreditableConfirmed' , align : 'center' , sortable : true } ,
{ name : 'Description' , label : 'Açı klama' , field : 'Description' , align : 'left' , sortable : false , classes : 'ol-col-desc' , headerClasses : 'ol-col-desc' , style : 'width:160px;max-width:160px' , headerStyle : 'width:160px;max-width:160px' } ,
{ name : 'pdf' , label : 'PDF' , field : 'pdf' , align : 'center' , sortable : false }
]
/* =========================
ACTIONS
========================= */
function selectOrder ( row ) {
if ( ! row ? . OrderHeaderID ) {
$q . notify ( { type : 'warning' , message : 'OrderHeaderID bulunamadı ' } )
@@ -397,12 +414,151 @@ function clearFilters () {
} )
}
/* =========================
INIT LOAD
========================= */
onMounted ( ( ) => {
store . fetchOrders ( )
} )
< / script >
< style scoped >
. ol - page {
padding : 10 px ;
}
. ol - filter - bar {
margin - bottom : 8 px ;
}
. ol - filter - row {
display : flex ;
flex - wrap : nowrap ;
gap : 10 px ;
align - items : center ;
}
. ol - filter - input {
min - width : 118 px ;
width : 136 px ;
flex : 0 0 136 px ;
}
. ol - search {
min - width : 240 px ;
max - width : 420 px ;
flex : 1 1 360 px ;
}
. ol - filter - actions {
display : flex ;
gap : 8 px ;
flex - wrap : nowrap ;
flex : 0 0 auto ;
}
. ol - filter - total {
margin - left : auto ;
display : flex ;
flex - direction : column ;
align - items : flex - end ;
justify - content : center ;
gap : 2 px ;
min - width : 250 px ;
line - height : 1.2 ;
flex : 0 0 auto ;
align - self : center ;
}
. ol - total - line {
display : flex ;
align - items : baseline ;
gap : 8 px ;
white - space : nowrap ;
}
. ol - total - label {
font - size : 12 px ;
color : # 4 b5563 ;
}
. ol - total - value {
font - size : 13 px ;
}
. ol - table : deep ( . q - table thead th ) {
font - size : 11 px ;
padding : 4 px 6 px ;
white - space : nowrap ;
}
. ol - table : deep ( . q - table tbody td ) {
font - size : 11 px ;
padding : 3 px 6 px ;
}
. ol - col - multiline {
display : block ;
white - space : normal ! important ;
word - break : break - word ;
line - height : 1.15 ;
overflow : hidden ;
text - overflow : ellipsis ;
display : - webkit - box ;
- webkit - box - orient : vertical ;
- webkit - line - clamp : 2 ;
max - height : 2.35 em ;
}
. ol - col - cari {
max - width : 160 px ;
}
. ol - col - short {
max - width : 88 px ;
}
. ol - col - desc {
max - width : 160 px ;
}
. ol - pack - rate - cell {
font - weight : 700 ;
}
. pack - rate - danger {
color : # c62828 ;
}
. pack - rate - warn {
color : # 8 a6d00 ;
}
. pack - rate - ok {
color : # 1 f7a4f ;
}
@ media ( max - width : 1440 px ) {
. ol - filter - row {
flex - wrap : wrap ;
align - items : flex - start ;
}
. ol - filter - actions {
flex - wrap : wrap ;
}
. ol - filter - input {
flex : 1 1 140 px ;
}
. ol - filter - total {
min - width : 100 % ;
margin - left : 0 ;
align - items : flex - start ;
margin - top : 6 px ;
}
. ol - total - line {
width : 100 % ;
justify - content : space - between ;
}
}
< / style >