// info  nam="SAMPLE07B"  tit="支払調書テスト"  dsc="支払調書用テストデータ作成"  pro=2

int  RandNum(int n1, int n2)
{ // ランダム数
  REAL ra = (REAL)rand() / (REAL)RAND_MAX;

  return (n2 > n1)? n1 + (int)(ra * (n2 - n1 + 1)): (n1 > n2)? n1 - (int)(ra * (n1 - n2 + 1)): n1;
}

int  DistNum(int n1, int n2)
{ // 先頭に偏ったランダム数
  REAL ra = (REAL)rand() / (REAL)RAND_MAX;

  ra *= ra;
  return (n2 > n1)? n1 + (int)(ra * (n2 - n1 + 1)): (n1 > n2)? n1 - (int)(ra * (n1 - n2 + 1)): n1;
}

int  NormNum(int n1, int n2)
{ // 中央に偏ったランダム数
  int me = (n1 + n2) / 2;

  return (rand() > RAND_MAX / 2)? DistNum(me, n2): DistNum(me, n1);
}

PCSTR RandStr(int nc)
{ // ランダム文字列
  int i, ln;
  PSTR st = ualloc(2 * nc + 1);
  static PCSTR SRC = "□☆○◎◇□△▽※○";

  ln = mbslen(SRC);
  *st = '\0';
  for (i = 0; i < nc; i++) {
    strcat(st, midstr(SRC, rand() % ln, 1));
  }
  return st;
}

int  PreCod(int cd)
{ // 都道府県コード
  int n1, n2;

  n1 = cd - 5; if (n1 <  1) n1 =  1; 
  n2 = cd + 5; if (n2 > 47) n2 = 47;
  return NormNum(n1, n2);
}

PCSTR ZipStr(int cd)
{ // 郵便番号
  PSTR st = ualloc(9);
  static int n0[48] = {
     0,  4,  3,  2, 98,  1, 99, 96, 30, 32, 37, 33, 26, 10, 21, 94, 93, 92, 91, 40, 38, 50, 41, 44,
    51, 52, 60, 53, 65, 63, 64, 68, 69, 70, 72, 74, 77, 76, 79, 78, 80, 84, 85, 86, 87, 88, 89, 90
  };

  sprintf(st, "%03d-%04d", n0[cd] * 10 + RandNum(0, 9), DistNum(1, 1500));
  return st;
}

PCSTR TelStr(int cd)
{ // 電話番号
  int a, b, c;
  PSTR st = ualloc(13);
  static int n0[48] = {
     0, 11, 17, 19, 22, 18, 23, 24, 29, 28, 27, 48, 43, 30, 44, 25, 76, 76, 77, 55, 26, 57, 54, 52,
    59, 74, 75, 60, 78, 74, 73, 85, 85, 86, 82, 83, 88, 87, 89, 88, 92, 95, 92, 96, 97, 98, 99, 98
  };

  a = n0[cd] * 10 + RandNum(0, 9);
  b = RandNum(11, 99);
  c = RandNum(1, 9900);
  if (a >= 300 && a < 400 || a >= 600 && a < 700) {
    sprintf(st, "%02d-%04d-%04d", a / 100, (a % 100) * 100 + b, c);
    if (st[3] == '0') st[3] = '3';
  } else if (a % 10 < 5) {
    sprintf(st, "%03d-%03d-%04d", a / 10, (a % 10) * 10 + b, c);
    if (st[4] == '0') st[4] = '4';
  } else {
    sprintf(st, "%04d-%02d-%04d", a, b, c);
    if (st[5] == '0') st[5] = '5';
  }
  return st;
}

PCSTR NamStr(void)
{ // 氏名
  PSTR st = ualloc(14);

  sprintf(st, "%s %s", RandStr(NormNum(1, 3)), RandStr(NormNum(1, 3)));
  return st;
}

int  INDcd(PCSTR bf)
{ // 個人番号のチェックディジット
  int i, s = 0;

  for (i = 1; i < 12; i++) {
    s += (bf[11 - i] - '0') * ((i <= 6)? i + 1: i - 5);
  }
  return (s % 11 > 1)? 11 - (s % 11): 0;
}

REAL RandIND(void)
{ // 個人番号
  int i;
  char bf[13];

  for (i = 0; i < 11; i++) {
    bf[i] = '0' + (rand() % 10);
  }
  bf[11] = '0' + INDcd(bf);
  bf[12] = '\0';
  return atof(bf);
}

int  CORcd(PCSTR bf)
{ // 法人番号のチェックディジット
  int i, s = 0;

  for (i = 0; i < 12; i++) {
    s += (bf[12 - i] - '0') * ((i % 2) + 1);
  }
  return 9 - (s % 9);
}

REAL RandCOR(void)
{ // 法人番号
  int i;
  char bf[14];

  for (i = 1; i < 13; i++) {
    bf[i] = '0' + (rand() % 10);
  }
  bf[13] = '\0';
  bf[0] = '0' + CORcd(bf);
  return atof(bf);
}

  // データ入力表
typedef struct {
  WORD  ser;
  BYTE  suf;
  BYTE  atr;
  char  zip[12];
  char  adr[64];
  char  nam[64];
  char  kan[64];
  char  tel[16];
  REAL  pin;
  char  acc[32];
  char  det[48];
  int   fee;
  int   unp;
  int   tax;
  int   unc;
  char  rem[64];
  char  mem[64];
  int   reg;
  char  usr[32];
  BYTE  rsv[20];
} HOUD;
typedef HOUD * PHOUD;
typedef const HOUD * PCHOUD;

void CommandMain(HWND hwnd)
{ // テストデータ作成
  int i, j, cd;
  HOPN op;
  HOUD dat;

  if (YesNoBox(hwnd, "支払調書用テストデータを新規作成しますか？", NULL) != IDYES) return;
  if (!ConnectDB("SAMPLE07A")) return;
  NewDBFiles();
  op = OpenTable("HOUDAT", OM_RDW); if (!op) return;
  DeleteTableRows(OHTBL(op), 0, NTableRows(OHTBL(op)));
  for (i = 0; i < 100; i++) {
    j = 0;
    memset(&dat, 0, sizeof(HOUD));
    dat.ser = i + 1;
    dat.suf = j + 1;
    dat.atr = (rand() % 2) + 1;
    cd = PreCod(13);
    strcpy(dat.zip, ZipStr(cd));
    strcpy(dat.adr, RandStr(NormNum(12, 29)));
    strcpy(dat.nam, (dat.atr == 1)? NamStr(): RandStr(NormNum(7, 16)));
    strcpy(dat.tel, TelStr(cd));
    dat.pin = (dat.atr == 1)? RandIND(): RandCOR();
    strcpy(dat.acc, RandStr(NormNum(3, 9)));
    if (rand() % 2) strcpy(dat.det, RandStr(NormNum(5, 16)));
    dat.fee = RandNum(500, 15000) * 100;
    if (dat.atr == 1) dat.tax = (int)(dat.fee * 0.1021);
    dat.reg = CurDate();
    strcpy(dat.usr, CurUser());
    memcpy(NewTableRow(OHTBL(op)), &dat, sizeof(HOUD));
  }
  CloseTable(op, TRUE);
  DisconnectDB();
  OkBox(hwnd, "支払調書用テストデータを作成しました。", NULL);
}
