Add JavaSrc: cobol-tna-system COBOL->Java conversion (ZAN01-06/KIN01-09/KYU01-09 + 变换规则 doc)
This commit is contained in:
@@ -0,0 +1,413 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import dto.Kyu04Rec;
|
||||
import dto.Kyu05Rec;
|
||||
import dto.Kyu99Rec;
|
||||
import dto.ZandatacPar;
|
||||
import dto.ZanendacPar;
|
||||
import dto.ZanmsgacPar;
|
||||
import util.ConvUtil;
|
||||
|
||||
/**
|
||||
* ============================================================
|
||||
* 【COBOL→Java】KYU08PRI 給与明細印刷処理
|
||||
* ============================================================
|
||||
* PROGRAM-ID. KYU08PRI → 类 Kyu08PriMain(PGMパターン:レイアウト編集のみ GETPUT)
|
||||
*
|
||||
* 使用ファイル(SELECT ASSIGN → パス定数):
|
||||
* R01INNFIL(KYU08R01 SALARY-NET F200B 入力) → R01INN_FILE(COPY KYU04REC → dto.Kyu04Rec)
|
||||
* W01OUTFIL(KYU08W01 PAYSLIP F200B 出力) → W01OUT_FILE(COPY KYU05REC → dto.Kyu05Rec)
|
||||
* W02OUTFIL(KYU08W02 ERROR-LOG VB200B 出力)→ W02OUT_FILE(COPY KYU99REC → dto.Kyu99Rec、将来拡張・現状出力なし)
|
||||
*
|
||||
* 使用SUB(CALL → 类#execute):
|
||||
* SUB01DAT→Sub01DatSub / SUB02MSG→Sub02MsgSub / SUB03END→Sub03EndSub
|
||||
*
|
||||
* 段落対応:
|
||||
* 0000MAJCOLSOR→run() 1000ITTSOR→initPara() 1100R01INNSOR→readR01Para()
|
||||
* 2000MAJSOR→majPara() 3000STPSOR→termPara() 4000MSGOUTSOR→msgOutPara()
|
||||
* 9999ABDSOR→abendPara()
|
||||
*
|
||||
* 処理要点(詳細設計書_KYU08PRI 準拠):
|
||||
* - 1社員1ページ。ヘッダ行→明細行→フッタ行を 200B 固定長で順次出力(LINAGE 66行/ページ相当)。
|
||||
* - ヘッダ行:HL-TITLE('========== 給与明細書 ==========') + ページ番号(Z(03)9) + 'PG'。
|
||||
* - 明細行:DETAIL-LINE は KYU05REC 布局と一致(PAGE-TITLE=SPACE)するため Kyu05Rec で編集。
|
||||
* EMP-NAME は X(020) JUSTIFIED RIGHT、BASIC/NET は Z(008)9 BLANK WHEN ZERO で編集。
|
||||
* - フッタ行:FL-MSG('--- 明細終了 ---')。
|
||||
* - COBOL は LINAGE/ADVANCING PAGE を用いるが、Java 平文テキスト出力では 200B 行の連続書出とし
|
||||
* ページ制御(フォームフィード等)は行わない(設計上 1社員1ページのため実害なし)。
|
||||
* - W02(ERROR-LOG) は OPEN OUTPUT のみ(現状 WRITE なし/将来拡張)。
|
||||
*/
|
||||
public class Kyu08PriMain {
|
||||
|
||||
// ==================== コンスタント領域 CNSARA ====================
|
||||
|
||||
/** 03 CNS-PRGIDX PIC X(008) VALUE 'KYU08PRI'. */
|
||||
private static final String CST_PRGIDX = "KYU08PRI";
|
||||
/** 03 CNS-MSGSTR PIC 9(003) VALUE 001. 開始メッセージ */
|
||||
private static final int CST_MSGSTR = 1;
|
||||
/** 03 CNS-MSGFIN PIC 9(003) VALUE 002. 終了メッセージ */
|
||||
private static final int CST_MSGFIN = 2;
|
||||
/** 03 CNS-MSGSUBEEK PIC 9(003) VALUE 005. サブエラーメッセージ */
|
||||
private static final int CST_MSGSUBEEK = 5;
|
||||
/** 03 CNS-MSGIINKES PIC 9(003) VALUE 006. 入力件数メッセージ */
|
||||
private static final int CST_MSGIINKES = 6;
|
||||
/** 03 CNS-MSGOUTKES PIC 9(003) VALUE 007. 出力件数メッセージ */
|
||||
private static final int CST_MSGOUTKES = 7;
|
||||
/** 03 CNS-MSGKEYINF PIC 9(003) VALUE 033. コンパイル日時メッセージ */
|
||||
private static final int CST_MSGKEYINF = 33;
|
||||
/** 03 CNS-KN0002 PIC 9(001) VALUE 2. */
|
||||
private static final int CST_KN0002 = 2;
|
||||
/** 03 CNS-ABD999 PIC 9(003) VALUE 999. */
|
||||
private static final int CST_ABD999 = 999;
|
||||
/** 03 CNS-HEADER-LINES PIC 9(002) VALUE 6. (LINAGE TOP 相当・参照用) */
|
||||
private static final int CST_HEADER_LINES = 6;
|
||||
/** 03 CNS-DETAIL-LINES PIC 9(002) VALUE 54. (LINAGE 明細相当・参照用) */
|
||||
private static final int CST_DETAIL_LINES = 54;
|
||||
/** 03 CNS-FOOTER-LINES PIC 9(002) VALUE 6. (LINAGE BOTTOM 相当・参照用) */
|
||||
private static final int CST_FOOTER_LINES = 6;
|
||||
|
||||
// ==================== ファイル定義(SELECT ASSIGN 相当) ====================
|
||||
|
||||
/** SELECT R01INNFIL ASSIGN TO KYU08R01.(SALARY-NET 入力 F200B) */
|
||||
private static final String R01INN_FILE = "data/KYU08R01.txt";
|
||||
/** SELECT W01OUTFIL ASSIGN TO KYU08W01.(PAYSLIP 出力 F200B) */
|
||||
private static final String W01OUT_FILE = "data/KYU08W01.txt";
|
||||
/** SELECT W02OUTFIL ASSIGN TO KYU08W02.(ERROR-LOG 出力 VB200B・現状出力なし) */
|
||||
private static final String W02OUT_FILE = "data/KYU08W02.txt";
|
||||
|
||||
// ==================== カウンタ領域 CUNARA(COMP-3 → long) ====================
|
||||
|
||||
/** 03 CUN-R01INN PIC S9(009) COMP-3 VALUE ZERO. */
|
||||
private long cunR01Inn;
|
||||
/** 03 CUN-W01OUT PIC S9(009) COMP-3 VALUE ZERO. */
|
||||
private long cunW01Out;
|
||||
/** 03 CUN-W02OUT PIC S9(009) COMP-3 VALUE ZERO. */
|
||||
private long cunW02Out;
|
||||
|
||||
// ==================== 作業領域 WRKARA ====================
|
||||
|
||||
/** 03 WRK-EOF PIC X(001). 読込フラグ(88 WRK-EOF-Y VALUE '1') */
|
||||
private String wrkEof = "0";
|
||||
/** 03 WRK-LINE-NO PIC 9(002). */
|
||||
private int wrkLineNo;
|
||||
/** 03 WRK-PAGE-COUNTER PIC 9(004) VALUE 0. */
|
||||
private int wrkPageCounter = 0;
|
||||
/** 03 WS-PAD-CHAR PIC X(001) VALUE SPACE. */
|
||||
private String wsPadChar = " ";
|
||||
/** 03 WS-FILE-STATUS PIC X(002). */
|
||||
private String wsFileStatus = "";
|
||||
/** 03 WS-DISP-PG PIC Z(03)9. (HL-PAGE-NO 編集用・参照用) */
|
||||
private int wsDispPg;
|
||||
|
||||
/** 88 WRK-EOF-Y VALUE '1'. */
|
||||
private boolean isEof() {
|
||||
return "1".equals(wrkEof);
|
||||
}
|
||||
|
||||
// ==================== サブプログラム連絡領域(LINKAGE COPY → DTO) ====================
|
||||
|
||||
/** COPY ZANMSGAC.(SUB02MSG用) */
|
||||
private final ZanmsgacPar m00MhoPar = new ZanmsgacPar();
|
||||
/** COPY ZANENDAC.(SUB03END用) */
|
||||
private final ZanendacPar e01AbdPar = new ZanendacPar();
|
||||
/** COPY ZANDATAC.(SUB01DAT用) */
|
||||
private final ZandatacPar d01UbsPar = new ZandatacPar();
|
||||
|
||||
// ==================== 入出力レコード(FILE SECTION → DTO) ====================
|
||||
|
||||
/** 01 R01INNREC.(FD R01INNFIL / COPY KYU04REC) */
|
||||
private final Kyu04Rec r01 = new Kyu04Rec();
|
||||
/** 01 W01OUTREC.(FD W01OUTFIL / COPY KYU05REC) */
|
||||
private final Kyu05Rec w01 = new Kyu05Rec();
|
||||
/** 01 W02OUTREC.(FD W02OUTFIL / COPY KYU99REC) */
|
||||
private final Kyu99Rec w02 = new Kyu99Rec();
|
||||
|
||||
// ==================== ファイルハンドル(OPEN/CLOSE 相当) ====================
|
||||
|
||||
private BufferedReader r01InnFil;
|
||||
private PrintWriter w01OutFil;
|
||||
private PrintWriter w02OutFil;
|
||||
|
||||
// ==================== PROCEDURE DIVISION ====================
|
||||
|
||||
public static void main(final String[] args) {
|
||||
new Kyu08PriMain().run();
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 0000MAJCOLSOR:制御処理。
|
||||
* PERFORM 1000ITTSOR → PERFORM 2000MAJSOR UNTIL WRK-EOF-Y → PERFORM 3000STPSOR → GOBACK.
|
||||
*/
|
||||
private void run() {
|
||||
try {
|
||||
initPara();
|
||||
while (!isEof()) { // PERFORM 2000MAJSOR UNTIL WRK-EOF = '1'
|
||||
majPara();
|
||||
}
|
||||
termPara();
|
||||
} finally {
|
||||
closeFiles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 1000ITTSOR:初期処理。
|
||||
* 開始メッセージ→コンパイル日時→ワーク初期化→SUB01DAT→OPEN→初回読込。
|
||||
*/
|
||||
private void initPara() {
|
||||
// *** 開始メッセージ出力
|
||||
// MOVE CNS-MSGSTR TO M00MSGCOD./PERFORM 4000MSGOUTSOR.
|
||||
msgOutPara(CST_MSGSTR, null, null);
|
||||
|
||||
// *** コンパイル日時出力 ※FUNCTION WHEN-COMPILED→起動時刻で代用
|
||||
// MOVE CNS-MSGKEYINF TO M00MSGCOD.
|
||||
// MOVE FUNCTION WHEN-COMPILED TO M00UMKDATS22-01.
|
||||
// MOVE 'COMPILED' TO M00UMKDATS22-02.
|
||||
final String compiled = java.time.LocalDateTime.now()
|
||||
.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
|
||||
msgOutPara(CST_MSGKEYINF, compiled, "COMPILED");
|
||||
|
||||
// *** ワークエリア初期化 INITIALIZE WRKARA.
|
||||
wrkEof = "0";
|
||||
wrkLineNo = 0;
|
||||
wrkPageCounter = 0;
|
||||
wsPadChar = " ";
|
||||
wsFileStatus = "";
|
||||
wsDispPg = 0;
|
||||
|
||||
// *** 運用日付取得 SUB01DAT
|
||||
// INITIALIZE D01UBSPAR./CALL 'SUB01DAT' USING D01UBSPAR.
|
||||
d01UbsPar.reset();
|
||||
Sub01DatSub.execute(d01UbsPar);
|
||||
if (d01UbsPar.getD01FkiCod() != 0) {
|
||||
// IF D01FKICOD NOT = ZERO
|
||||
// MOVE CNS-MSGSUBEEK TO M00MSGCOD
|
||||
// MOVE 'SUB01DAT' TO M00UMKDATS22-01
|
||||
// MOVE D01FKICOD TO M00UMKDATS22-02
|
||||
// PERFORM 4000MSGOUTSOR
|
||||
// PERFORM 9999ABDSOR
|
||||
msgOutPara(CST_MSGSUBEEK, "SUB01DAT",
|
||||
ConvUtil.padLeftZero(d01UbsPar.getD01FkiCod(), 4));
|
||||
abendPara();
|
||||
return;
|
||||
}
|
||||
|
||||
// *** 使用ファイルのオープン
|
||||
// OPEN INPUT R01INNFIL./OPEN OUTPUT W01OUTFIL W02OUTFIL.
|
||||
openFiles();
|
||||
|
||||
// *** R01 初回読込(1100R01INNSOR)
|
||||
readR01Para();
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 1100R01INNSOR:R01読込処理。
|
||||
* READ R01INNFIL AT END SET WRK-EOF-Y / NOT AT END ADD 1 TO CUN-R01INN.
|
||||
*/
|
||||
private void readR01Para() {
|
||||
try {
|
||||
final String line = r01InnFil.readLine();
|
||||
if (line == null) {
|
||||
// AT END: SET WRK-EOF-Y TO TRUE.
|
||||
wrkEof = "1";
|
||||
} else {
|
||||
// NOT AT END: 固定長解析 → R01INNREC、ADD 1 TO CUN-R01INN.
|
||||
r01.parseRecord(line);
|
||||
cunR01Inn++;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e); // READ異常 ≈ ABEND
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 2000MAJSOR:主処理。
|
||||
* ヘッダ出力(改ページ+ページ番号)→明細行編集・出力→フッタ出力(改ページ)→次レコード読込。
|
||||
*/
|
||||
private void majPara() {
|
||||
// *** ページカウンタ加算
|
||||
// ADD 1 TO WRK-PAGE-COUNTER.
|
||||
wrkPageCounter++;
|
||||
// MOVE WRK-PAGE-COUNTER TO HL-PAGE-NO./MOVE WRK-PAGE-COUNTER TO WS-DISP-PG.
|
||||
wsDispPg = wrkPageCounter;
|
||||
|
||||
// *** ヘッダ出力(BEFORE ADVANCING PAGE)
|
||||
// WRITE W01OUTREC FROM HEADER-LINE BEFORE ADVANCING PAGE.
|
||||
w01OutFil.println(buildHeaderLine(wrkPageCounter));
|
||||
|
||||
// *** 明細行編集(DETAIL-LINE ≡ KYU05REC 布局:PAGE-TITLE=SPACE)
|
||||
// MOVE R01EMP-ID TO DL-EMP-ID.
|
||||
// MOVE R01EMP-NAME TO DL-EMP-NAME.
|
||||
// MOVE R01GROSS-PAYMENT TO DL-BASIC-SALARY.
|
||||
// MOVE R01NET-PAYMENT TO DL-NET-PAYMENT.
|
||||
w01.reset();
|
||||
w01.setW01EmpId(r01.getR01EmpId());
|
||||
w01.setW01EmpName(r01.getR01EmpName());
|
||||
w01.setW01BasicSalary((int) r01.getR01GrossPayment());
|
||||
w01.setW01NetPayment((int) r01.getR01NetPayment());
|
||||
w01.setW01PageTitle(""); // 明細行の PAGE-TITLE は SPACE
|
||||
|
||||
// WRITE W01OUTREC FROM DETAIL-LINE BEFORE ADVANCING 1 LINE
|
||||
// AT END-OF-PAGE WRITE W01OUTREC FROM FOOTER-LINE BEFORE ADVANCING PAGE.
|
||||
// (1社員1ページのため AT END-OF-PAGE は発動しない)
|
||||
w01OutFil.println(w01.toRecordLine());
|
||||
// ADD 1 TO CUN-W01OUT.
|
||||
cunW01Out++;
|
||||
|
||||
// *** フッタ出力(BEFORE ADVANCING PAGE)
|
||||
// WRITE W01OUTREC FROM FOOTER-LINE BEFORE ADVANCING PAGE.
|
||||
w01OutFil.println(buildFooterLine());
|
||||
|
||||
// *** 次レコード読込(1100R01INNSOR)
|
||||
readR01Para();
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 3000STPSOR:終了処理。
|
||||
* CLOSE→入出力件数メッセージ×3→終了メッセージ。
|
||||
*/
|
||||
private void termPara() {
|
||||
// *** 入出力ファイルのクローズ
|
||||
// CLOSE R01INNFIL W01OUTFIL W02OUTFIL.
|
||||
closeFiles();
|
||||
|
||||
// *** 入出力件数メッセージ出力
|
||||
// MOVE CNS-MSGIINKES TO M00MSGCOD. MOVE 'KYU08R01' TO PARM1. MOVE CUN-R01INN TO PARM2.
|
||||
msgOutPara(CST_MSGIINKES, "KYU08R01", ConvUtil.padLeftZero(cunR01Inn, 9));
|
||||
// MOVE CNS-MSGOUTKES TO M00MSGCOD. MOVE 'KYU08W01' TO PARM1. MOVE CUN-W01OUT TO PARM2.
|
||||
msgOutPara(CST_MSGOUTKES, "KYU08W01", ConvUtil.padLeftZero(cunW01Out, 9));
|
||||
// MOVE CNS-MSGOUTKES TO M00MSGCOD. MOVE 'KYU08W02' TO PARM1. MOVE CUN-W02OUT TO PARM2.
|
||||
msgOutPara(CST_MSGOUTKES, "KYU08W02", ConvUtil.padLeftZero(cunW02Out, 9));
|
||||
|
||||
// *** 終了メッセージ出力
|
||||
// MOVE CNS-MSGFIN TO M00MSGCOD./PERFORM 4000MSGOUTSOR.
|
||||
msgOutPara(CST_MSGFIN, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 4000MSGOUTSOR:メッセージ編集出力処理。
|
||||
* M00UMKDATS22-03(1:1)/-04(1:1) に '2'、-05 にプログラムIDを設定し SUB02MSG を呼ぶ。
|
||||
*/
|
||||
private void msgOutPara(final int msgCod, final String p1, final String p2) {
|
||||
m00MhoPar.reset();
|
||||
m00MhoPar.setM00MsgCod(msgCod);
|
||||
if (p1 != null) {
|
||||
m00MhoPar.setM00Umkdats2201(p1);
|
||||
}
|
||||
if (p2 != null) {
|
||||
m00MhoPar.setM00Umkdats2202(p2);
|
||||
}
|
||||
// MOVE CNS-KN0002 TO M00UMKDATS22-03(1:1). → 先頭1桁 '2' + 後続SPACE(30)
|
||||
m00MhoPar.setM00Umkdats2203(ConvUtil.padRight(Integer.toString(CST_KN0002), 30));
|
||||
// MOVE CNS-KN0002 TO M00UMKDATS22-04(1:1).
|
||||
m00MhoPar.setM00Umkdats2204(ConvUtil.padRight(Integer.toString(CST_KN0002), 30));
|
||||
// MOVE CNS-PRGIDX TO M00UMKDATS22-05.
|
||||
m00MhoPar.setM00Umkdats2205(CST_PRGIDX);
|
||||
Sub02MsgSub.execute(m00MhoPar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 段落 9999ABDSOR:ABEND処理。
|
||||
* MOVE 999 TO E01ABDCOD./CALL 'SUB03END' USING E01ABDPAR.
|
||||
*/
|
||||
private void abendPara() {
|
||||
e01AbdPar.reset();
|
||||
e01AbdPar.setE01AbdCod(CST_ABD999);
|
||||
Sub03EndSub.execute(e01AbdPar);
|
||||
}
|
||||
|
||||
// ==================== 印刷行編集補助(HEADER-LINE / FOOTER-LINE) ====================
|
||||
|
||||
/**
|
||||
* 01 HEADER-LINE 編集(200B)。
|
||||
* 05 HL-TITLE PIC X(040) VALUE '========== 給与明細書 =========='
|
||||
* 05 FILLER PIC X(010) VALUE SPACES
|
||||
* 05 HL-PAGE-NO PIC Z(03)9
|
||||
* 05 FILLER PIC X(002) VALUE 'PG'
|
||||
* 05 FILLER PIC X(144) VALUE SPACES
|
||||
*/
|
||||
private static String buildHeaderLine(final int pageNo) {
|
||||
// PIC Z(03)9 編集(4桁、先頭3桁ゼロ抑制)
|
||||
final String pageNoEd = editZ(pageNo, 3);
|
||||
return ConvUtil.padRight("========== 給与明細書 ==========", 40)
|
||||
+ ConvUtil.padRight("", 10)
|
||||
+ pageNoEd
|
||||
+ "PG"
|
||||
+ ConvUtil.padRight("", 144);
|
||||
}
|
||||
|
||||
/**
|
||||
* 01 FOOTER-LINE 編集(200B)。
|
||||
* 05 FL-MSG PIC X(040) VALUE '--- 明細終了 ---'
|
||||
* 05 FILLER PIC X(160) VALUE SPACES
|
||||
*/
|
||||
private static String buildFooterLine() {
|
||||
return ConvUtil.padRight("--- 明細終了 ---", 40)
|
||||
+ ConvUtil.padRight("", 160);
|
||||
}
|
||||
|
||||
/** PIC Z(n)9 BLANK WHEN ZERO 編集(編集桁数 = zCount + 1)。 */
|
||||
private static String editZ(final int val, final int zCount) {
|
||||
final int len = zCount + 1;
|
||||
if (val == 0) {
|
||||
// BLANK WHEN ZERO
|
||||
return ConvUtil.padRight("", len);
|
||||
}
|
||||
final String s = ConvUtil.padLeftZero(val, len);
|
||||
final char[] ca = s.toCharArray();
|
||||
for (int i = 0; i < zCount; i++) {
|
||||
if (ca[i] == '0') {
|
||||
ca[i] = ' ';
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new String(ca);
|
||||
}
|
||||
|
||||
// ==================== ファイル操作補助(OPEN/CLOSE 相当) ====================
|
||||
|
||||
/** OPEN INPUT R01INNFIL / OUTPUT W01OUTFIL W02OUTFIL. */
|
||||
private void openFiles() {
|
||||
try {
|
||||
r01InnFil = new BufferedReader(
|
||||
new InputStreamReader(new FileInputStream(R01INN_FILE), StandardCharsets.UTF_8));
|
||||
w01OutFil = new PrintWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(W01OUT_FILE), StandardCharsets.UTF_8));
|
||||
w02OutFil = new PrintWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(W02OUT_FILE), StandardCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e); // OPEN失敗 ≈ ABEND
|
||||
}
|
||||
}
|
||||
|
||||
/** CLOSE R01INNFIL W01OUTFIL W02OUTFIL. */
|
||||
private void closeFiles() {
|
||||
closeQuiet(r01InnFil);
|
||||
closeQuiet(w01OutFil);
|
||||
closeQuiet(w02OutFil);
|
||||
r01InnFil = null;
|
||||
w01OutFil = null;
|
||||
w02OutFil = null;
|
||||
}
|
||||
|
||||
private static void closeQuiet(final Object handle) {
|
||||
try {
|
||||
if (handle instanceof BufferedReader) {
|
||||
((BufferedReader) handle).close();
|
||||
} else if (handle instanceof PrintWriter) {
|
||||
((PrintWriter) handle).close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// CLOSE異常は無視(原程序もFILE STATUS未管理)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user