diff --git a/internal/toukibo/houjin_body.go b/internal/toukibo/houjin_body.go index 856bf81..ae3d182 100644 --- a/internal/toukibo/houjin_body.go +++ b/internal/toukibo/houjin_body.go @@ -36,11 +36,11 @@ func (h *HoujinBody) String() string { return out } -func (h *HoujinBody) GetHoujinKaku() (HoujinkakuType, error) { +func (h *HoujinBody) GetHoujinKaku() HoujinkakuType { if h.HoujinKaku == HoujinKakuUnknown { - return HoujinKakuUnknown, fmt.Errorf("not found houjin kaku") + return HoujinKakuUnknown } - return h.HoujinKaku, nil + return h.HoujinKaku } func (h *HoujinBody) GetHoujinExecutives() ([]HoujinExecutiveValue, error) { @@ -134,10 +134,7 @@ func (h *HoujinBody) GetHoujinRepresentatives() ([]HoujinExecutiveValue, error) return res, nil } - houjinKaku, err := h.GetHoujinKaku() - if err != nil { - return nil, err - } + houjinKaku := h.GetHoujinKaku() // 特定目的会社、有限会社は取締役が代表となる if houjinKaku == HoujinKakuYugen || houjinKaku == HoujinKakuTokuteiMokuteki { diff --git a/internal/toukibo/houjin_kaku.go b/internal/toukibo/houjin_kaku.go index ea7acf6..fba3567 100644 --- a/internal/toukibo/houjin_kaku.go +++ b/internal/toukibo/houjin_kaku.go @@ -38,9 +38,192 @@ const ( HoujinKakuUniversity HoujinkakuType = "国立大学法人" HoujinKakuGakko HoujinkakuType = "学校法人" HoujinKakuBengoshi HoujinkakuType = "弁護士法人" + HoujinKakuDokuritsu HoujinkakuType = "独立行政法人" + + // 認可法人と特殊法人の違い + // https://www.gyoukaku.go.jp/siryou/tokusyu/about.pdf + // 一覧 https://www.hatosan.com/utc/jdt.html + + // 認可法人 + // 特別の法律によって限定数設置されるが、特殊法人と異なり、「特別の設立行為」によ + // って強制設立されるものではなく、法律の枠内において民間等の関係者が任意設立し、 + // 主務大臣の認可を受けたもの + HoujinKakuNinka HoujinkakuType = "認可法人" + + // 特殊法人 + // 特別の法律により特別の設立行為をもって強制設立すべきものとされる法人。 + HoujinKakuTokushu HoujinkakuType = "特殊法人" + + // 特別民間法人 + HoujinKakuTokubetsuMinkan HoujinkakuType = "特別民間法人" ) +var tokushuHoujin = map[string]struct{}{ + // 内閣府所管 + "沖縄振興開発金融公庫": {}, + "沖縄科学技術大学院大学学園": {}, + // 復興庁所管 + "福島国際研究機構": {}, + // 総務省所管 + "日本電信電話株式会社": {}, + "東日本電信電話株式会社": {}, + "西日本電信電話株式会社": {}, + "日本放送協会": {}, + "日本郵政株式会社": {}, + "日本郵便株式会社": {}, + // 財務省所管 + "日本たばこ産業株式会社": {}, + "株式会社日本政策金融公庫": {}, + "株式会社日本政策投資銀行": {}, + "輸出入・港湾関連情報処理センター株式会社": {}, + "株式会社国際協力銀行": {}, + // 文部科学省所管 + "日本私立学校振興・共済事業団": {}, + "放送大学学園": {}, + // 厚生労働省所管 + "日本年金機構": {}, + // 農林水産省所管 + "日本中央競馬会": {}, + // 経済産業省所管 + "日本アルコール産業株式会社": {}, + "株式会社商工組合中央金庫": {}, + "株式会社日本貿易保険": {}, + // 国土交通省所管 + "新関西国際空港株式会社": {}, + "北海道旅客鉄道株式会社": {}, + "四国旅客鉄道株式会社": {}, + "日本貨物鉄道株式会社": {}, + "東京地下鉄株式会社": {}, + "成田国際空港株式会社": {}, + "東日本高速道路株式会社": {}, + "中日本高速道路株式会社": {}, + "西日本高速道路株式会社": {}, + "首都高速道路株式会社": {}, + "阪神高速道路株式会社": {}, + "本州四国連絡高速道路株式会社": {}, + // 環境省所管 + "中間貯蔵・環境安全事業株式会社": {}, +} + +func IsTokushuHoujin(name string) bool { + // https://www.gyoukaku.go.jp/siryou/tokusyu/taisyou_houjin.pdf + _, ok := tokushuHoujin[name] + return ok +} + +var ninkaHoujin = map[string]struct{}{ + "銀行等保有株式取得機構": {}, + "原子力損害賠償・廃炉等支援機構": {}, + "株式会社地域経済活性化支援機構": {}, + "株式会社民間資金等活用事業推進機構": {}, + "株式会社東日本大震災事業者再生支援機構": {}, + "大阪湾広域臨海環境整備センター": {}, + "株式会社海外通信・放送・郵便事業支援機構": {}, + "外国人技能実習機構": {}, + "日本銀行": {}, + "預金保険機構": {}, + "日本赤十字社": {}, + "農水産業協同組合貯金保険機構": {}, + "株式会社農林漁業成長産業化支援機構": {}, + "電力広域的運営推進機関": {}, + "使用済燃料再処理機構": {}, + "株式会社産業革新投資機構": {}, + "株式会社海外需要開拓支援機構": {}, + "株式会社海外交通・都市開発事業支援機構": {}, + "株式会社脱炭素化支援機構": {}, +} + +var tokubetsuMinkanHoujin = map[string]struct{}{ + // 内閣府所管 + "日本消防検定協会": {}, + "消防団員等公務災害補償等共済基金": {}, + "自動車安全運転センター": {}, + "日本公認会計士協会": {}, + // 総務省所管 + "危険物保安技術協会": {}, + "日本行政書士会連合会": {}, + // 法務省所管 + "日本司法書士会連合会": {}, + "日本土地家屋調査士会連合会": {}, + // 財務省所管 + "日本税理士会連合会": {}, + // 厚生労働省所管 + "社会保険診療報酬支払基金": {}, + "中央労働災害防止協会": {}, + "建設業労働災害防止協会": {}, + "陸上貨物運送事業労働災害防止協会": {}, + "林業・木材製造業労働災害防止協会": {}, + "港湾貨物運送事業労働災害防止協会": {}, + "中央職業能力開発協会": {}, + "企業年金連合会": {}, + "石炭鉱業年金基金": {}, + "全国社会保険労務士会連合会": {}, + "全国健康保険協会": {}, + // 農林水産省所管 + "農林中央金庫": {}, + "全国漁業共済組合連合会": {}, + // 経済産業省所管 + "東京中小企業投資育成株式会社": {}, + "名古屋中小企業投資育成株式会社": {}, + "大阪中小企業投資育成株式会社": {}, + "高圧ガス保安協会": {}, + "日本電気計器検定所": {}, + "日本商工会議所": {}, + "全国商工会連合会": {}, + "日本弁理士会": {}, + // 国土交通省所管 + "日本勤労者住宅協会": {}, + "軽自動車検査協会": {}, + "日本小型船舶検査機構": {}, + "日本水先人会連合会": {}, +} + +func IsNinkaHoujin(name string) bool { + _, ok := ninkaHoujin[name] + return ok +} + +func IsTokubetsuMinkanHoujin(name string) bool { + _, ok := tokubetsuMinkanHoujin[name] + return ok +} + +var politicalParty = map[string]struct{}{ + "公明党": {}, + "国民民主党": {}, + "参政党": {}, + "社会民主党": {}, + "自由民主党": {}, + "日本維新の会": {}, + "日本保守党": {}, + "日本共産党": {}, + "みんなでつくる党": {}, + "立憲民主党": {}, + "れいわ新選組": {}, +} + +func IsPoliticalParty(name string) bool { + _, ok := politicalParty[name] + return ok +} + func FindHoujinKaku(name, s string) HoujinkakuType { + if IsPoliticalParty(name) { + return HoujinKakuPoliticalParty + } + + if IsNinkaHoujin(name) { + return HoujinKakuNinka + } + + if IsTokushuHoujin(name) { + return HoujinKakuTokushu + } + + if IsTokubetsuMinkanHoujin(name) { + return HoujinKakuTokubetsuMinkan + } + if strings.Contains(name, "株式会社") { return HoujinKakuKabusiki } else if strings.Contains(name, "有限会社") { @@ -94,25 +277,18 @@ func FindHoujinKaku(name, s string) HoujinkakuType { return HoujinKakuNPO } else if strings.Contains(name, "特定非営利活動法人") { return HoujinKakuTokuteiHieiri - } else if strings.Contains(name, "政党") { - // このパターンは今のところ存在しない 2024/08/04 - return HoujinKakuPoliticalParty } else if strings.Contains(name, "国立大学法人") { return HoujinKakuUniversity } else if strings.Contains(name, "学校法人") { return HoujinKakuGakko } else if strings.Contains(name, "弁護士法人") { return HoujinKakuBengoshi + } else if strings.Contains(name, "独立行政法人") { + return HoujinKakuDokuritsu } else { if strings.Contains(s, "宗教法人") || strings.Contains(s, "境内建物、境内地") { return HoujinKakuShukyo } - - if name == "自由民主党" || name == "日本共産党" || name == "公明党" || name == "立憲民主党" || - name == "国民民主党" || name == "社会民主党" || name == "日本維新の会" || name == "れいわ新選組" { - return HoujinKakuPoliticalParty - } } - return HoujinKakuUnknown } diff --git a/internal/toukibo/houjin_kaku_test.go b/internal/toukibo/houjin_kaku_test.go new file mode 100644 index 0000000..58a23e6 --- /dev/null +++ b/internal/toukibo/houjin_kaku_test.go @@ -0,0 +1,366 @@ +package toukibo_test + +import ( + "testing" + + "github.com/tychy/toukibo-parser/internal/toukibo" +) + +func TestIsTokushuHoujin(t *testing.T) { + tests := []struct { + name string + input string + expected bool + }{ + { + name: "特殊法人のケース", + input: "日本電信電話株式会社", + expected: true, + }, + { + name: "特殊法人でないケース", + input: "株式会社テスト", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toukibo.IsTokushuHoujin(tt.input) + if result != tt.expected { + t.Errorf("IsTokushuHoujin(%q) = %v, want %v", tt.input, result, tt.expected) + } + }) + } +} + +func TestIsNinkaHoujin(t *testing.T) { + tests := []struct { + name string + input string + expected bool + }{ + { + name: "認可法人のケース", + input: "日本銀行", + expected: true, + }, + { + name: "認可法人でないケース", + input: "株式会社テスト", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toukibo.IsNinkaHoujin(tt.input) + if result != tt.expected { + t.Errorf("IsNinkaHoujin(%q) = %v, want %v", tt.input, result, tt.expected) + } + }) + } +} + +func TestIsTokubetsuMinkanHoujin(t *testing.T) { + tests := []struct { + name string + input string + expected bool + }{ + { + name: "特別民間法人のケース", + input: "日本公認会計士協会", + expected: true, + }, + { + name: "特別民間法人でないケース", + input: "株式会社テスト", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toukibo.IsTokubetsuMinkanHoujin(tt.input) + if result != tt.expected { + t.Errorf("IsTokubetsuMinkanHoujin(%q) = %v, want %v", tt.input, result, tt.expected) + } + }) + } +} + +func TestIsPoliticalParty(t *testing.T) { + tests := []struct { + name string + input string + expected bool + }{ + { + name: "政党のケース", + input: "自由民主党", + expected: true, + }, + { + name: "政党でないケース", + input: "株式会社テスト", + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toukibo.IsPoliticalParty(tt.input) + if result != tt.expected { + t.Errorf("IsPoliticalParty(%q) = %v, want %v", tt.input, result, tt.expected) + } + }) + } +} + +func TestFindHoujinKaku(t *testing.T) { + tests := []struct { + name string + input string + content string + expected toukibo.HoujinkakuType + }{ + { + name: "政党のケース", + input: "自由民主党", + content: "", + expected: toukibo.HoujinKakuPoliticalParty, + }, + { + name: "認可法人のケース", + input: "日本銀行", + content: "", + expected: toukibo.HoujinKakuNinka, + }, + { + name: "特殊法人のケース", + input: "日本郵便株式会社", + content: "", + expected: toukibo.HoujinKakuTokushu, + }, + { + name: "特別民間法人のケース", + input: "日本公認会計士協会", + content: "", + expected: toukibo.HoujinKakuTokubetsuMinkan, + }, + { + name: "株式会社のケース", + input: "株式会社テスト", + content: "", + expected: toukibo.HoujinKakuKabusiki, + }, + { + name: "株式会社の前後に空白があるケース", + input: " 株式会社テスト ", + content: "", + expected: toukibo.HoujinKakuKabusiki, + }, + { + name: "有限会社のケース", + input: "有限会社テスト", + content: "", + expected: toukibo.HoujinKakuYugen, + }, + { + name: "合同会社のケース", + input: "合同会社テスト", + content: "", + expected: toukibo.HoujinKakuGoudou, + }, + { + name: "合資会社のケース", + input: "合資会社テスト", + content: "", + expected: toukibo.HoujinKakuGousi, + }, + { + name: "合名会社のケース", + input: "合名会社テスト", + content: "", + expected: toukibo.HoujinKakuGoumei, + }, + { + name: "特定目的会社のケース", + input: "特定目的会社テスト", + content: "", + expected: toukibo.HoujinKakuTokuteiMokuteki, + }, + { + name: "協同組合のケース", + input: "協同組合テスト", + content: "", + expected: toukibo.HoujinKakuKyodou, + }, + { + name: "労働組合のケース", + input: "労働組合テスト", + content: "", + expected: toukibo.HoujinKakuRoudou, + }, + { + name: "森林組合のケース", + input: "森林組合テスト", + content: "", + expected: toukibo.HoujinKakuSinrin, + }, + { + name: "生活衛生同業組合のケース", + input: "生活衛生同業組合テスト", + content: "", + expected: toukibo.HoujinKakuSeikatuEisei, + }, + { + name: "信用金庫のケース", + input: "信用金庫テスト", + content: "", + expected: toukibo.HoujinKakuSinyou, + }, + { + name: "商工会のケース", + input: "商工会テスト", + content: "", + expected: toukibo.HoujinKakuShokoukai, + }, + { + name: "公益財団法人のケース", + input: "公益財団法人テスト", + content: "", + expected: toukibo.HoujinKakuKoueki, + }, + { + name: "農事組合のケース", + input: "農事組合テスト", + content: "", + expected: toukibo.HoujinKakuNouji, + }, + { + name: "管理組合法人のケース", + input: "管理組合法人テスト", + content: "", + expected: toukibo.HoujinKakuKanriKumiai, + }, + { + name: "医療法人のケース", + input: "医療法人テスト", + content: "", + expected: toukibo.HoujinKakuIryo, + }, + { + name: "司法書士法人のケース", + input: "司法書士法人テスト", + content: "", + expected: toukibo.HoujinKakuSihoshosi, + }, + { + name: "税理士法人のケース", + input: "税理士法人テスト", + content: "", + expected: toukibo.HoujinKakuZeirishi, + }, + { + name: "社会福祉法人のケース", + input: "社会福祉法人テスト", + content: "", + expected: toukibo.HoujinKakuShakaifukusi, + }, + { + name: "一般社団法人のケース", + input: "一般社団法人テスト", + content: "", + expected: toukibo.HoujinKakuIppanShadan, + }, + { + name: "公益社団法人のケース", + input: "公益社団法人テスト", + content: "", + expected: toukibo.HoujinKakuKouekiShadan, + }, + { + name: "一般財産法人のケース", + input: "一般財産法人テスト", + content: "", + expected: toukibo.HoujinKakuIppanZaisan, + }, + { + name: "一般財団法人のケース", + input: "一般財団法人テスト", + content: "", + expected: toukibo.HoujinKakuIppanZaidan, + }, + { + name: "NPO法人のケース(半角)", + input: "NPO法人テスト", + content: "", + expected: toukibo.HoujinKakuNPO, + }, + { + name: "NPO法人のケース(全角)", + input: "NPO法人テスト", + content: "", + expected: toukibo.HoujinKakuNPO, + }, + { + name: "特定非営利活動法人のケース", + input: "特定非営利活動法人テスト", + content: "", + expected: toukibo.HoujinKakuTokuteiHieiri, + }, + { + name: "国立大学法人のケース", + input: "国立大学法人テスト", + content: "", + expected: toukibo.HoujinKakuUniversity, + }, + { + name: "学校法人のケース", + input: "学校法人テスト", + content: "", + expected: toukibo.HoujinKakuGakko, + }, + { + name: "弁護士法人のケース", + input: "弁護士法人テスト", + content: "", + expected: toukibo.HoujinKakuBengoshi, + }, + { + name: "独立行政法人のケース", + input: "独立行政法人テスト", + content: "", + expected: toukibo.HoujinKakuDokuritsu, + }, + { + name: "宗教法人のケース(contentに宗教法人が含まれる)", + input: "テスト法人", + content: "宗教法人", + expected: toukibo.HoujinKakuShukyo, + }, + { + name: "宗教法人のケース(contentに境内建物、境内地が含まれる)", + input: "テスト法人", + content: "境内建物、境内地", + expected: toukibo.HoujinKakuShukyo, + }, + { + name: "不明なケース", + input: "テスト法人", + content: "", + expected: toukibo.HoujinKakuUnknown, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toukibo.FindHoujinKaku(tt.input, tt.content) + if result != tt.expected { + t.Errorf("FindHoujinKaku(%q, %q) = %v, want %v", tt.input, tt.content, result, tt.expected) + } + }) + } +}