Merge remote-tracking branch 'origin/master'
# Conflicts: # ui/src/pages/OrderList.vue
This commit is contained in:
@@ -262,6 +262,11 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router
|
|||||||
rdPerm := "/api/roles/{roleId}/departments/{deptCode}/permissions"
|
rdPerm := "/api/roles/{roleId}/departments/{deptCode}/permissions"
|
||||||
rdHandler := routes.NewRoleDepartmentPermissionHandler(pgDB)
|
rdHandler := routes.NewRoleDepartmentPermissionHandler(pgDB)
|
||||||
|
|
||||||
|
bindV3(r, pgDB,
|
||||||
|
"/api/role-dept-permissions/list", "GET",
|
||||||
|
"user", "update",
|
||||||
|
wrapV3(http.HandlerFunc(rdHandler.List)),
|
||||||
|
)
|
||||||
bindV3(r, pgDB,
|
bindV3(r, pgDB,
|
||||||
rdPerm, "GET",
|
rdPerm, "GET",
|
||||||
"user", "update",
|
"user", "update",
|
||||||
@@ -407,6 +412,8 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router
|
|||||||
{"/api/order/update", "POST", "update", http.HandlerFunc(routes.UpdateOrderHandler)},
|
{"/api/order/update", "POST", "update", http.HandlerFunc(routes.UpdateOrderHandler)},
|
||||||
{"/api/order/get/{id}", "GET", "view", routes.GetOrderByIDHandler(mssql)},
|
{"/api/order/get/{id}", "GET", "view", routes.GetOrderByIDHandler(mssql)},
|
||||||
{"/api/orders/list", "GET", "view", routes.OrderListRoute(mssql)},
|
{"/api/orders/list", "GET", "view", routes.OrderListRoute(mssql)},
|
||||||
|
{"/api/orders/close-ready", "GET", "update", routes.OrderCloseReadyListRoute(mssql)},
|
||||||
|
{"/api/orders/bulk-close", "POST", "update", routes.OrderBulkCloseRoute(mssql)},
|
||||||
{"/api/orders/export", "GET", "export", routes.OrderListExcelRoute(mssql)},
|
{"/api/orders/export", "GET", "export", routes.OrderListExcelRoute(mssql)},
|
||||||
{"/api/order/check/{id}", "GET", "view", routes.OrderExistsHandler(mssql)},
|
{"/api/order/check/{id}", "GET", "view", routes.OrderExistsHandler(mssql)},
|
||||||
{"/api/order/validate", "POST", "insert", routes.ValidateOrderHandler(mssql)},
|
{"/api/order/validate", "POST", "insert", routes.ValidateOrderHandler(mssql)},
|
||||||
|
|||||||
@@ -34,6 +34,67 @@ DO UPDATE SET
|
|||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
|
// LIST (role+department sets with summary)
|
||||||
|
const ListRoleDepartmentPermissionSets = `
|
||||||
|
WITH role_dept AS (
|
||||||
|
SELECT DISTINCT
|
||||||
|
p.role_id,
|
||||||
|
p.department_code
|
||||||
|
FROM mk_sys_role_department_permissions p
|
||||||
|
),
|
||||||
|
base AS (
|
||||||
|
SELECT
|
||||||
|
rd.role_id,
|
||||||
|
COALESCE(NULLIF(r.title, ''), r.code, rd.role_id::text) AS role_title,
|
||||||
|
rd.department_code,
|
||||||
|
COALESCE(d.title, rd.department_code) AS department_title
|
||||||
|
FROM role_dept rd
|
||||||
|
LEFT JOIN dfrole r
|
||||||
|
ON r.id = rd.role_id
|
||||||
|
LEFT JOIN mk_dprt d
|
||||||
|
ON d.code = rd.department_code
|
||||||
|
WHERE
|
||||||
|
($1 = '' OR
|
||||||
|
COALESCE(NULLIF(r.title, ''), r.code, '') ILIKE '%' || $1 || '%' OR
|
||||||
|
COALESCE(d.title, '') ILIKE '%' || $1 || '%' OR
|
||||||
|
rd.department_code ILIKE '%' || $1 || '%' OR
|
||||||
|
rd.role_id::text ILIKE '%' || $1 || '%')
|
||||||
|
),
|
||||||
|
perm_agg AS (
|
||||||
|
SELECT
|
||||||
|
p.role_id,
|
||||||
|
p.department_code,
|
||||||
|
LOWER(p.module_code) AS module_code,
|
||||||
|
LOWER(p.action) AS action,
|
||||||
|
BOOL_OR(p.allowed) AS has_allowed
|
||||||
|
FROM mk_sys_role_department_permissions p
|
||||||
|
GROUP BY
|
||||||
|
p.role_id,
|
||||||
|
p.department_code,
|
||||||
|
LOWER(p.module_code),
|
||||||
|
LOWER(p.action)
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
b.role_id,
|
||||||
|
b.role_title,
|
||||||
|
b.department_code,
|
||||||
|
b.department_title,
|
||||||
|
COALESCE(
|
||||||
|
(
|
||||||
|
SELECT jsonb_object_agg(pa.module_code || '|' || pa.action, pa.has_allowed)
|
||||||
|
FROM perm_agg pa
|
||||||
|
WHERE
|
||||||
|
pa.role_id = b.role_id
|
||||||
|
AND pa.department_code = b.department_code
|
||||||
|
),
|
||||||
|
'{}'::jsonb
|
||||||
|
) AS module_flags
|
||||||
|
FROM base b
|
||||||
|
ORDER BY
|
||||||
|
b.role_title,
|
||||||
|
b.department_title
|
||||||
|
`
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
// 📦 MODULES
|
// 📦 MODULES
|
||||||
// ======================================================
|
// ======================================================
|
||||||
@@ -45,3 +106,20 @@ SELECT
|
|||||||
FROM mk_sys_modules
|
FROM mk_sys_modules
|
||||||
ORDER BY id
|
ORDER BY id
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const GetModuleActionLookup = `
|
||||||
|
SELECT DISTINCT
|
||||||
|
LOWER(x.module_code) AS module_code,
|
||||||
|
LOWER(x.action) AS action
|
||||||
|
FROM (
|
||||||
|
SELECT module_code, action FROM mk_sys_routes
|
||||||
|
UNION ALL
|
||||||
|
SELECT module_code, action FROM mk_sys_role_department_permissions
|
||||||
|
) x
|
||||||
|
WHERE
|
||||||
|
x.module_code IS NOT NULL
|
||||||
|
AND x.action IS NOT NULL
|
||||||
|
ORDER BY
|
||||||
|
LOWER(x.module_code),
|
||||||
|
LOWER(x.action)
|
||||||
|
`
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
@@ -24,6 +25,30 @@ type Row struct {
|
|||||||
CanAccess bool `json:"can_access"`
|
CanAccess bool `json:"can_access"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RoleDeptPermissionSummary struct {
|
||||||
|
RoleID int `json:"role_id"`
|
||||||
|
RoleTitle string `json:"role_title"`
|
||||||
|
DepartmentCode string `json:"department_code"`
|
||||||
|
DepartmentTitle string `json:"department_title"`
|
||||||
|
ModuleFlags map[string]bool `json:"module_flags"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModuleLookupOption struct {
|
||||||
|
Value string `json:"value"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModuleActionLookupOption struct {
|
||||||
|
ModuleCode string `json:"module_code"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoleDeptPermissionListResponse struct {
|
||||||
|
Modules []ModuleLookupOption `json:"modules"`
|
||||||
|
ModuleActions []ModuleActionLookupOption `json:"module_actions"`
|
||||||
|
Rows []RoleDeptPermissionSummary `json:"rows"`
|
||||||
|
}
|
||||||
|
|
||||||
type RoleDepartmentPermissionHandler struct {
|
type RoleDepartmentPermissionHandler struct {
|
||||||
DB *sql.DB
|
DB *sql.DB
|
||||||
Repo *permissions.RoleDepartmentPermissionRepo
|
Repo *permissions.RoleDepartmentPermissionRepo
|
||||||
@@ -37,6 +62,109 @@ func NewRoleDepartmentPermissionHandler(db *sql.DB) *RoleDepartmentPermissionHan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ======================================================
|
||||||
|
LIST
|
||||||
|
====================================================== */
|
||||||
|
|
||||||
|
func (h *RoleDepartmentPermissionHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
claims, ok := auth.GetClaimsFromContext(r.Context())
|
||||||
|
if !ok || claims == nil {
|
||||||
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
search := strings.TrimSpace(r.URL.Query().Get("search"))
|
||||||
|
|
||||||
|
modRows, err := h.DB.Query(queries.GetModuleLookup)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "module lookup error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer modRows.Close()
|
||||||
|
|
||||||
|
modules := make([]ModuleLookupOption, 0, 32)
|
||||||
|
for modRows.Next() {
|
||||||
|
var m ModuleLookupOption
|
||||||
|
if err := modRows.Scan(&m.Value, &m.Label); err != nil {
|
||||||
|
http.Error(w, "module lookup scan error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
modules = append(modules, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := modRows.Err(); err != nil {
|
||||||
|
http.Error(w, "module lookup rows error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actionRows, err := h.DB.Query(queries.GetModuleActionLookup)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "module action lookup error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer actionRows.Close()
|
||||||
|
|
||||||
|
moduleActions := make([]ModuleActionLookupOption, 0, 128)
|
||||||
|
for actionRows.Next() {
|
||||||
|
var a ModuleActionLookupOption
|
||||||
|
if err := actionRows.Scan(&a.ModuleCode, &a.Action); err != nil {
|
||||||
|
http.Error(w, "module action scan error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
moduleActions = append(moduleActions, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := actionRows.Err(); err != nil {
|
||||||
|
http.Error(w, "module action rows error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := h.DB.Query(queries.ListRoleDepartmentPermissionSets, search)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "db error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
list := make([]RoleDeptPermissionSummary, 0, 128)
|
||||||
|
for rows.Next() {
|
||||||
|
var item RoleDeptPermissionSummary
|
||||||
|
var rawFlags []byte
|
||||||
|
if err := rows.Scan(
|
||||||
|
&item.RoleID,
|
||||||
|
&item.RoleTitle,
|
||||||
|
&item.DepartmentCode,
|
||||||
|
&item.DepartmentTitle,
|
||||||
|
&rawFlags,
|
||||||
|
); err != nil {
|
||||||
|
http.Error(w, "scan error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
item.ModuleFlags = map[string]bool{}
|
||||||
|
if len(rawFlags) > 0 {
|
||||||
|
if err := json.Unmarshal(rawFlags, &item.ModuleFlags); err != nil {
|
||||||
|
http.Error(w, "module flags parse error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = append(list, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
http.Error(w, "rows error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
_ = json.NewEncoder(w).Encode(RoleDeptPermissionListResponse{
|
||||||
|
Modules: modules,
|
||||||
|
ModuleActions: moduleActions,
|
||||||
|
Rows: list,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/* ======================================================
|
/* ======================================================
|
||||||
GET
|
GET
|
||||||
====================================================== */
|
====================================================== */
|
||||||
|
|||||||
@@ -208,6 +208,11 @@ const menuItems = [
|
|||||||
label: 'Siparişler',
|
label: 'Siparişler',
|
||||||
to: '/app/order-gateway',
|
to: '/app/order-gateway',
|
||||||
permission: 'order:view'
|
permission: 'order:view'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Tamamlanan Siparişleri Toplu Kapatma',
|
||||||
|
to: '/app/order-bulk-close',
|
||||||
|
permission: 'order:update'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -57,6 +57,13 @@
|
|||||||
label="MEVCUT SİPARİŞİ AÇ"
|
label="MEVCUT SİPARİŞİ AÇ"
|
||||||
@click="goOrderList"
|
@click="goOrderList"
|
||||||
/>
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="canUpdateOrder"
|
||||||
|
color="negative"
|
||||||
|
icon="task_alt"
|
||||||
|
label="TAMAMLANANLARI TOPLU KAPAT"
|
||||||
|
@click="goBulkClose"
|
||||||
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -80,10 +87,11 @@ import { useQuasar } from 'quasar'
|
|||||||
import { useOrderEntryStore } from 'src/stores/orderentryStore'
|
import { useOrderEntryStore } from 'src/stores/orderentryStore'
|
||||||
import { usePermission } from 'src/composables/usePermission'
|
import { usePermission } from 'src/composables/usePermission'
|
||||||
|
|
||||||
const { canRead, canWrite } = usePermission()
|
const { canRead, canWrite, canUpdate } = usePermission()
|
||||||
|
|
||||||
const canReadOrder = canRead('order')
|
const canReadOrder = canRead('order')
|
||||||
const canWriteOrder = canWrite('order')
|
const canWriteOrder = canWrite('order')
|
||||||
|
const canUpdateOrder = canUpdate('order')
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const $q = useQuasar()
|
const $q = useQuasar()
|
||||||
@@ -182,6 +190,10 @@ function goOrderList () {
|
|||||||
router.push({ name: 'order-list' })
|
router.push({ name: 'order-list' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goBulkClose () {
|
||||||
|
router.push({ name: 'order-bulk-close' })
|
||||||
|
}
|
||||||
|
|
||||||
/* ===========================================================
|
/* ===========================================================
|
||||||
🧹 NEW Taslağı Temizle (SADECE NEW)
|
🧹 NEW Taslağı Temizle (SADECE NEW)
|
||||||
=========================================================== */
|
=========================================================== */
|
||||||
|
|||||||
@@ -1,49 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-page class="ol-page">
|
<q-page v-if="canReadOrder" class="ol-page">
|
||||||
<!-- 🔍 Sticky Filter -->
|
|
||||||
<div class="ol-filter-bar">
|
<div class="ol-filter-bar">
|
||||||
|
|
||||||
<!-- 🔹 TEK SATIR FLEX -->
|
|
||||||
<div class="ol-filter-row">
|
<div class="ol-filter-row">
|
||||||
|
|
||||||
<!-- 🔍 Arama -->
|
|
||||||
<q-input
|
<q-input
|
||||||
|
v-model="store.filters.search"
|
||||||
class="ol-filter-input ol-search"
|
class="ol-filter-input ol-search"
|
||||||
dense
|
dense
|
||||||
filled
|
filled
|
||||||
v-model="store.filters.search"
|
|
||||||
label="Arama (Sipariş No / Cari / Açıklama)"
|
|
||||||
debounce="300"
|
debounce="300"
|
||||||
clearable
|
clearable
|
||||||
|
label="Arama (Sipariş No / Cari / Açıklama)"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<q-icon name="search" />
|
<q-icon name="search" />
|
||||||
</template>
|
</template>
|
||||||
</q-input>
|
</q-input>
|
||||||
|
|
||||||
<!-- 🧾 Cari Kodu -->
|
|
||||||
<q-input
|
<q-input
|
||||||
class="ol-filter-input"
|
|
||||||
dense
|
|
||||||
filled
|
|
||||||
v-model="store.filters.CurrAccCode"
|
v-model="store.filters.CurrAccCode"
|
||||||
label="Cari Kodu"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 📅 Sipariş Tarihi -->
|
|
||||||
<q-input
|
|
||||||
class="ol-filter-input"
|
class="ol-filter-input"
|
||||||
dense
|
dense
|
||||||
filled
|
filled
|
||||||
v-model="store.filters.OrderDate"
|
clearable
|
||||||
label="Sipariş Tarihi"
|
label="Cari Kodu"
|
||||||
type="date"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 🔘 Butonlar -->
|
<q-input
|
||||||
<div class="ol-filter-actions">
|
v-model="store.filters.OrderDate"
|
||||||
|
class="ol-filter-input"
|
||||||
|
dense
|
||||||
|
filled
|
||||||
|
type="date"
|
||||||
|
label="Sipariş Tarihi"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="ol-filter-actions">
|
||||||
<q-btn
|
<q-btn
|
||||||
label="Temizle"
|
label="Temizle"
|
||||||
icon="clear"
|
icon="clear"
|
||||||
@@ -52,9 +43,7 @@
|
|||||||
:disable="store.loading"
|
:disable="store.loading"
|
||||||
@click="clearFilters"
|
@click="clearFilters"
|
||||||
>
|
>
|
||||||
<q-tooltip>
|
<q-tooltip>Tüm filtreleri temizle</q-tooltip>
|
||||||
Tüm filtreleri temizle
|
|
||||||
</q-tooltip>
|
|
||||||
</q-btn>
|
</q-btn>
|
||||||
|
|
||||||
<q-btn
|
<q-btn
|
||||||
@@ -73,25 +62,31 @@
|
|||||||
:disable="store.loading || store.filteredOrders.length === 0"
|
:disable="store.loading || store.filteredOrders.length === 0"
|
||||||
@click="exportExcel"
|
@click="exportExcel"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 💰 Toplam -->
|
|
||||||
<div class="ol-filter-total">
|
<div class="ol-filter-total">
|
||||||
Toplam Görünen Sipariş Tutarı (USD):
|
<div class="ol-total-line">
|
||||||
<strong>
|
<span class="ol-total-label">Toplam USD:</span>
|
||||||
{{ store.totalVisibleUSD.toLocaleString('tr-TR', { minimumFractionDigits: 2 }) }}
|
<strong class="ol-total-value">
|
||||||
USD
|
{{ store.totalVisibleUSD.toLocaleString('tr-TR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }}
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 📋 ORDER LIST TABLE -->
|
|
||||||
<q-table
|
<q-table
|
||||||
title="Mevcut Siparişler"
|
title="Mevcut Siparişler"
|
||||||
class="ol-table"
|
class="ol-table"
|
||||||
@@ -107,11 +102,8 @@
|
|||||||
:rows-per-page-options="[0]"
|
:rows-per-page-options="[0]"
|
||||||
hide-bottom
|
hide-bottom
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- 📄 PDF + DURUM -->
|
|
||||||
<template #body-cell-IsCreditableConfirmed="props">
|
<template #body-cell-IsCreditableConfirmed="props">
|
||||||
<q-td :props="props" class="text-center q-gutter-sm">
|
<q-td :props="props" class="text-center q-gutter-sm">
|
||||||
|
|
||||||
<q-btn
|
<q-btn
|
||||||
icon="picture_as_pdf"
|
icon="picture_as_pdf"
|
||||||
color="red"
|
color="red"
|
||||||
@@ -132,11 +124,9 @@
|
|||||||
{{ props.row.IsCreditableConfirmed ? 'Onaylı' : 'Onaysız' }}
|
{{ props.row.IsCreditableConfirmed ? 'Onaylı' : 'Onaysız' }}
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
</q-icon>
|
</q-icon>
|
||||||
|
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 📅 Tarih -->
|
|
||||||
<template #body-cell-OrderDate="props">
|
<template #body-cell-OrderDate="props">
|
||||||
<q-td :props="props" class="text-center">
|
<q-td :props="props" class="text-center">
|
||||||
{{ formatDate(props.row.OrderDate) }}
|
{{ formatDate(props.row.OrderDate) }}
|
||||||
@@ -149,27 +139,65 @@
|
|||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</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">
|
<template #body-cell-CurrAccDescription="props">
|
||||||
<q-td :props="props" class="ol-col-cari ol-col-multiline">
|
<q-td :props="props" class="ol-col-cari">
|
||||||
{{ props.value }}
|
<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">
|
<q-tooltip v-if="props.value">
|
||||||
{{ props.value }}
|
{{ props.value }}
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 📝 Açıklama — 5 Satır -->
|
|
||||||
<template #body-cell-Description="props">
|
<template #body-cell-Description="props">
|
||||||
<q-td :props="props" class="ol-col-desc ol-col-multiline">
|
<q-td :props="props" class="ol-col-desc">
|
||||||
{{ props.value }}
|
<div class="ol-col-multiline">{{ props.value }}</div>
|
||||||
<q-tooltip v-if="props.value">
|
<q-tooltip v-if="props.value">
|
||||||
{{ props.value }}
|
{{ props.value }}
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 🔗 Aç -->
|
|
||||||
<template #body-cell-select="props">
|
<template #body-cell-select="props">
|
||||||
<q-td :props="props" class="text-center">
|
<q-td :props="props" class="text-center">
|
||||||
<q-btn
|
<q-btn
|
||||||
@@ -184,14 +212,17 @@
|
|||||||
</q-btn>
|
</q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</q-table>
|
</q-table>
|
||||||
|
|
||||||
<!-- ❌ HATA -->
|
|
||||||
<q-banner v-if="store.error" class="bg-red text-white q-mt-sm">
|
<q-banner v-if="store.error" class="bg-red text-white q-mt-sm">
|
||||||
❌ {{ store.error }}
|
Hata: {{ store.error }}
|
||||||
</q-banner>
|
</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>
|
</q-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -199,47 +230,28 @@
|
|||||||
import { onMounted, watch } from 'vue'
|
import { onMounted, watch } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useQuasar } from 'quasar'
|
import { useQuasar } from 'quasar'
|
||||||
|
|
||||||
import { useOrderListStore } from 'src/stores/OrdernewListStore'
|
import { useOrderListStore } from 'src/stores/OrdernewListStore'
|
||||||
import { useAuthStore } from 'src/stores/authStore'
|
import { useAuthStore } from 'src/stores/authStore'
|
||||||
import { usePermission } from 'src/composables/usePermission'
|
import { usePermission } from 'src/composables/usePermission'
|
||||||
|
|
||||||
const { canRead, canWrite, canUpdate } = usePermission()
|
const { canRead } = usePermission()
|
||||||
|
|
||||||
const canReadOrder = canRead('order')
|
const canReadOrder = canRead('order')
|
||||||
const canWriteOrder = canWrite('order')
|
|
||||||
const canUpdateOrder = canUpdate('order')
|
|
||||||
|
|
||||||
/* =========================
|
|
||||||
INIT
|
|
||||||
========================= */
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const $q = useQuasar()
|
const $q = useQuasar()
|
||||||
|
|
||||||
// ⚠️ ÖNCE store tanımlanır
|
|
||||||
const store = useOrderListStore()
|
const store = useOrderListStore()
|
||||||
|
|
||||||
/* =========================
|
|
||||||
SEARCH DEBOUNCE
|
|
||||||
========================= */
|
|
||||||
|
|
||||||
let searchTimer = null
|
let searchTimer = null
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => store.filters.search,
|
() => store.filters.search,
|
||||||
() => {
|
() => {
|
||||||
clearTimeout(searchTimer)
|
clearTimeout(searchTimer)
|
||||||
|
|
||||||
searchTimer = setTimeout(() => {
|
searchTimer = setTimeout(() => {
|
||||||
store.fetchOrders()
|
store.fetchOrders()
|
||||||
}, 400)
|
}, 400)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
/* =========================
|
|
||||||
HELPERS
|
|
||||||
========================= */
|
|
||||||
function exportExcel () {
|
function exportExcel () {
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
|
|
||||||
@@ -276,80 +288,85 @@ function exportExcel () {
|
|||||||
|
|
||||||
function formatDate (s) {
|
function formatDate (s) {
|
||||||
if (!s) return ''
|
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}`
|
return `${d}.${m}.${y}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================
|
function packRateClass (value) {
|
||||||
TABLE COLUMNS
|
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 = [
|
const columns = [
|
||||||
{ name: 'select', label: '', field: 'select', align: 'center', sortable: false },
|
{ name: 'select', label: '', field: 'select', align: 'center', sortable: false },
|
||||||
|
{ 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: 'OrderNumber', label: 'Sipariş No', field: 'OrderNumber', align: 'left', sortable: true },
|
{ 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: 'OrderDate', label: 'Tarih', field: 'OrderDate', align: 'center', sortable: true },
|
{ name: 'CurrAccCode', label: 'Cari Kod', field: 'CurrAccCode', 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: 'CurrAccCode', label: 'Cari Kod', field: 'CurrAccCode', align: 'left', sortable: true },
|
{ 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: 'CurrAccDescription',
|
{ name: 'DocCurrencyCode', label: 'PB', field: 'DocCurrencyCode', align: 'center', sortable: true, style: 'min-width:46px;white-space:nowrap', headerStyle: 'min-width:46px;white-space:nowrap' },
|
||||||
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: 'TotalAmount',
|
name: 'TotalAmount',
|
||||||
label: 'Tutar',
|
label: 'Tutar',
|
||||||
field: 'TotalAmount',
|
field: 'TotalAmount',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
format: (val, row) =>
|
style: 'min-width:120px;white-space:nowrap',
|
||||||
Number(val || 0).toLocaleString('tr-TR', { minimumFractionDigits: 2 }) +
|
headerStyle: 'min-width:120px;white-space:nowrap',
|
||||||
' ' + row.DocCurrencyCode
|
format: (val, row) => Number(val || 0).toLocaleString('tr-TR', { minimumFractionDigits: 2 }) + ' ' + row.DocCurrencyCode
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'TotalAmountUSD',
|
name: 'TotalAmountUSD',
|
||||||
label: 'Tutar (USD)',
|
label: 'Tutar (USD)',
|
||||||
field: 'TotalAmountUSD',
|
field: 'TotalAmountUSD',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
sortable: true,
|
sortable: true,
|
||||||
format: val =>
|
style: 'min-width:120px;white-space:nowrap',
|
||||||
Number(val || 0).toLocaleString('tr-TR', { minimumFractionDigits: 2 }) + ' USD'
|
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',
|
name: 'PackedAmount',
|
||||||
label: 'Açıklama',
|
label: 'Paketlenen',
|
||||||
field: 'Description',
|
field: 'PackedAmount',
|
||||||
align: 'left',
|
align: 'right',
|
||||||
sortable: false,
|
sortable: true,
|
||||||
classes: 'ol-col-desc',
|
style: 'min-width:120px;white-space:nowrap',
|
||||||
headerClasses: 'ol-col-desc',
|
headerStyle: 'min-width:120px;white-space:nowrap',
|
||||||
style: 'max-width:220px'
|
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 }
|
{ name: 'pdf', label: 'PDF', field: 'pdf', align: 'center', sortable: false }
|
||||||
]
|
]
|
||||||
|
|
||||||
/* =========================
|
|
||||||
ACTIONS
|
|
||||||
========================= */
|
|
||||||
|
|
||||||
function selectOrder (row) {
|
function selectOrder (row) {
|
||||||
if (!row?.OrderHeaderID) {
|
if (!row?.OrderHeaderID) {
|
||||||
$q.notify({ type: 'warning', message: 'OrderHeaderID bulunamadı' })
|
$q.notify({ type: 'warning', message: 'OrderHeaderID bulunamadı' })
|
||||||
@@ -397,12 +414,151 @@ function clearFilters () {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================
|
|
||||||
INIT LOAD
|
|
||||||
========================= */
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.fetchOrders()
|
store.fetchOrders()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.ol-page {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-bar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-input {
|
||||||
|
min-width: 118px;
|
||||||
|
width: 136px;
|
||||||
|
flex: 0 0 136px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-search {
|
||||||
|
min-width: 240px;
|
||||||
|
max-width: 420px;
|
||||||
|
flex: 1 1 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
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: 2px;
|
||||||
|
min-width: 250px;
|
||||||
|
line-height: 1.2;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-total-line {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-total-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-total-value {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-table :deep(.q-table thead th) {
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 4px 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-table :deep(.q-table tbody td) {
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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.35em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-col-cari {
|
||||||
|
max-width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-col-short {
|
||||||
|
max-width: 88px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-col-desc {
|
||||||
|
max-width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-pack-rate-cell {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pack-rate-danger {
|
||||||
|
color: #c62828;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pack-rate-warn {
|
||||||
|
color: #8a6d00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pack-rate-ok {
|
||||||
|
color: #1f7a4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1440px) {
|
||||||
|
.ol-filter-row {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-actions {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-input {
|
||||||
|
flex: 1 1 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-filter-total {
|
||||||
|
min-width: 100%;
|
||||||
|
margin-left: 0;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ol-total-line {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -68,6 +68,13 @@
|
|||||||
Rol + Departman Yetkilendirme
|
Rol + Departman Yetkilendirme
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
icon="list"
|
||||||
|
label="Liste"
|
||||||
|
@click="goList"
|
||||||
|
/>
|
||||||
|
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="canUpdateUser"
|
v-if="canUpdateUser"
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -178,12 +185,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import { ref, onMounted, watch } from 'vue'
|
import { ref, onMounted, watch } from 'vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { Notify } from 'quasar'
|
import { Notify } from 'quasar'
|
||||||
import api from 'src/services/api'
|
import api from 'src/services/api'
|
||||||
import { usePermission } from 'src/composables/usePermission'
|
import { usePermission } from 'src/composables/usePermission'
|
||||||
|
|
||||||
const { canUpdate } = usePermission()
|
const { canUpdate } = usePermission()
|
||||||
const canUpdateUser = canUpdate('user')
|
const canUpdateUser = canUpdate('user')
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
|
||||||
/* ================= STATE ================= */
|
/* ================= STATE ================= */
|
||||||
@@ -237,6 +247,27 @@ const columns = [
|
|||||||
|
|
||||||
let matrixLoading = false
|
let matrixLoading = false
|
||||||
|
|
||||||
|
function goList () {
|
||||||
|
router.push({ name: 'role-dept-permissions-list' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyRouteSelection () {
|
||||||
|
const qRole = String(route.query.roleId || '').trim()
|
||||||
|
const qDept = String(route.query.deptCode || '').trim()
|
||||||
|
|
||||||
|
if (/^\d+$/.test(qRole) && Number(qRole) > 0) {
|
||||||
|
roleId.value = qRole
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qDept) {
|
||||||
|
deptCode.value = qDept
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roleId.value && deptCode.value) {
|
||||||
|
loadMatrix()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ================= LOOKUPS ================= */
|
/* ================= LOOKUPS ================= */
|
||||||
|
|
||||||
@@ -425,14 +456,19 @@ function toggleColumn (key, val) {
|
|||||||
|
|
||||||
/* ================= INIT ================= */
|
/* ================= INIT ================= */
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
loadLookups()
|
await loadLookups()
|
||||||
|
applyRouteSelection()
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(roleId, v => console.log('ROLE_ID >>>', v))
|
watch(roleId, v => console.log('ROLE_ID >>>', v))
|
||||||
watch(deptCode, v => console.log('DEPT >>>', v))
|
watch(deptCode, v => console.log('DEPT >>>', v))
|
||||||
|
watch(
|
||||||
|
() => [route.query.roleId, route.query.deptCode],
|
||||||
|
() => {
|
||||||
|
if (!lookupsLoaded.value) return
|
||||||
|
applyRouteSelection()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,20 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: 'role-dept-permissions',
|
path: 'role-dept-permissions',
|
||||||
name: 'role-dept-permissions',
|
name: 'role-dept-permissions',
|
||||||
|
component: () => import('pages/RoleDepartmentPermissionGateway.vue'),
|
||||||
|
meta: { permission: 'user:update' }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'role-dept-permissions/list',
|
||||||
|
name: 'role-dept-permissions-list',
|
||||||
|
component: () => import('pages/RoleDepartmentPermissionList.vue'),
|
||||||
|
meta: { permission: 'user:update' }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'role-dept-permissions/editor',
|
||||||
|
name: 'role-dept-permissions-editor',
|
||||||
component: () => import('pages/RoleDepartmentPermissionPage.vue'),
|
component: () => import('pages/RoleDepartmentPermissionPage.vue'),
|
||||||
meta: { permission: 'user:update' }
|
meta: { permission: 'user:update' }
|
||||||
},
|
},
|
||||||
@@ -228,6 +242,13 @@ const routes = [
|
|||||||
meta: { permission: 'order:view' }
|
meta: { permission: 'order:view' }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'order-bulk-close',
|
||||||
|
name: 'order-bulk-close',
|
||||||
|
component: () => import('pages/OrderBulkClose.vue'),
|
||||||
|
meta: { permission: 'order:update' }
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: 'order-pdf/:id',
|
path: 'order-pdf/:id',
|
||||||
name: 'order-pdf',
|
name: 'order-pdf',
|
||||||
|
|||||||
Reference in New Issue
Block a user