alfa release
This commit is contained in:
520
ui/src/pages/tmpl.vue
Normal file
520
ui/src/pages/tmpl.vue
Normal file
@@ -0,0 +1,520 @@
|
||||
<template>
|
||||
<q-page padding>
|
||||
<m-edit-header
|
||||
title="Şablon Tasarımı"
|
||||
:show-save-cancel="ld.isDirty"
|
||||
@save="save"
|
||||
@cancel="cancel"
|
||||
/>
|
||||
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<q-select v-model="ld.companyID"
|
||||
map-options
|
||||
emit-value
|
||||
:label="t('selectCompany')"
|
||||
:options="ld.companies"
|
||||
option-value="ID"
|
||||
option-label="Title"
|
||||
dense
|
||||
options-dense
|
||||
outlined
|
||||
bg-color="white"
|
||||
@update:model-value="load"
|
||||
>
|
||||
<template v-slot:after>
|
||||
<q-btn
|
||||
flat
|
||||
icon="business"
|
||||
dense
|
||||
size="sm"
|
||||
color="white"
|
||||
to="/company/new"
|
||||
>
|
||||
<q-tooltip>{{ t('createCompany') }}</q-tooltip>
|
||||
</q-btn>
|
||||
</template>
|
||||
</q-select>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="ld.companyID" class="">
|
||||
<div class="row q-gutter-y-sm q-col-gutter-md">
|
||||
<q-file
|
||||
dense
|
||||
class="col-12"
|
||||
v-model="ld.xlsFileName"
|
||||
@update:model-value="loadFile"
|
||||
label="Bordro Dosyası"
|
||||
/>
|
||||
|
||||
<q-select
|
||||
class="col-3"
|
||||
v-model="tmpl.bordroSheet"
|
||||
:options="tmpl.sheets"
|
||||
label="Bordro Sayfası"
|
||||
dense
|
||||
/>
|
||||
<q-input
|
||||
class="col-3"
|
||||
dense
|
||||
v-model.number="tmpl.baslikSatiri"
|
||||
label="Başlık Satır No"
|
||||
/>
|
||||
<q-input
|
||||
class="col-3"
|
||||
dense
|
||||
v-model.number="tmpl.baslikSatirAdedi"
|
||||
label="Başlık Satır Adedi"
|
||||
/>
|
||||
<div class="col-3 flex justify-center">
|
||||
<q-btn label="Dosya Analizi"
|
||||
no-caps
|
||||
@click="processXLS"
|
||||
:disable="tmpl.bordroSheet === ''"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="ld.showFields">
|
||||
<q-list bordered class="rounded-borders">
|
||||
|
||||
<q-expansion-item
|
||||
expand-separator
|
||||
label="Alan Tanımları"
|
||||
switch-toggle-side
|
||||
header-class="text-h6 text-pcolor1"
|
||||
default-opened
|
||||
>
|
||||
<q-markup-table flat bordered>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Kolon No</th>
|
||||
<th>Alan</th>
|
||||
<th>Kontrol</th>
|
||||
<th>Fişte Göster</th>
|
||||
<th>Tip</th>
|
||||
<th>B/A</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="r in tmpl.alanlar" :key="r.fieldName">
|
||||
<td class="text-center" style="width: 70px;">{{ r.colNro }}</td>
|
||||
<td>{{ r.fieldName }}</td>
|
||||
<td class="text-center" style="width: 70px;">
|
||||
<q-radio
|
||||
v-model.number="tmpl.kontrolKolonu"
|
||||
:val="r.colNro"
|
||||
@update:model-value="ld.isDirty = true"
|
||||
/>
|
||||
</td>
|
||||
<td class="text-center" style="width: 70px;">
|
||||
<q-checkbox
|
||||
v-model="r.showInSlip"
|
||||
@update:model-value="ld.isDirty = true"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<q-select
|
||||
dense
|
||||
v-model="r.colType" :options="['', 'kriter', 'veri']"
|
||||
@update:model-value="ld.isDirty = true"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<q-select
|
||||
dense
|
||||
v-model="r.ba" :options="['B', 'A']"
|
||||
v-if="r.colType === 'veri'"
|
||||
@update:model-value="ld.isDirty = true"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</q-markup-table>
|
||||
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="ld.showFields">
|
||||
<div class="row q-col-gutter-md q-mb-md">
|
||||
<div class="col-auto">
|
||||
<q-btn label="Kriterleri Doldur"
|
||||
outline
|
||||
color="pcolor1"
|
||||
no-caps
|
||||
@click="fillCriteria"
|
||||
/>
|
||||
</div>
|
||||
<div class="col text-h6 text-pcolor1">
|
||||
Kriter Hesap Atamaları
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<q-list bordered class="rounded-borders">
|
||||
<q-expansion-item
|
||||
v-for="(v, k) in tmpl.kriterler" :key="k"
|
||||
expand-separator
|
||||
:label="k"
|
||||
switch-toggle-side
|
||||
>
|
||||
<q-markup-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-weight-bolder">
|
||||
Değer
|
||||
<q-btn
|
||||
flat
|
||||
icon="add"
|
||||
dense
|
||||
color="positive"
|
||||
/>
|
||||
<q-popup-edit
|
||||
v-model="ld.selectedVal"
|
||||
buttons
|
||||
v-slot="scope"
|
||||
@update:modelValue="addMapping(k)"
|
||||
>
|
||||
<q-select
|
||||
v-model="scope.value"
|
||||
:options="valFielOptions"
|
||||
dense
|
||||
autofocus
|
||||
counter
|
||||
@keyup.enter="scope.set"/>
|
||||
</q-popup-edit>
|
||||
</td>
|
||||
<td v-for="f in v.valFields" :key="f">
|
||||
{{ f }}
|
||||
<q-btn
|
||||
flat
|
||||
icon="delete"
|
||||
dense
|
||||
color="negative"
|
||||
@click="delMapping(k, f)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(kv, kk) in v.mappings" :key="kk">
|
||||
<td>{{ kk }}</td>
|
||||
<td v-for="f in v.valFields" :key="f">
|
||||
<q-input
|
||||
v-model="kv[f]"
|
||||
dense
|
||||
@update:modelValue="ld.isDirty=true"
|
||||
/>
|
||||
</td>
|
||||
|
||||
<!--
|
||||
<td>
|
||||
<q-input
|
||||
v-model="kv.code01"
|
||||
dense
|
||||
@update:modelValue="ld.isDirty=true"
|
||||
/>
|
||||
</td>
|
||||
-->
|
||||
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</q-markup-table>
|
||||
</q-expansion-item>
|
||||
</q-list>
|
||||
|
||||
</q-card-section>
|
||||
|
||||
</q-card>
|
||||
</q-page>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, reactive, toRaw } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { api } from 'boot/axios'
|
||||
import { catchAxiosError, showAxiosError } from 'src/libjs/lib/axios'
|
||||
import MEditHeader from 'src/libjs/comp/MEditHeader.vue'
|
||||
import { read, utils } from 'xlsx'
|
||||
import { useQuasar } from 'quasar'
|
||||
|
||||
const { t } = useI18n()
|
||||
const $q = useQuasar()
|
||||
|
||||
const ld = reactive({
|
||||
companyID: null,
|
||||
companies: [],
|
||||
isDirty: false,
|
||||
xlsFileName: null,
|
||||
selectedVal: '',
|
||||
alreadySelectedValFields: {},
|
||||
|
||||
showFields: false,
|
||||
})
|
||||
|
||||
const tmpl = reactive({
|
||||
rawData: null,
|
||||
sheets: [],
|
||||
bordroSheet: '',
|
||||
|
||||
baslikSatiri: 7,
|
||||
baslikSatirAdedi: 2,
|
||||
|
||||
kontrolKolonu: -1,
|
||||
|
||||
alanlar: [],
|
||||
kriterler: {},
|
||||
})
|
||||
|
||||
let workbook = null
|
||||
|
||||
onMounted(() => {
|
||||
getCompanyList()
|
||||
})
|
||||
|
||||
const valFielOptions = computed(() => {
|
||||
const ls = tmpl.alanlar.filter(f => {return f.colType === 'veri'})
|
||||
const opts = []
|
||||
ls.forEach(f => {
|
||||
|
||||
if (!ld.alreadySelectedValFields.hasOwnProperty(f.fieldName)) {
|
||||
opts.push(f.fieldName)
|
||||
}
|
||||
|
||||
})
|
||||
return opts
|
||||
})
|
||||
|
||||
const getCompanyList = function () {
|
||||
api.get('/sy/companies').then(res => {
|
||||
if (res.data.Success) {
|
||||
ld.companies = res.data.Data || []
|
||||
} else {
|
||||
showAxiosError(res)
|
||||
}
|
||||
}).catch(err => {
|
||||
catchAxiosError(err)
|
||||
})
|
||||
}
|
||||
|
||||
const save = function () {
|
||||
$q.loading.show()
|
||||
api.post(`/tmpl/${ld.companyID}`, toRaw(tmpl)).then(res => {
|
||||
if (res.data.Success) {
|
||||
ld.isDirty = false
|
||||
} else {
|
||||
showAxiosError()
|
||||
}
|
||||
}).catch(err => {
|
||||
catchAxiosError(err)
|
||||
}).finally(() => {
|
||||
$q.loading.hide()
|
||||
})
|
||||
}
|
||||
|
||||
const load = function () {
|
||||
Object.keys(ld.alreadySelectedValFields).forEach(k => {
|
||||
delete ld.alreadySelectedValFields[k]
|
||||
})
|
||||
|
||||
Object.keys(tmpl.kriterler).forEach(k => {
|
||||
delete tmpl.kriterler[k]
|
||||
})
|
||||
tmpl.sheets.splice(0)
|
||||
tmpl.alanlar.splice(0)
|
||||
tmpl.bordroSheet = ''
|
||||
|
||||
$q.loading.show()
|
||||
api.get(`/tmpl/${ld.companyID}`).then(res => {
|
||||
if (res.data.Success) {
|
||||
if (res.data.Data === null) {
|
||||
ld.showFields = false
|
||||
return
|
||||
}
|
||||
|
||||
ld.isDirty = false
|
||||
ld.showFields = true
|
||||
|
||||
Object.keys(res.data.Data).forEach(k => {
|
||||
tmpl[k] = res.data.Data[k]
|
||||
|
||||
/*
|
||||
if (k !== 'alanlar') {
|
||||
tmpl[k] = res.data.Data[k]
|
||||
}
|
||||
|
||||
*/
|
||||
})
|
||||
//tmpl.rawData = new Uint8Array(res.data.Data.rawData)
|
||||
//workbook = read(tmpl.rawData)
|
||||
|
||||
Object.keys(tmpl.kriterler).forEach(k => {
|
||||
tmpl.kriterler[k].valFields.forEach(f => {
|
||||
ld.alreadySelectedValFields[f] = 'x'
|
||||
})
|
||||
})
|
||||
|
||||
} else {
|
||||
showAxiosError()
|
||||
}
|
||||
}).catch(err => {
|
||||
catchAxiosError(err)
|
||||
}).finally(() => {
|
||||
$q.loading.hide()
|
||||
})
|
||||
}
|
||||
|
||||
const loadFile = function () {
|
||||
const reader = new FileReader()
|
||||
/*
|
||||
reader.addEventListener('load', (event) => {
|
||||
console.log(event.target.result)
|
||||
});
|
||||
reader.readAsDataURL(ld.xlsFile);
|
||||
|
||||
*/
|
||||
|
||||
reader.onload = function (e) {
|
||||
const uin = new Uint8Array(e.target.result)
|
||||
readXLS(uin)
|
||||
}
|
||||
|
||||
reader.readAsArrayBuffer(ld.xlsFileName)
|
||||
}
|
||||
|
||||
const readXLS = function (inb) {
|
||||
tmpl.sheets.splice(0)
|
||||
tmpl.bordroSheet = ''
|
||||
|
||||
workbook = read(inb)
|
||||
tmpl.sheets.push(...workbook.SheetNames)
|
||||
}
|
||||
|
||||
const processXLS = function () {
|
||||
const sheet = workbook.Sheets[tmpl.bordroSheet]
|
||||
tmpl.rawData = utils.sheet_to_json(sheet, { header: 1 })
|
||||
|
||||
tmpl.alanlar.splice(0)
|
||||
|
||||
let lastCol = -1
|
||||
tmpl.rawData[tmpl.baslikSatiri - 1].forEach((val, ndx) => {
|
||||
|
||||
//başlık olmayan kolonlar
|
||||
if (ndx - lastCol > 1) {
|
||||
for (let j = 1; j < ndx - lastCol; j++) {
|
||||
tmpl.alanlar.push({
|
||||
colNro: lastCol + 1,
|
||||
fieldName: `Kolon ${lastCol + 2}`,
|
||||
colType: '',
|
||||
ba: 'B',
|
||||
showInSlip: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let name = val
|
||||
|
||||
for (let j = 1; j < tmpl.baslikSatirAdedi; j++) {
|
||||
let addiVal = tmpl.rawData[tmpl.baslikSatiri - 1 + j][ndx]
|
||||
if (!addiVal) {
|
||||
addiVal = ''
|
||||
}
|
||||
name = name + ' ' + addiVal
|
||||
}
|
||||
|
||||
tmpl.alanlar.push({
|
||||
colNro: ndx,
|
||||
fieldName: name,
|
||||
showInSlip: false,
|
||||
colType: '',
|
||||
ba: 'B',
|
||||
})
|
||||
|
||||
lastCol = ndx
|
||||
})
|
||||
|
||||
ld.showFields = true
|
||||
}
|
||||
|
||||
const fillCriteria = function () {
|
||||
ld.isDirty = true
|
||||
// kriterleri temizleyelim
|
||||
Object.keys(ld.alreadySelectedValFields).forEach(k => {
|
||||
delete ld.alreadySelectedValFields[k]
|
||||
})
|
||||
tmpl.kriterler = {}
|
||||
|
||||
// kriter alanlarını bulup boş kriter nesnelerini oluşturalım
|
||||
const kriterCols = []
|
||||
tmpl.alanlar.filter(f => {return f.colType === 'kriter'}).forEach(f => {
|
||||
tmpl.kriterler[f.fieldName] = {
|
||||
colNro: f.colNro,
|
||||
|
||||
valFields: [],
|
||||
/*
|
||||
[
|
||||
{fieldName: 'xxx', colNro: 3}
|
||||
{fieldName: 'yyy', colNro: 4}
|
||||
]
|
||||
*/
|
||||
|
||||
mappings: {},
|
||||
/*
|
||||
mapping['kriter1'] = {xxx: 770.01.001, yyy: 770.01.002}
|
||||
*/
|
||||
}
|
||||
kriterCols.push(f.fieldName)
|
||||
})
|
||||
|
||||
tmpl.rawData.forEach((row, ndx) => {
|
||||
if (ndx <= tmpl.baslikSatiri - 1 + tmpl.baslikSatirAdedi) {
|
||||
|
||||
} else {
|
||||
const kval = row[tmpl.kontrolKolonu]
|
||||
if ((kval !== null) && (kval !== undefined) && (kval !== '')) {
|
||||
Object.keys(tmpl.kriterler).forEach(k => {
|
||||
const kriterVal = row[tmpl.kriterler[k].colNro]
|
||||
if ((kriterVal !== null) && (kriterVal !== undefined) && (kriterVal !== '')) {
|
||||
tmpl.kriterler[k].mappings[kriterVal] = {}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const addMapping = function (k) {
|
||||
ld.isDirty = true
|
||||
ld.alreadySelectedValFields[ld.selectedVal] = ''
|
||||
tmpl.kriterler[k].valFields.push(ld.selectedVal)
|
||||
Object.keys(tmpl.kriterler[k].mappings).forEach(vk => {
|
||||
tmpl.kriterler[k].mappings[vk][ld.selectedVal] = ''
|
||||
})
|
||||
ld.selectedVal = ''
|
||||
}
|
||||
|
||||
const delMapping = function (k, valField) {
|
||||
ld.isDirty = true
|
||||
delete ld.alreadySelectedValFields[valField]
|
||||
|
||||
const index = tmpl.kriterler[k].valFields.indexOf(valField)
|
||||
if (index !== -1) {
|
||||
tmpl.kriterler[k].valFields.splice(index, 1)
|
||||
}
|
||||
|
||||
Object.keys(tmpl.kriterler[k].mappings).forEach(vk => {
|
||||
delete tmpl.kriterler[k].mappings[vk][ld.selectedVal]
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user