fix : 전표 등록, 수정은 결재선만 해결하여 올림, api 추가까지 완료

This commit is contained in:
Yesol Choi
2025-06-05 16:20:04 +09:00
parent 0a9355c766
commit aefe71bb2b
4 changed files with 173 additions and 221 deletions

View File

@@ -1,8 +1,7 @@
<script setup lang="ts">
import {saveTempSlip} from "/@src/service/slipApi.ts";
import {formatDatefromStringDate} from "/@src/utils/common/comfunc.ts";
import {ApprsList, type iPbAtt, type Person} from "/@src/utils/types.ts";
import {type iPbAtt, Person, SapPerson} from "/@src/utils/types.ts";
import {VTabsItem} from "/src/components/app-vuero/VCustomTabs.vue";
import {getContractDetail} from "/@src/service/contractApi.ts";
import {deletePrcsFile} from "/@src/service/priceApi.ts";
@@ -70,7 +69,7 @@ const params = reactive({
})
const pbAtts = ref<iPbAtt[]>(params.slipAtts)
const formattedNumber = ref(0)
const apprLine = ref<VTabsItem[]>([])
const apprLine = ref<SapPerson[]>([])
const getDetailBeforeList = (item) => {
console.log("item before",item)
@@ -127,14 +126,32 @@ const createChit = async () => {
zwf0011t : {
wkftx : "결재 테스트11", //!!!!!!어떤 값인지 모름
apprs : [{
label: apprLine.value[0].label,
value: apprLine.value[0].value.map((req) => ({
label: '결재',
value: apprLine.value.map((req) => ({
lineclsf : req.lineclsf,
bname : req.bname,
abscd : req.abscd
}))
}]
}
// waers : currencyCode.value, //"KRW",
// bktxt : params.bktxt,//"전표 생성 테스트1",
// lifnr : params.lifnr, //999-99-99999",
// wrbtr : formattedNumber.value, //수정필요 "1203",
// mwskz : taxCode.value, //"V4",
// gsber : affiliationCode.value, //무슨 값인지 모름 gsber bukrs bupla 같다고 함 1000
// bupla : affiliationCode.value, //1000
// zterm : params.zterm, //어떤 값인지 모름 PF00
// banks : params.banks , //어떤 값인지 모름 KR
// bankl : params.bankl, //012
// bankn : params.bankn, //3510876657453
// hkont : params.hkont,//G/L 계정 5366010
// wrbtrS : formattedNumber.value, //1102
// kostl : "12330", //12330
// projk : selectCostCode.value, //빈값
// trtGubun : params.trtGubun,//어떤 값인지 모름 11
// txBillSeq : params.txBillSeq,//어떤 값인지 모름 202503231
}
notyf.dismissAll()
res = await saveTempSlip(createParams)
@@ -149,63 +166,22 @@ const createChit = async () => {
}
}
const updateChit = async () => {
let res = null
try{
loading.value = true
const createParams = {
contNo : params.contNo, //"CONT-0000000005",
bldat : '20250602',//params.regSdt.replace("-",""), // "20250501",
budat : '20250610',//params.regSdt2.replace("-",""), // "20250502",
waers : currencyCode.value, //"KRW",
bktxt : params.bktxt,//"전표 생성 테스트1",
lifnr : params.lifnr, //999-99-99999",
wrbtr : formattedNumber.value, //수정필요 "1203",
mwskz : taxCode.value, //"V4",
gsber : affiliationCode.value, //무슨 값인지 모름 gsber bukrs bupla 같다고 함 1000
bupla : affiliationCode.value, //1000
zterm : params.zterm, //어떤 값인지 모름 PF00
banks : params.banks , //어떤 값인지 모름 KR
bankl : params.bankl, //012
bankn : params.bankn, //3510876657453
hkont : params.hkont,//G/L 계정 5366010
wrbtrS : formattedNumber.value, //1102
kostl : "12330", //12330
projk : selectCostCode.value, //빈값
trtGubun : params.trtGubun,//어떤 값인지 모름 11
txBillSeq : params.txBillSeq,//어떤 값인지 모름 202503231
slipAtts: pbAtts.value.map(req => ({
logiFnm: req.logiFnm,
data: req.data})),//첨부파일 데이터,
zwf0011t : {
wkftx : "결재 테스트11", //어떤 값인지 모름
apprs : [{
label: apprLine.value[0].label,
value: apprLine.value[0].value.map((req) => ({
lineclsf : req.lineclsf,
bname : req.bname,
abscd : req.abscd
}))
}]
const selectUser = ref<SapPerson[]>([])
const isDuplicate = (person: SapPerson) =>{
return apprLine.value.some((p) => p.bname === person.bname)}
watch(
selectUser,
(newPersons) => {
if (Array.isArray(newPersons) && newPersons.length > 0) {
const filtered = newPersons.filter((p) => !isDuplicate(p))
apprLine.value = [...apprLine.value, ...filtered]
selectUser.value = []
}
}
notyf.dismissAll()
res = await saveTempSlip(createParams)
if(res.request.status == '200'){
notyf.primary('등록 되었습니다.')
router.push({path: '/app/priceManagement'})
}
}catch(e){
notyf.error(e.message)
}finally {
loading.value = false
}
}
const selectedTab = ref<VTabsItem[]>()
const addTabFromRow =()=>{
console.log("row",row)
console.log("row",index)
}
},
{ deep: true }
)
const onFileClick = () => {
const input = <any> document.querySelector('.file-input')
@@ -264,25 +240,6 @@ const onPrcsFileDownload = async (prcsNo: string, fileOrd: number, logiFnm: stri
link.click()
}
const selectUser = ref<Person[]>([])
const isDuplicate = (person: Person) =>{
console.log("value[0].value", apprLine.value)
return apprLine.value.some((p) => p.lineclsf === person.sabun)}
watch(
selectUser,
(newPersons) => {
console.log("newPersons",newPersons)
if (Array.isArray(newPersons) && newPersons.length > 0) {
const filtered = newPersons.filter((p) => !isDuplicate(p))
apprLine.value = [...apprLine.value, ...filtered]
selectUser.value = []
}
},
{ deep: true }
)
const onPriceDelete = (index: number) => {
if(apprLine.value.length-1 !== params.flexColumn.length
@@ -529,10 +486,9 @@ const moveDown = (index: number) => {
<td>예산관리</td>
<td>
<VButton
color="primary"
@click="centeredActionsOpen = true"
>
G/L계정// 설정필요
disabled
color="primary">
G/L계정
</VButton>
</td>
<td colspan="2">
@@ -632,49 +588,37 @@ const moveDown = (index: number) => {
<div class="column is-12">
<VUserSap v-model="selectUser" placeholder="사번이나 이름으로 검색해주세요"/>
</div>
<VCustomTabs
type="boxed"
v-model:selected="selectedTab"
:tabs="apprLine">
<template #tab-link-label="{ tab }">
{{ tab.label }}
</template>
<template #tab="{ activeValue }">
<div>
<ComVFlexTable
:data="activeValue? activeValue : []"
:columns="params.flexColumn"
:compact="true"
:clickable="true"
@rowClick="addTabFromRow"
>
<template #body-cell="{row, column, index, value}">
<span v-if="column.key=='lineclsf'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=9
v-model="row.lineclsf"
/>
</VField>
</span>
<span v-else-if="column.key=='wkfst'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=8
v-model="row.wkfst"
/>
</VField>
<div>
<ComVFlexTable
:data="apprLine"
:columns="params.flexColumn"
:compact="true"
>
<template #body-cell="{row, column, index, value}">
<span v-if="column.key=='lineclsf'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=9
v-model="row.lineclsf"
/>
</VField>
</span>
<span v-else-if="column.key === 'actions'" class="flex gap-1">
<VCustomButton v-if="index != 1" @click="moveUp(index)" icon="lucide:arrow-up" />
<VCustomButton @click="moveDown(index)" icon="lucide:arrow-down" />
<VCustomButton @click="onPriceDelete(index)">{{"삭제"}}</VCustomButton>
</span>
</template>
</ComVFlexTable>
</div>
</template>
</VCustomTabs>
<span v-else-if="column.key=='wkfst'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=8
v-model="row.wkfst"
/>
</VField>
</span>
<span v-else-if="column.key === 'actions'" class="flex gap-1">
<VCustomButton v-if="index != 1" @click="moveUp(index)" icon="lucide:arrow-up" />
<VCustomButton @click="moveDown(index)" icon="lucide:arrow-down" />
<VCustomButton @click="onPriceDelete(index)">{{"삭제"}}</VCustomButton>
</span>
</template>
</ComVFlexTable>
</div>
</div>
</div>
</div>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import {getBeforeSlipDetail, saveTempSlip} from "/@src/service/slipApi.ts";
import {getBeforeSlipDetail, saveTempSlip, updateTempSlip} from "/@src/service/slipApi.ts";
import {formatDatefromStringDate} from "/@src/utils/common/comfunc.ts";
import { type iPbAtt, type Person} from "/@src/utils/types.ts";
import {type iPbAtt, Person, type SapPerson} from "/@src/utils/types.ts";
import {VTabsItem} from "/@src/components/app-vuero/VCustomTabs.vue";
import {getContractDetail} from "/@src/service/contractApi.ts";
import {deletePrcsFile} from "/@src/service/priceApi.ts";
@@ -11,8 +11,6 @@ onBeforeMount(async ()=>{
const result = await getBeforeSlipDetail(history.state.key)
// 대금지급 전 slip api 에서 결재선까지 받아옴
getDetailList(result)
apprLine.value = result.zwf0011t.apprs
selectedTab.value = apprLine.value[0].value
})
const notyf = useNotyf()
@@ -72,7 +70,7 @@ const params = reactive({
})
const pbAtts = ref<iPbAtt[]>(params.slipAtts)
const formattedNumber = ref(0)
const apprLine = ref<VTabsItem[]>([])
const apprLine = ref<SapPerson[]>([])
const getDetailList = (item) => {
console.log("getDetailList",item)
params.contNo = item.contNo
@@ -99,19 +97,10 @@ const getDetailList = (item) => {
params.txBillSeq = item.txBillSeq
params.slipAtts = item.slipAtts//첨부파일
console.log("params.slipAtts",params.slipAtts)
apprLine.value = item.zwf0011t.apprs
apprLine.value = item.zwf0011t.apprs[0].value
console.log("apprsList.value",apprLine.value)
}
const getDetailBeforeList = (item) => {
console.log("item before",item)
params.contStatCd = item.contStatCd
params.contNo = item.contNo
params.place = item.compNm// !!!!!!업체명 bupla
params.bktxt = item.title //!!!!!!계약명
params.lifnr = item.bizNo //!!!!!계약상대자
}
function onInput(event) {
let onlyNumber = event.target.value.replace(/[^0-9]/g, '')
formattedNumber.value = onlyNumber ? Number(onlyNumber).toLocaleString() : ''
@@ -135,33 +124,12 @@ const updateChit = async () => {
loading.value = true
const createParams = {
contNo : params.contNo, //"CONT-0000000005",
bldat : '20250602',//params.regSdt.replace("-",""), // "20250501",
budat : '20250610',//params.regSdt2.replace("-",""), // "20250502",
waers : currencyCode.value, //"KRW",
bktxt : params.bktxt,//"전표 생성 테스트1",
lifnr : params.lifnr, //999-99-99999",
wrbtr : formattedNumber.value, //수정필요 "1203",
mwskz : taxCode.value, //"V4",
gsber : affiliationCode.value, //무슨 값인지 모름 gsber bukrs bupla 같다고 함 1000
bupla : affiliationCode.value, //1000
zterm : params.zterm, //어떤 값인지 모름 PF00
banks : params.banks , //어떤 값인지 모름 KR
bankl : params.bankl, //012
bankn : params.bankn, //3510876657453
hkont : params.hkont,//G/L 계정 5366010
wrbtrS : formattedNumber.value, //1102
kostl : "12330", //12330
projk : selectCostCode.value, //빈값
trtGubun : params.trtGubun,//어떤 값인지 모름 11
txBillSeq : params.txBillSeq,//어떤 값인지 모름 202503231
slipAtts: pbAtts.value.map(req => ({
logiFnm: req.logiFnm,
data: req.data})),//첨부파일 데이터,
zwf0011t : {
wkftx : "결재 테스트11", //어떤 값인지 모름
belnr: "0605145807", //!!!!!!!뭔 값인지 모름
wkfid: "FI2025900020", //!!!!!!!뭔 값인지 모름
apprs : [{
label: apprLine.value[0].label,
value: apprLine.value[0].value.map((req) => ({
label: '결재',
value: apprLine.value.map((req) => ({
lineclsf : req.lineclsf,
bname : req.bname,
abscd : req.abscd
@@ -170,7 +138,7 @@ const updateChit = async () => {
}
}
notyf.dismissAll()
res = await saveTempSlip(createParams)
res = await updateTempSlip(createParams)
if(res.request.status == '200'){
notyf.primary('등록 되었습니다.')
router.push({path: '/app/priceManagement'})
@@ -182,10 +150,6 @@ const updateChit = async () => {
}
}
const selectedTab = ref<VTabsItem[]>()
const addTabFromRow =()=>{
console.log("row",row)
console.log("row",index)
}
const onFileClick = () => {
const input = <any> document.querySelector('.file-input')
@@ -247,8 +211,7 @@ const onPrcsFileDownload = async (prcsNo: string, fileOrd: number, logiFnm: stri
const selectUser = ref<Person[]>([])
const isDuplicate = (person: Person) =>{
console.log("value[0].value", apprLine.value)
return apprLine.value.some((p) => p.lineclsf === person.sabun)}
return apprLine.value.some((p) => p.bname === person.bname)}
watch(
selectUser,
@@ -508,12 +471,11 @@ const moveDown = (index: number) => {
<tr>
<td>예산관리</td>
<td>
<VButton
color="primary"
@click="centeredActionsOpen = true"
>
G/L계정// 설정필요
</VButton>
<VButton
disabled
color="primary">
G/L계정
</VButton>
</td>
<td colspan="2">
<VField>
@@ -612,49 +574,37 @@ const moveDown = (index: number) => {
<div class="column is-12">
<VUserSap v-model="selectUser" placeholder="사번이나 이름으로 검색해주세요"/>
</div>
<VCustomTabs
type="boxed"
v-model:selected="selectedTab"
:tabs="apprLine">
<template #tab-link-label="{ tab }">
{{ tab.label }}
</template>
<template #tab="{ activeValue }">
<div>
<ComVFlexTable
:data="activeValue? activeValue : []"
:columns="params.flexColumn"
:compact="true"
:clickable="true"
@rowClick="addTabFromRow"
>
<template #body-cell="{row, column, index, value}">
<span v-if="column.key=='lineclsf'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=9
v-model="row.lineclsf"
/>
</VField>
</span>
<span v-else-if="column.key=='wkfst'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=8
v-model="row.wkfst"
/>
</VField>
<div>
<ComVFlexTable
:data="apprLine"
:columns="params.flexColumn"
:compact="true"
>
<template #body-cell="{row, column, index, value}">
<span v-if="column.key=='lineclsf'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=9
v-model="row.lineclsf"
/>
</VField>
</span>
<span v-else-if="column.key === 'actions'" class="flex gap-1">
<VCustomButton v-if="index != 1" @click="moveUp(index)" icon="lucide:arrow-up" />
<VCustomButton @click="moveDown(index)" icon="lucide:arrow-down" />
<VCustomButton @click="onDocDelete(index)">{{"삭제"}}</VCustomButton>
</span>
</template>
</ComVFlexTable>
</div>
</template>
</VCustomTabs>
<span v-else-if="column.key=='wkfst'" class="column">
<VField class="pr-1">
<VCodeSelect
cd_grp=8
v-model="row.wkfst"
/>
</VField>
</span>
<span v-else-if="column.key === 'actions'" class="flex gap-1">
<VCustomButton v-if="index != 1" @click="moveUp(index)" icon="lucide:arrow-up" />
<VCustomButton @click="moveDown(index)" icon="lucide:arrow-down" />
<VCustomButton @click="onDocDelete(index)">{{"삭제"}}</VCustomButton>
</span>
</template>
</ComVFlexTable>
</div>
</div>
</div>
</div>

View File

@@ -1,4 +1,29 @@
import axios from 'axios'
/**
* 임시전표 수정
* @param {object} params
* @property {string} params.contNo -계약번호
* @returns
*/
export async function updateTempSlip(params = {}) {
try {
const result = await axios.put(`/api/slip`,params)
return result
} catch (e) {
const serverError = e.response?.data;
const message = typeof serverError?.body === 'string'
? serverError.body
: 'Unknown error occurred';
const error = new Error(message); // ✅ 반드시 string만 넣기! 아니면 객체가 문자열로 나옴
error.code = serverError?.code;
error.errTime = serverError?.errTime;
throw error;
}
}
/**
* 임시전표 저장
* @param {object} params
@@ -71,6 +96,31 @@ export async function deleteSlipDetail(contNo: string) {
}
}
/**
* 대금지급 첨부파일 삭제
* @property {string} params.contNo -계약번호
* @returns
* @param contNo
*/
export async function deleteSlipDetailFile(contNo: string, fileOrd: string) {
try {
const result = await axios.delete(`/api/slip/${contNo}/${fileOrd}`)
return result.data
} catch (e) {
const serverError = e.response?.data;
const message = typeof serverError?.body === 'string'
? serverError.body
: 'Unknown error occurred';
const error = new Error(message); // ✅ 반드시 string만 넣기! 아니면 객체가 문자열로 나옴
error.code = serverError?.code;
error.errTime = serverError?.errTime;
throw error;
}
}
/**
* 전표 상세 조회(대금지급중)
* @property {string} params.contNo -계약번호

View File

@@ -16,6 +16,14 @@ export type Person = {
gubun_cd: string
}
export type SapPerson = {
lineclsfnm: string
lineclsf: string //구분은 입력받는 값
bname: string //sabun
btext: string //name
abscd: string //attend_cd
}
export interface iPbAtt {
prcsNo: string
bizNo: string