// info  nam="SAMPLE04B"  tit="備品管理改"  dsc="説明用サンプル"  pro=1

  // リース等契約区分
PCSTR SLTP[3] = { "リース", "レンタル", "買取" };
ENMS esLTP = { SLTP, NELEM(SLTP) };

  // 事業所
CODI diOFC[6] = {
  { 19, "本社" }, { 20, "仙台" }, { 23, "名古屋" }, { 24, "大阪" },
  { 26, "広島" }, { 27, "九州" }
};
CODS dsOFC = { diOFC, NELEM(diOFC) };

  // リース等データ
typedef struct {
  char  lid[10];
  BYTE  ltp, ofc;
  char  dsc[40];
  int   ter;
  int   bdt, edt;
  int   mnp;
  int   amp;
  char  ven[24];
  char  len[24];
  char  lcd[40];
  char  rem[40];
  char  fil[12];
} LEADAT;

PVOID fcalLFD(PVOID pv, PCVOID pb, PCCOLI co)
{ // リース満期日
  int ter = ((LEADAT *)pb)->ter, bdt = ((LEADAT *)pb)->bdt;

  *(int *)pv = (ter && bdt)? date_serial(year(bdt), month(bdt) + ter, day(bdt) - 1): 0;
  return pv;
}

  // リース状態
PCSTR SLST[3] = { "", "リース中", "再リース" };
ENMS esLST = { SLST, NELEM(SLST) };

PVOID fcalLST(PVOID pv, PCVOID pb, PCCOLI co)
{ // リース状態
  int ltp = ((LEADAT *)pb)->ltp, bdt = ((LEADAT *)pb)->bdt, edt = ((LEADAT *)pb)->edt, cdt, fdt;

  cdt = CurDate(); fcalLFD(&fdt, pb, co);
  *(int *)pv = (ltp == 0 && cdt >= bdt && cdt <= edt)? ((cdt <= fdt)? 1: 2): 0;
  return pv;
}

PVOID fcalLAL(PVOID pv, PCVOID pb, PCCOLI co)
{ // リース支払総額
  int ter = ((LEADAT *)pb)->ter, mnp = ((LEADAT *)pb)->mnp;

  *(int *)pv = ter * mnp;
  return pv;
}

PVOID fcalLRA(PVOID pv, PCVOID pb, PCCOLI co)
{ // リース料率
  int mnp = ((LEADAT *)pb)->mnp, amp = ((LEADAT *)pb)->amp;

  *(REAL *)pv = amp? (REAL)mnp / (REAL)amp: 0;
  return pv;
}

  // リース等リスト
COLI ciLEA[18] = {
  { ASC(10),  9, "lid", "リース等ＩＤ", NULL, CF_KEY, }, // 0
  { TID_E1B,  6, "ltp", "区分", "契約区分", CF_DDL, NULL, NULL, (UINT)&esLTP, },
  { TID_C1B,  0, "ofc", "事業所", NULL, CF_DDL, NULL, NULL, (UINT)&dsOFC, },
  { STR(40),  0, "dsc", "物件名", NULL, CF_NZR, },
  { TID_I4B,  4, "ter", "期間", "期間(月数)", CF_HZR, },
  { TID_YMD,  0, "bdt", "開始日", NULL, CF_NZR, },       // 5
  { CAL_YMD,  0, "fdt", "満期日", NULL, 0, fcalLFD, },   // 6
  { TID_YMD,  0, "edt", "終了日", },                     // 7
  { CAL_E4B,  7, "sta", "状　態", NULL, 0, fcalLST, NULL, (UINT)&esLST, }, // 8
  { TID_M4B, 10, "mnp", "月払額", NULL, CF_HZR, },
  { CAL_M4B, 10, "alp", "支払総額", NULL, CF_HZR, fcalLAL, },
  { TID_M4B, 10, "amp", "物件価格", NULL, CF_HZR, },
  { CAL_F8B,  7, "rat", "料　率", NULL, CF_HZR, fcalLRA, NULL, (UINT)"%.4f", },
  { STR(24),  0, "ven", "販売会社名", },
  { STR(24),  0, "len", "リース等会社名", },
  { STR(40), 20, "lcd", "契約コード", },
  { STR(40),  0, "rem", "備　考", },
  { STR(12),  8, "fil", "ファイル", },
};
COLS csLEA = { ciLEA, NELEM(ciLEA) };

  // 保守契約区分
PCSTR SMTP[3] = { "月払", "年払", "その他" };
ENMS esMTP = { SMTP, NELEM(SMTP) };

  // 保守契約データ
typedef struct {
  char  mid[10];
  BYTE  mtp, ofc;
  char  dsc[40];
  int   ter;
  int   bdt, edt;
  int   mnp;
  char  ven[24];
  char  mcd[40];
  char  rem[40];
  char  fil[12];
} MNTDAT;

PVOID fcalMFD(PVOID pv, PCVOID pb, PCCOLI co)
{ // 保守満期日
  int ter = ((MNTDAT *)pb)->ter, bdt = ((MNTDAT *)pb)->bdt;

  *(int *)pv = (ter && bdt)? date_serial(year(bdt), month(bdt) + ter, day(bdt) - 1): 0;
  return pv;
}

  // 保守状態
PCSTR SMST[2] = { "", "継続中" };
ENMS esMST = { SMST, NELEM(SMST) };

PVOID fcalMST(PVOID pv, PCVOID pb, PCCOLI co)
{ // 保守状態
  int bdt = ((MNTDAT *)pb)->bdt, edt = ((MNTDAT *)pb)->edt, cdt;

  cdt = CurDate();
  *(int *)pv = (cdt >= bdt && cdt <= edt);
  return pv;
}

PVOID fcalMAL(PVOID pv, PCVOID pb, PCCOLI co)
{ // 保守支払総額
  int ter = ((MNTDAT *)pb)->ter, mnp = ((MNTDAT *)pb)->mnp;

  *(int *)pv = ter * mnp;
  return pv;
}

  // 保守契約リスト
COLI ciMNT[15] = {
  { ASC(10),  9, "mid", "保守ＩＤ", NULL, CF_KEY, },   // 0
  { TID_E1B,  6, "mtp", "区分", "契約区分", CF_DDL, NULL, NULL, (UINT)&esMTP, },
  { TID_C1B,  0, "ofc", "事業所", NULL, CF_DDL, NULL, NULL, (UINT)&dsOFC, },
  { STR(40),  0, "dsc", "物件名", NULL, CF_NZR, },
  { TID_I4B,  4, "ter", "期間", "期間(月数)", CF_HZR, },
  { TID_YMD,  0, "bdt", "開始日", NULL, CF_NZR, },     // 5
  { CAL_YMD,  0, "fdt", "満期日", NULL, 0, fcalMFD, }, // 6
  { TID_YMD,  0, "edt", "終了日", },                   // 7
  { CAL_E4B,  7, "sta", "状　態", NULL, 0, fcalMST, NULL, (UINT)&esMST, }, // 8
  { TID_M4B, 10, "mnp", "月払額", NULL, CF_HZR, },
  { CAL_M4B, 10, "alp", "支払総額", NULL, CF_HZR, fcalMAL, },
  { STR(24),  0, "ven", "保守会社名", },
  { STR(40), 20, "mcd", "保守コード", },
  { STR(40),  0, "rem", "備　考", },
  { STR(12),  8, "fil", "ファイル", },
};
COLS csMNT = { ciMNT, NELEM(ciMNT) };

  // 品目
PCSTR SCAT[10] = {
  "", "パソコン", "ディスプレイ", "大判プリンタ", "コピー機", "プリンタ",
  "サーバ等", "その他機器", "ソフト等", "ＩＰ割当"
};
ENMS esCAT = { SCAT, NELEM(SCAT) };

  // 状態
PCSTR SSTA[5] = { "現用", "予備", "故障", "撤去済", "未配備" };
ENMS esSTA = { SSTA, NELEM(SSTA) };

  // 備品データ
typedef struct {
  char  qid[10];
  BYTE  cat, ofc, sta;
  char  mak[23];
  char  mdl[24];
  char  snm[24];
  char  spc[24];
  char  use[40];
  char  lid[10];
  char  mid[10];
  char  qcd[40];
  char  ipa[16];
  int   ddt;
  char  rem[44];
} EQUDAT;

  // 備品リスト
COLI ciEQU[23] = {
  { ASC(10),  9, "qid", "備品ＩＤ", NULL, CF_KEY, },
  { TID_E1B, 10, "cat", "品目", "品　目", CF_DDL, NULL, NULL, (UINT)&esCAT, },
  { TID_C1B,  0, "ofc", "事業所", NULL, CF_DDL, NULL, NULL, (UINT)&dsOFC, },
  { TID_E1B,  0, "sta", "状態", "状　態", CF_DDL, NULL, NULL, (UINT)&esSTA, },
  { STR(23), 12, "mak", "メーカー名", },
  { STR(24), 16, "mdl", "製品名／型番", },
  { STR(24), 16, "snm", "製造番号等", },
  { STR(24), 16, "spc", "スペック等", },
  { STR(40),  0, "use", "主要用途等", },
  { ASC(10),  9, "lid", "リース等ＩＤ", NULL, CF_REF, NULL, NULL, 0, RKY(0, 0), },
  { CAL_YMD,  0, "lbd", "リース開始", NULL, CF_REF, NULL, NULL, 0, RKY(0, 5), },
  { CAL_YMD,  0, "lfd", "リース満期", NULL, CF_REF, NULL, NULL, 0, RKY(0, 6), },
  { CAL_YMD,  0, "led", "リース終了", NULL, CF_REF, NULL, NULL, 0, RKY(0, 7), },
  { CAL_E4B,  7, "lst", "リ状態", "リース状態", CF_REF, NULL, NULL, (UINT)&esLST, RKY(0, 8), },
  { ASC(10),  9, "mid", "保守ＩＤ", NULL, CF_REF, NULL, NULL, 0, RKY(1, 0), },
  { CAL_YMD,  0, "mbd", "保守開始", NULL, CF_REF, NULL, NULL, 0, RKY(1, 5), },
  { CAL_YMD,  0, "mfd", "保守満期", NULL, CF_REF, NULL, NULL, 0, RKY(1, 6), },
  { CAL_YMD,  0, "med", "保守終了", NULL, CF_REF, NULL, NULL, 0, RKY(1, 7), },
  { CAL_E4B,  7, "mst", "保状態", "保守状態", CF_REF, NULL, NULL, (UINT)&esMST, RKY(1, 8), },
  { STR(40), 16, "qcd", "個体保守コード", },
  { STR(16),  0, "ipa", "ＩＰアドレス", },
  { TID_YMD,  0, "ddt", "個体撤去日", },
  { STR(44),  0, "rem", "備　考", },
};
COLS csEQU = { ciEQU, NELEM(ciEQU) };

BYTE uso(PCSTR usr)
{ // ユーザーの所属事業所
  BYTE ofc;

  if      (stricmp(usr, "T.Yamada")   == 0) ofc = 19;
  else if (stricmp(usr, "A.Hirose")   == 0) ofc = 20;
  else if (stricmp(usr, "S.Wakamiya") == 0) ofc = 23;
  else if (stricmp(usr, "K.Nanba")    == 0) ofc = 24;
  else if (stricmp(usr, "K.Kamiya")   == 0) ofc = 26;
  else if (stricmp(usr, "F.Nakagawa") == 0) ofc = 27;
  else                                      ofc = 0;
  return ofc;
}

BOOL ftrgBIH(HTBL tb, int msg, int ir, PVOID pb)
{ // 操作履歴／アクセス制御
  BYTE ofc;
  HANDLE hf;
  char bf[256];
  static char opr[3][6] = { "変更 ", "挿入 ", "削除 " };

  switch (msg) {
  case TRGM_DEFAULT:
    DefaultTableTrigger(tb, msg, ir, pb);
    ofc = uso(CurUser());
    SetRowBufCellValue(TableRowBuf(tb, ir), 2, &ofc);
    return TRUE;
  case TRGM_UPDATERECORD:
  case TRGM_INSERTRECORD:
  case TRGM_DELETERECORD:
    strcpy(bf, dtformat("yyyy/mm/dd hh:mm:ss ", now()));
    strcat(bf, opr[msg - TRGM_UPDATERECORD]);
    strcat(bf, format("%s ", (PCSTR)pb));
    strcat(bf, CurUser());
    hf = open_file(strconc(TableName(tb), ".LOG"), OP_APD);
    if (!hf) break;
    set_file_ptr(hf, 0, FILE_END);
    write_line(hf, bf);
    close_file(hf);
    break;
  }
  if (CurAuth() < 3) {
    switch (LOWORD(msg)) {
    case TRGM_BEFOREUPDATEOF:
      if (HIWORD(msg) == 2) return FALSE;
      // fall through
    case TRGM_BEFOREUPDATE:
    case TRGM_BEFOREDELETE:
      GetTableCellValue(&ofc, tb, ir, 2);
      if (uso(CurUser()) != ofc) return FALSE;
      break;
    }
  }
  return DefaultTableTrigger(tb, msg, ir, pb);
}

TBLI tiBIH[3] = {
  { &csLEA, NULL, "LEADAT",  "リース等リスト", NULL, 0, ftrgBIH, NULL, 0, sizeof(LEADAT) },
  { &csMNT, NULL, "MNTDAT",  "保守契約リスト", NULL, 0, ftrgBIH, NULL, 0, sizeof(MNTDAT) },
  { &csEQU, NULL, "EQUDAT",  "備品リスト",     NULL, 0, ftrgBIH, NULL, 0, sizeof(EQUDAT) },
};
TBLS tsBIH = { tiBIH, NELEM(tiBIH) };

BDBI dbBIH = { &tsBIH, "SAMPLE04B", "備品管理", "説明用サンプル" };

BOOL ConnectMain(void)
{ // サンプル
  return ConnectDBX(&dbBIH);
}
