반응형
여기는 선급금요청GL, 선급금GL, 은행GL이 1개씩이라 하드코딩 했으나 각자 사정에 맞춰서 수정하시고...
po/item별로 선급금을 1개만 요청하는 경우도 있고 2개 이상 요청하는 경우도 있고 선급금 100%인 곳도 있고 선급금 30%인 곳도 있고... 선급금 전표도 쪼갰다 붙였다 송장도 쪼갰다 붙였다 지급도 쪼갰다 붙였다 ㅠㅠ
왠만한 케이스는 다 잡은거 같은데 아닐수도......
그리고 송장을 여러개의 po/item 합쳐서 하는 케이스가 있기 때문에 외상매출금에 대한 실제 은행 지급 금액을 비율로 쪼개서 금액 차이가 좀 발생함. -1~1달러 차이는 정상으로 처리 했음.
REPORT ZFIR9998.
TYPE-POOLS: SLIS.
TABLES: BSEG, BKPF, RSEG, RBKP, BSE_CLR, ZIMTP00, ZIMTP01.
*=====================================================================
*STEP 1. 조회 조건 정의
*회사코드, 전기일, 선급금 요청 GL계정(기본:0099040101), PO 조건 입력
*=====================================================================
*1.조회 조건
SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-T01.
PARAMETERS: P_BUKRS TYPE BUKRS DEFAULT '1000' OBLIGATORY.
SELECT-OPTIONS: S_BUDAT FOR BKPF-BUDAT DEFAULT '20250701' TO '99991231' NO-EXTENSION.
PARAMETERS: P_HKONT TYPE HKONT DEFAULT '0099040101' OBLIGATORY.
SELECT-OPTIONS: S_PO FOR BKPF-BKTXT NO INTERVALS.
SELECTION-SCREEN END OF BLOCK B1.
*=====================================================================
*STEP 2. 출력/집계용 내부 테이블 및 구조 정의
*=====================================================================
*2. 데이터 구조 정의
TYPES: BEGIN OF TY_OUT,
LIFNR TYPE BSEG-LIFNR,
NAME1 TYPE LFA1-NAME1,
EBELN TYPE BSEG-EBELN,
EBELP TYPE BSEG-EBELP,
REQ_BELNR TYPE STRING,
REQ_AMT TYPE BSEG-WRBTR,
PRE_BELNR TYPE STRING,
PRE_AMT TYPE BSEG-WRBTR,
CLR_PRE_BEL TYPE STRING,
CLR_PRE_AMT TYPE BSEG-WRBTR,
BAL_PRE_AMT TYPE BSEG-WRBTR,
AP_FI_BELNR TYPE STRING,
AP_AMT TYPE BSEG-WRBTR,
BANK_BELNR TYPE STRING,
BANK_AMT TYPE BSEG-WRBTR,
OFF_AMT TYPE BSEG-WRBTR,
VAL_AMT TYPE BSEG-WRBTR,
WAERS TYPE BKPF-WAERS,
REMARK TYPE CHAR100,
LINE_COLOR TYPE CHAR4,
END OF TY_OUT.
TYPES: BEGIN OF TY_RSEG_TOT,
BELNR TYPE RSEG-BELNR,
GJAHR TYPE RSEG-GJAHR,
WRBTR TYPE RSEG-WRBTR,
END OF TY_RSEG_TOT.
TYPES: BEGIN OF TY_CBO_MAP,
ZCLNO TYPE BELNR_D,
ZCLYR TYPE GJAHR,
ZIMPNO TYPE ZIMPNO,
END OF TY_CBO_MAP.
TYPES: BEGIN OF TY_CBO_ITEM,
ZIMPNO TYPE ZIMPNO,
EBELN TYPE EBELN,
EBELP TYPE EBELP,
END OF TY_CBO_ITEM.
DATA: LT_OUTPUT TYPE TABLE OF TY_OUT,
LT_FCAT TYPE SLIS_T_FIELDCAT_ALV,
LT_RSEG_TOT TYPE TABLE OF TY_RSEG_TOT,
LT_CBO_HEAD TYPE TABLE OF TY_CBO_MAP,
LT_CBO_ITEM TYPE TABLE OF TY_CBO_ITEM.
DATA: LV_INV_BANK_TOT TYPE BSEG-WRBTR,
LV_INV_TOT TYPE BSEG-WRBTR,
LV_TOT_ALLOCATED_CLR TYPE BSEG-WRBTR,
LV_TMP_BANK_BELNR TYPE STRING.
DATA: BEGIN OF LT_PAY OCCURS 0,
EBELN LIKE BSEG-EBELN,
EBELP LIKE BSEG-EBELP,
BELNR LIKE BSEG-BELNR,
GJAHR LIKE BSEG-GJAHR,
BUZEI LIKE BSEG-BUZEI,
WRBTR LIKE BSEG-WRBTR,
END OF LT_PAY.
START-OF-SELECTION.
DATA: LT_WHERE_CLAUSES TYPE STANDARD TABLE OF STRING,
LV_WHERE_LINE TYPE STRING.
DATA: LV_LEN TYPE I,
LV_EBELN TYPE EKPO-EBELN,
LV_EBELP TYPE STRING.
DATA: LS_BUDAT LIKE LINE OF S_BUDAT.
CLEAR: LT_WHERE_CLAUSES.
" 1. 회사코드
CONCATENATE 'A~BUKRS =''' P_BUKRS '''' INTO LV_WHERE_LINE.
APPEND LV_WHERE_LINE TO LT_WHERE_CLAUSES.
" 2. G/L 계정
CONCATENATE 'AND A~HKONT =''' P_HKONT '''' INTO LV_WHERE_LINE.
APPEND LV_WHERE_LINE TO LT_WHERE_CLAUSES.
" 3. 역분개 여부
APPEND 'AND B~STBLG =''''' TO LT_WHERE_CLAUSES.
" 4. 전기일
IF S_BUDAT[] IS NOT INITIAL.
LOOP AT S_BUDAT INTO LS_BUDAT.
CASE LS_BUDAT-OPTION.
WHEN 'EQ'.
CONCATENATE 'AND B~BUDAT =''' LS_BUDAT-LOW '''' INTO LV_WHERE_LINE.
APPEND LV_WHERE_LINE TO LT_WHERE_CLAUSES.
WHEN 'BT'.
CONCATENATE 'AND B~BUDAT BETWEEN''' LS_BUDAT-LOW ''' AND ''' LS_BUDAT-HIGH '''' INTO LV_WHERE_LINE.
APPEND LV_WHERE_LINE TO LT_WHERE_CLAUSES.
ENDCASE.
ENDLOOP.
ENDIF.
" 5. PO/ITEM 정보
IF S_PO[] IS NOT INITIAL.
DATA: LT_PO_TMP TYPE STANDARD TABLE OF STRING,
LV_PO_TMP TYPE STRING.
LOOP AT S_PO.
CLEAR: LV_EBELN, LV_EBELP, LV_PO_TMP.
CONDENSE S_PO-LOW NO-GAPS.
LV_LEN = STRLEN( S_PO-LOW ).
IF LV_LEN > 10.
" PO 10자리 + 아이템 번호 패턴
LV_EBELN = S_PO-LOW+0(10).
LV_EBELP = S_PO-LOW+10.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = LV_EBELP
IMPORTING
OUTPUT = LV_EBELP.
IF LT_PO_TMP IS INITIAL.
CONCATENATE '( A~EBELN = ''' LV_EBELN ''' AND A~EBELP = ''' LV_EBELP ''' )' INTO LV_PO_TMP.
ELSE.
CONCATENATE 'OR ( A~EBELN = ''' LV_EBELN ''' AND A~EBELP = ''' LV_EBELP ''' )' INTO LV_PO_TMP.
ENDIF.
APPEND LV_PO_TMP TO LT_PO_TMP.
ELSEIF LV_LEN > 0 AND LV_LEN <= 10.
" 아이템 번호 없이 PO만 넣었을 때
LV_EBELN = S_PO-LOW.
IF LT_PO_TMP IS INITIAL.
CONCATENATE '( A~EBELN = ''' LV_EBELN ''' )' INTO LV_PO_TMP.
ELSE.
CONCATENATE 'OR ( A~EBELN = ''' LV_EBELN ''' )' INTO LV_PO_TMP.
ENDIF.
APPEND LV_PO_TMP TO LT_PO_TMP.
ENDIF.
ENDLOOP.
" 메인 조건 텍스트 뒤에 'AND (' 와 ')'로 감쌈
IF LT_PO_TMP IS NOT INITIAL.
INSERT 'AND (' INTO LT_PO_TMP INDEX 1.
APPEND ')' TO LT_PO_TMP.
APPEND LINES OF LT_PO_TMP TO LT_WHERE_CLAUSES.
ENDIF.
ENDIF.
* =====================================================================
* STEP 3. 선급금 요청 조회 " GL 0099040101 : 선급금_요청 " 선급 요청
* 전표를 PO/Item 기준 집계의 시작 데이터로 사용
* =====================================================================
*3. 선급요청 조회
SELECT A~LIFNR,
C~NAME1,
A~EBELN,
A~EBELP,
A~BELNR,
A~WRBTR,
B~WAERS,
A~GJAHR
FROM BSEG AS A INNER JOIN BKPF AS B ON A~BUKRS = B~BUKRS
AND A~BELNR = B~BELNR
AND A~GJAHR = B~GJAHR
LEFT OUTER JOIN LFA1 AS C ON A~LIFNR EQ C~LIFNR
INTO TABLE @DATA(LT_DP_REQUEST)
WHERE (LT_WHERE_CLAUSES).
IF LT_DP_REQUEST IS INITIAL.
MESSAGE '조회된 데이터가 없습니다.' TYPE 'S' DISPLAY LIKE 'E'. EXIT.
ENDIF.
*=====================================================================
*STEP 4. PO/Item 단위 집계 " 동일 PO/Item의 여러 요청 전표를 하나로 집계
*=====================================================================
*4. PO/ITEM 그룹핑
LOOP AT LT_DP_REQUEST INTO DATA(LS_REQ).
READ TABLE LT_OUTPUT ASSIGNING FIELD-SYMBOL(<FS_OUT>)
WITH KEY EBELN = LS_REQ-EBELN EBELP = LS_REQ-EBELP.
IF SY-SUBRC <> 0.
APPEND INITIAL LINE TO LT_OUTPUT ASSIGNING <FS_OUT>.
<FS_OUT>-LIFNR = LS_REQ-LIFNR. <FS_OUT>-NAME1 = LS_REQ-NAME1.
<FS_OUT>-EBELN = LS_REQ-EBELN. <FS_OUT>-EBELP = LS_REQ-EBELP.
<FS_OUT>-WAERS = LS_REQ-WAERS.
ENDIF.
IF NOT <FS_OUT>-REQ_BELNR CS LS_REQ-BELNR.
IF <FS_OUT>-REQ_BELNR IS INITIAL.
<FS_OUT>-REQ_BELNR = |{ LS_REQ-BELNR }({ LS_REQ-GJAHR })|.
ELSE.
<FS_OUT>-REQ_BELNR = |{ <FS_OUT>-REQ_BELNR }, { LS_REQ-BELNR }({ LS_REQ-GJAHR })|.
ENDIF.
ENDIF.
<FS_OUT>-REQ_AMT = <FS_OUT>-REQ_AMT + LS_REQ-WRBTR.
ENDLOOP.
*=====================================================================
*STEP 5. 선급금 지급 조회 " GL 0011050102 : 선급금_수입 " 차변(SHKZG='S')
*기준 실제 지급액 집계
*=====================================================================
*5. 선급지급 정보 조회
SELECT A~EBELN,
A~EBELP,
A~WRBTR,
A~BELNR,
A~GJAHR,
A~BUZEI
FROM BSEG AS A INNER JOIN BKPF AS B ON A~BUKRS = B~BUKRS
AND A~BELNR = B~BELNR
AND A~GJAHR = B~GJAHR
FOR ALL ENTRIES IN @LT_OUTPUT
WHERE A~BUKRS = @P_BUKRS
AND A~HKONT = '0011050102'
AND A~EBELN = @LT_OUTPUT-EBELN
AND A~EBELP = @LT_OUTPUT-EBELP
AND B~STBLG = ''
AND A~SHKZG = 'S'
INTO TABLE @DATA(LT_PAY_PRE_RAW).
LOOP AT LT_PAY_PRE_RAW INTO DATA(LS_PRE).
MOVE-CORRESPONDING LS_PRE TO LT_PAY. COLLECT LT_PAY.
ENDLOOP.
*=====================================================================
*STEP 6. 선금반제(F-54) 및 CBO 검증 " GL 0011050102 대변 반제내역과
*ZIMTP00/01 매핑 확인
*=====================================================================
*6. 선급금 반제 정보 및 CBO 데이터 수집
IF LT_OUTPUT IS NOT INITIAL.
SELECT A~EBELN,
A~EBELP,
A~BELNR,
A~GJAHR,
A~WRBTR,
A~BUZEI
FROM BSEG AS A INNER JOIN BKPF AS B ON A~BUKRS = B~BUKRS
AND A~BELNR = B~BELNR
AND A~GJAHR = B~GJAHR
FOR ALL ENTRIES IN @LT_OUTPUT
WHERE A~BUKRS = @P_BUKRS
AND A~HKONT = '0011050102'
AND A~EBELN = @LT_OUTPUT-EBELN
AND A~EBELP = @LT_OUTPUT-EBELP
AND B~STBLG = ''
AND A~SHKZG = 'H'
INTO TABLE @DATA(LT_PRE_OFFSET).
IF LT_PRE_OFFSET IS NOT INITIAL.
SELECT ZCLNO,
ZCLYR,
ZIMPNO
FROM ZIMTP00
FOR ALL ENTRIES IN @LT_PRE_OFFSET
WHERE ZCLNO = @LT_PRE_OFFSET-BELNR
AND ZCLYR = @LT_PRE_OFFSET-GJAHR
INTO TABLE @LT_CBO_HEAD.
IF LT_CBO_HEAD IS NOT INITIAL.
SELECT ZIMPNO,
EBELN,
EBELP
FROM ZIMTP01
FOR ALL ENTRIES IN @LT_CBO_HEAD
WHERE ZIMPNO = @LT_CBO_HEAD-ZIMPNO
INTO TABLE @LT_CBO_ITEM.
ENDIF.
ENDIF.
ENDIF.
*=====================================================================
*STEP 7. MM/FI 송장 조회 " RBKP-VGART = 'RD' => 물류송장만 조회
*=====================================================================
*7. MM/FI 송장 연계 조회
SELECT A~EBELN,
A~EBELP,
A~BELNR,
A~GJAHR,
A~WRBTR
FROM RSEG AS A INNER JOIN RBKP AS B ON A~BELNR = B~BELNR
AND A~GJAHR = B~GJAHR
FOR ALL ENTRIES IN @LT_OUTPUT
WHERE A~EBELN = @LT_OUTPUT-EBELN
AND A~EBELP = @LT_OUTPUT-EBELP
AND B~VGART = 'RD'
AND A~KSCHL = ''
AND B~STBLG = ''
INTO TABLE @DATA(LT_MM_INV).
IF LT_MM_INV IS NOT INITIAL.
TYPES: BEGIN OF TY_AWKEY,
AWKEY TYPE BKPF-AWKEY,
END OF TY_AWKEY.
DATA: LT_AWKEY TYPE TABLE OF TY_AWKEY.
LOOP AT LT_MM_INV INTO DATA(LS_MI).
APPEND VALUE #( AWKEY = |{ LS_MI-BELNR }{ LS_MI-GJAHR }| ) TO LT_AWKEY.
ENDLOOP.
SORT LT_AWKEY BY AWKEY. DELETE ADJACENT DUPLICATES FROM LT_AWKEY.
SELECT BELNR,
GJAHR,
AWKEY
FROM BKPF
FOR ALL ENTRIES IN @LT_AWKEY
WHERE BUKRS = @P_BUKRS
AND AWKEY = @LT_AWKEY-AWKEY
AND STBLG = ''
INTO TABLE @DATA(LT_FI_DOCS).
IF LT_FI_DOCS IS NOT INITIAL.
SELECT BELNR,
GJAHR,
BUZEI,
WRBTR
FROM RSEG
FOR ALL ENTRIES IN @LT_MM_INV
WHERE BELNR = @LT_MM_INV-BELNR
AND GJAHR = @LT_MM_INV-GJAHR
AND KSCHL = ''
INTO TABLE @DATA(LT_RSEG_RAW).
LOOP AT LT_RSEG_RAW INTO DATA(LS_RRAW).
COLLECT VALUE TY_RSEG_TOT( BELNR = LS_RRAW-BELNR GJAHR = LS_RRAW-GJAHR WRBTR = LS_RRAW-WRBTR ) INTO LT_RSEG_TOT.
ENDLOOP.
SELECT BELNR,
GJAHR,
BUZEI,
AUGBL
FROM BSEG
FOR ALL ENTRIES IN @LT_FI_DOCS
WHERE BUKRS = @P_BUKRS
AND BELNR = @LT_FI_DOCS-BELNR
AND GJAHR = @LT_FI_DOCS-GJAHR
AND KOART = 'K'
INTO TABLE @DATA(LT_FI_VEND).
ENDIF.
ENDIF.
*=====================================================================
*STEP 8. 은행 지급 확인 " 보통예금_외화 GL(0011010202) 지급 여부 확인
*=====================================================================
*8. 은행 지급용 BSE_CLR 조회
IF LT_FI_VEND IS NOT INITIAL.
SELECT A~BUKRS,
A~BELNR,
A~GJAHR,
A~BUZEI,
A~BELNR_CLR,
A~GJAHR_CLR,
A~WRBTR,
A~DIFFW,
A~CLRIN
FROM BSE_CLR AS A INNER JOIN BKPF AS B ON A~BUKRS = B~BUKRS
AND A~BELNR_CLR = B~BELNR
AND A~GJAHR_CLR = B~GJAHR
FOR ALL ENTRIES IN @LT_FI_VEND
WHERE A~BUKRS = @P_BUKRS
AND A~BELNR = @LT_FI_VEND-BELNR
AND A~GJAHR = @LT_FI_VEND-GJAHR
AND A~BUZEI = @LT_FI_VEND-BUZEI
AND B~STBLG = ''
INTO TABLE @DATA(LT_BSE_CLR).
IF LT_BSE_CLR IS NOT INITIAL.
SELECT BELNR AS BELNR_CLR,
GJAHR AS GJAHR_CLR
FROM BSEG
FOR ALL ENTRIES IN @LT_BSE_CLR
WHERE BUKRS = @P_BUKRS
AND BELNR = @LT_BSE_CLR-BELNR_CLR
AND GJAHR = @LT_BSE_CLR-GJAHR_CLR
AND HKONT = '0011010202'
INTO TABLE @DATA(LT_BANK_CHK).
SORT LT_BANK_CHK BY BELNR_CLR GJAHR_CLR.
ENDIF.
ENDIF.
*=====================================================================
*STEP 9. 최종 집계 및 검증
*선급/반제/송장/은행지급을 비교하여 상태(REMARK) 결정
*=====================================================================
*9. 최종 집계 및 비고 판단
LOOP AT LT_OUTPUT ASSIGNING <FS_OUT>. " 선급금 지급 집계
LOOP AT LT_PAY WHERE EBELN = <FS_OUT>-EBELN AND EBELP = <FS_OUT>-EBELP.
<FS_OUT>-PRE_AMT = <FS_OUT>-PRE_AMT + LT_PAY-WRBTR.
IF NOT <FS_OUT>-PRE_BELNR CS LT_PAY-BELNR.
IF <FS_OUT>-PRE_BELNR IS INITIAL.
<FS_OUT>-PRE_BELNR = |{ LT_PAY-BELNR }({ LT_PAY-GJAHR })|.
ELSE.
<FS_OUT>-PRE_BELNR = |{ <FS_OUT>-PRE_BELNR }, { LT_PAY-BELNR }({ LT_PAY-GJAHR })|.
ENDIF.
ENDIF.
ENDLOOP.
" CBO Mismatch 검증
DATA: LV_ZIMP_LIST TYPE STRING, LV_CBO_ERROR TYPE STRING.
CLEAR: LV_ZIMP_LIST, LV_CBO_ERROR.
LOOP AT LT_PRE_OFFSET INTO DATA(LS_OFF) WHERE EBELN = <FS_OUT>-EBELN AND EBELP = <FS_OUT>-EBELP.
<FS_OUT>-CLR_PRE_AMT = <FS_OUT>-CLR_PRE_AMT + LS_OFF-WRBTR.
IF NOT <FS_OUT>-CLR_PRE_BEL CS LS_OFF-BELNR.
IF <FS_OUT>-CLR_PRE_BEL IS INITIAL.
<FS_OUT>-CLR_PRE_BEL = |{ LS_OFF-BELNR }({ LS_OFF-GJAHR })|.
ELSE.
<FS_OUT>-CLR_PRE_BEL = |{ <FS_OUT>-CLR_PRE_BEL }, { LS_OFF-BELNR }({ LS_OFF-GJAHR })|.
ENDIF.
ENDIF.
" 해당 전표와 연결된 수입 번호를 뒤져서 현재 PO 항목이 없는지 체크
LOOP AT LT_CBO_HEAD INTO DATA(LS_HEAD) WHERE ZCLNO = LS_OFF-BELNR AND ZCLYR = LS_OFF-GJAHR.
IF NOT LV_ZIMP_LIST CS LS_HEAD-ZIMPNO.
IF LV_ZIMP_LIST IS INITIAL.
LV_ZIMP_LIST = LS_HEAD-ZIMPNO.
ELSE.
LV_ZIMP_LIST = |{ LV_ZIMP_LIST }, { LS_HEAD-ZIMPNO }|.
ENDIF.
ENDIF.
" 하나라도 매칭되지 않는 전표가 발견되면 즉시 에러
READ TABLE LT_CBO_ITEM WITH KEY ZIMPNO = LS_HEAD-ZIMPNO EBELN = <FS_OUT>-EBELN EBELP = <FS_OUT>-EBELP TRANSPORTING NO FIELDS.
IF SY-SUBRC <> 0.
LV_CBO_ERROR = |{ LS_HEAD-ZIMPNO }에 { <FS_OUT>-EBELN }/{ <FS_OUT>-EBELP }이 없습니다.|.
EXIT. " 헤더 루프 탈출
ENDIF.
ENDLOOP.
IF LV_CBO_ERROR IS NOT INITIAL. EXIT. ENDIF. " 오프셋 루프 탈출
ENDLOOP.
IF LV_CBO_ERROR IS NOT INITIAL.
<FS_OUT>-REMARK = LV_CBO_ERROR.
<FS_OUT>-LINE_COLOR = 'C610'.
ENDIF.
" 송장 및 은행 지급액 배분
DATA: LV_HAS_OPEN(1), LV_HAS_CLEARED(1).
CLEAR: LV_TOT_ALLOCATED_CLR, LV_TMP_BANK_BELNR, LV_HAS_OPEN, LV_HAS_CLEARED.
LOOP AT LT_MM_INV INTO DATA(LS_INV) WHERE EBELN = <FS_OUT>-EBELN AND EBELP = <FS_OUT>-EBELP.
<FS_OUT>-AP_AMT = <FS_OUT>-AP_AMT + LS_INV-WRBTR.
READ TABLE LT_FI_DOCS INTO DATA(LS_FI) WITH KEY AWKEY = |{ LS_INV-BELNR }{ LS_INV-GJAHR }|.
IF SY-SUBRC = 0.
IF NOT <FS_OUT>-AP_FI_BELNR CS LS_FI-BELNR.
IF <FS_OUT>-AP_FI_BELNR IS INITIAL.
<FS_OUT>-AP_FI_BELNR = |{ LS_FI-BELNR }({ LS_FI-GJAHR })|.
ELSE.
<FS_OUT>-AP_FI_BELNR = |{ <FS_OUT>-AP_FI_BELNR }, { LS_FI-BELNR }({ LS_FI-GJAHR })|.
ENDIF.
ENDIF.
CLEAR: LV_INV_BANK_TOT, LV_INV_TOT.
READ TABLE LT_RSEG_TOT INTO DATA(LS_RTOT) WITH KEY BELNR = LS_FI-AWKEY(10) GJAHR = LS_FI-AWKEY+10(4).
IF SY-SUBRC = 0. LV_INV_TOT = LS_RTOT-WRBTR. ENDIF.
LOOP AT LT_FI_VEND INTO DATA(LS_VEND) WHERE BELNR = LS_FI-BELNR AND GJAHR = LS_FI-GJAHR.
IF LS_VEND-AUGBL IS INITIAL.
LV_HAS_OPEN = 'X'. " 미반제 건 존재
ELSE.
LV_HAS_CLEARED = 'X'. " 정상 반제 됨
ENDIF.
LOOP AT LT_BSE_CLR INTO DATA(LS_CLR) WHERE BELNR = LS_VEND-BELNR AND GJAHR = LS_VEND-GJAHR AND BUZEI = LS_VEND-BUZEI.
READ TABLE LT_BANK_CHK TRANSPORTING NO FIELDS WITH KEY BELNR_CLR = LS_CLR-BELNR_CLR GJAHR_CLR = LS_CLR-GJAHR_CLR BINARY SEARCH.
IF SY-SUBRC = 0.
DATA(LV_CB) = COND BSEG-WRBTR( WHEN LS_CLR-CLRIN = SPACE THEN LS_CLR-WRBTR ELSE LS_CLR-WRBTR - LS_CLR-DIFFW ).
LV_INV_BANK_TOT = LV_INV_BANK_TOT + LV_CB.
IF NOT LV_TMP_BANK_BELNR CS LS_CLR-BELNR_CLR.
IF LV_TMP_BANK_BELNR IS INITIAL.
LV_TMP_BANK_BELNR = |{ LS_CLR-BELNR_CLR }({ LS_CLR-GJAHR_CLR })|.
ELSE.
LV_TMP_BANK_BELNR = |{ LV_TMP_BANK_BELNR }, { LS_CLR-BELNR_CLR }({ LS_CLR-GJAHR_CLR })|.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDLOOP.
IF LV_INV_BANK_TOT > 0 AND LV_INV_TOT > 0.
LV_TOT_ALLOCATED_CLR = LV_TOT_ALLOCATED_CLR + ( LV_INV_BANK_TOT * ( LS_INV-WRBTR / LV_INV_TOT ) ).
ENDIF.
ENDIF.
ENDLOOP.
" 잔액 및 추가 비고
IF LV_TOT_ALLOCATED_CLR > 0.
DATA(LV_R) = LV_TOT_ALLOCATED_CLR - <FS_OUT>-PRE_AMT.
IF LV_R <= 0.
LV_R = 0. CLEAR <FS_OUT>-BANK_BELNR.
ELSE.
<FS_OUT>-BANK_BELNR = LV_TMP_BANK_BELNR.
ENDIF.
<FS_OUT>-BANK_AMT = LV_R.
ENDIF.
<fS_OUT>-BAL_PRE_AMT = <fS_OUT>-PRE_AMT - <fS_OUT>-CLR_PRE_AMT.
<FS_OUT>-VAL_AMT = <FS_OUT>-AP_AMT - <FS_OUT>-PRE_AMT - <FS_OUT>-BANK_AMT.
" 비고 덮어쓰기 방지
IF <FS_OUT>-REMARK IS NOT INITIAL. CONTINUE. ENDIF.
IF <FS_OUT>-AP_AMT = 0.
IF <FS_OUT>-REQ_AMT > 0.
IF <FS_OUT>-PRE_AMT >= <FS_OUT>-REQ_AMT.
<FS_OUT>-REMARK = '선급지급완료 (송장대기)'.
ELSE.
<FS_OUT>-REMARK = '선급지급중'.
ENDIF.
ENDIF.
ELSE.
IF <FS_OUT>-CLR_PRE_AMT > <FS_OUT>-PRE_AMT.
<FS_OUT>-REMARK = '!! 선금반제 오류 (선급금 초과) !!'. <FS_OUT>-LINE_COLOR = 'C610'.
ELSEIF <FS_OUT>-PRE_AMT > 0 AND <FS_OUT>-CLR_PRE_BEL IS INITIAL.
<FS_OUT>-REMARK = '!! 선금반제(F-54) 처리 누락 !!'. <FS_OUT>-LINE_COLOR = 'C610'.
ELSEIF <FS_OUT>-VAL_AMT BETWEEN -1 AND 1.
IF <FS_OUT>-CLR_PRE_AMT < <FS_OUT>-PRE_AMT.
<FS_OUT>-REMARK = '!! 선금반제 오류 (선급금 미달) !!'. <FS_OUT>-LINE_COLOR = 'C610'.
ELSE.
IF <FS_OUT>-BANK_AMT = 0.
<FS_OUT>-REMARK = '정상 처리 완료 (상계완료)'.
ELSE.
<FS_OUT>-REMARK = '정상 처리 완료 (추가지급완료)'.
ENDIF.
ENDIF.
ELSEIF <FS_OUT>-VAL_AMT > 1.
IF LV_HAS_OPEN = 'X' AND LV_HAS_CLEARED = 'X'.
<FS_OUT>-REMARK = '추가 지급 필요 (일부 송장 미반제)'.
ELSEIF LV_HAS_OPEN = 'X'.
<FS_OUT>-REMARK = '추가 지급 필요 (미지급)'.
ELSE.
<FS_OUT>-OFF_AMT = <FS_OUT>-VAL_AMT.
CLEAR <FS_OUT>-VAL_AMT.
<FS_OUT>-REMARK = '정상 처리 완료 (상계완료)'.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
SORT LT_OUTPUT BY REMARK LIFNR EBELN EBELP.
PERFORM BUILD_FIELDCAT.
PERFORM DISPLAY_ALV.
"----------------------------------------------------------------------
FORM BUILD_FIELDCAT.
DATA: LS_FCAT TYPE SLIS_FIELDCAT_ALV.
DEFINE ADD_COL.
CLEAR LS_FCAT. LS_FCAT-FIELDNAME = &1. LS_FCAT-SELTEXT_L = &2.
IF &1 CP '*AMT*'. LS_FCAT-DO_SUM = 'X'. LS_FCAT-CFIELDNAME = 'WAERS'. ENDIF.
APPEND LS_FCAT TO LT_FCAT.
END-OF-DEFINITION.
ADD_COL 'LIFNR' '구매처'.
ADD_COL 'NAME1' '구매처명'.
ADD_COL 'EBELN' 'PO번호'.
ADD_COL 'EBELP' '항목'.
ADD_COL 'REQ_BELNR' '선급요청전표'.
ADD_COL 'REQ_AMT' '선급요청액'.
ADD_COL 'PRE_BELNR' '선급지급전표'.
ADD_COL 'PRE_AMT' '선급지급액(A)'.
ADD_COL 'CLR_PRE_BEL' '선금반제전표'.
ADD_COL 'CLR_PRE_AMT' '선금반제합계(Z)'.
ADD_COL 'BAL_PRE_AMT' '선급잔액(A-Z)'.
ADD_COL 'AP_FI_BELNR' '송장회계전표'.
ADD_COL 'AP_AMT' '물품송장합계(B)'.
ADD_COL 'BANK_BELNR' '은행지급전표'.
ADD_COL 'BANK_AMT' '은행지급액(C)'.
ADD_COL 'OFF_AMT' '상계금액(D)'.
ADD_COL 'VAL_AMT' '검증잔액(B-A-C-D)'.
ADD_COL 'REMARK' '비고'.
ENDFORM.
FORM DISPLAY_ALV.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
IS_LAYOUT = VALUE SLIS_LAYOUT_ALV( ZEBRA = 'X' COLWIDTH_OPTIMIZE = 'X' INFO_FIELDNAME = 'LINE_COLOR' )
IT_FIELDCAT = LT_FCAT
TABLES
T_OUTTAB = LT_OUTPUT.
ENDFORM.반응형
'IT WORK > SAP FI and ABAP' 카테고리의 다른 글
| [SAP FI] GL 계정 대체 (0) | 2026.05.28 |
|---|---|
| [FI/SD] SD 청구문서 -> FI 회계문서 GL계정 매핑 확인 (0) | 2026.05.14 |
| [SAP FI] 라인 아이템 있는 / 없는 반제 전표 (1) | 2026.04.24 |
| [SAP ABAP] SAP Script Painter (SE71)에 전역변수 추가하기 (F110 지급매체 출력시 reguh-zstra에 35자 넘는 주소 출력하기) (0) | 2026.02.03 |
| [SAP FI] BP 민감필드 설정 되어있어도 일부 경우 자동 승인되도록 하는 로직 (0) | 2026.01.28 |