view src/kaigo/Porori/src2/porori.go @ 65:0369656be06c default tip

many changes.
author pyon@macmini
date Fri, 20 May 2022 06:30:34 +0900
parents 34a474fb83c3
children
line wrap: on
line source

/*
	Last Change: 2021-09-07 火 14:39:09.
*/
package main

import (
	"bufio"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"sort"
	"strings"
	"time"

	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
)

const jsonfile = "porori.json"

type Sinsei struct {
	No string
	Name string
	Ymd string
	Kbn string
	Ccn string
	Bgn string
	End string
	Hist string
	ReqI string
	Acc string
	ReqC string
	Visit string
	Remark string
}

func (s Sinsei) String() string {
	s.ChangeExpression()

	var ymd, ccn, bgn, end, reqi, acc, reqc, visit, remark time.Time
	ymd, s.Ymd       = s.TransDate(s.Ymd)
	ccn, s.Ccn       = s.TransDate(s.Ccn)
	bgn, s.Bgn       = s.TransDate(s.Bgn)
	end, s.End       = s.TransDate(s.End)
	reqi, s.ReqI     = s.TransDate(s.ReqI)
	acc,  s.Acc      = s.TransDate(s.Acc)
	reqc,  s.ReqC    = s.TransDate(s.ReqC)
	visit, s.Visit   = s.TransDate(s.Visit)
	remark, s.Remark = s.TransDate(s.Remark)

	term   := fmt.Sprintf("%d", s.CalcTerm(bgn, end))
	ridays := fmt.Sprintf("%d", s.CountDay(ymd, reqi))
	adays  := fmt.Sprintf("%d", s.CountDay(reqi, acc))
	rcdays := fmt.Sprintf("%d", s.CountDay(ymd, reqc))
	vdays  := fmt.Sprintf("%d", s.CountDay(reqc, visit))
	tdays  := fmt.Sprintf("%d", s.CountDay(visit, remark))
	rdays  := fmt.Sprintf("%d", s.CountDay(ymd, ccn))
	return strings.Join([]string{s.No, s.Name, s.Ymd, s.Kbn, s.Bgn, s.End, term, s.Ccn, rdays, s.ReqI, ridays, s.Acc, adays, s.ReqC, rcdays, s.Visit, vdays, s.Remark, tdays}, ",")
}

func (s Sinsei) TransDate (ymd string) (time.Time, string) {
	zero := time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
	if !strings.HasPrefix(ymd, "20") {
		return zero, ""	// it's dummy
	}
	t, _ := time.Parse("20060102", ymd)
	return t, t.Format(" 2006-01-02")
}

func (s Sinsei) CalcTerm(bgn, end time.Time) int {
	if bgn.IsZero() || end.IsZero() {
		return 0
	}

	m := (end.Year() * 12 + int(end.Month())) - (bgn.Year() * 12 + int(bgn.Month()))
	if bgn.Day() == 1 {
		m++
	}
	return m
}

func (s Sinsei) CountDay(bgn, end time.Time) int {
	if bgn.IsZero() || end.IsZero() {
		return -9999
	}

	if bgn.Year() == end.Year() {
		return end.YearDay() - bgn.YearDay()
	}
	if end.Year() - bgn.Year() == 1 {
		d := 365 - bgn.YearDay() + end.YearDay()
		if bgn.Year() % 4 == 0 { // can use 2001 - 2099
			d++
		}
		return d
	}

	return -9999
}

func (s *Sinsei) ChangeExpression() {
	s.No = "=\"" + strings.TrimSpace(s.No) + "\""

	switch s.Kbn {
	case "01":
		s.Kbn = "新規"
	case "02":
		s.Kbn = "更新"
	case "10":
		s.Kbn = "支介"
	case "05":
		s.Kbn = "区変"
	case "03":
		s.Kbn = "転入"
	case "09":
		s.Kbn = "証交"
	}
	s.Kbn, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), s.Kbn)
}

func read_line(file string) ([]string, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	var s []string
	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		s = append(s, scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return s, nil
}

func main() {

	if len(os.Args) != 5 {
		fmt.Fprint(os.Stderr, "bat input.")
		os.Exit(1)
	}

	// Filter Setting
	type YF struct {
		From string
		To string
	}
	var yf YF

	content, err := os.ReadFile(jsonfile)
	if err != nil {
		log.Fatal(err)
	}
	if err := json.Unmarshal(content, &yf); err != nil {
		log.Fatal(err)
	}

	// Read CSV
	content, err = os.ReadFile(os.Args[1]) // nintei.csv
	if err != nil {
		log.Fatal(err)
	}

	r := csv.NewReader(strings.NewReader(string(content)))

	records, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	ikensho, err := read_line(os.Args[2]) // i.csv
	if err != nil {
		log.Fatal(err)
	}
	chosa, err := read_line(os.Args[3]) // c.csv
	if err != nil {
		log.Fatal(err)
	}

	remark, err := read_line(os.Args[4]) // t.csv
	if err != nil {
		log.Fatal(err)
	}

	// Main Proccess
	var sinsei []Sinsei

	for _, record := range records {
		if record[5] < yf.From || record[5] > yf.To {
			continue
		}
		var riymd, aymd, rcymd, vymd string
		key := strings.Join([]string{record[0], record[1]}, ",")
		for _, i := range ikensho {
			if strings.HasPrefix(i, key) {
				riymd = strings.Split(i, ",")[2]
				aymd  = strings.Split(i, ",")[3]
				break
			}
		}
		for _, c := range chosa {
			if strings.HasPrefix(c, key) {
				rcymd = strings.Split(c, ",")[2]
				vymd  = strings.Split(c, ",")[3]
				break
			}
		}
		var rymd string
		for _, t := range remark {
			h := strings.TrimSpace(record[0])
			c := strings.Split(t, ",")
			if strings.EqualFold(h, c[0]) && strings.EqualFold(record[3], c[1]) {
				rymd = c[2]
				break
			}
		}

		ss := Sinsei{
			No: record[0],
			Hist: record[1],
			Name: record[2],
			Ymd: record[3],
			Kbn: record[4],
			Ccn: record[5],
			Bgn: record[6],
			End: record[7],
			ReqI: riymd,
			Acc: aymd,
			ReqC: rcymd,
			Visit: vymd,
			Remark: rymd,
		}
		sinsei = append(sinsei, ss)
	}

	sort.Slice(sinsei, func(i, j int) bool {
		return sinsei[i].Ymd < sinsei[j].Ymd
	})

	// Output
	header := strings.Join([]string{"被保番", "氏名", "申請日", "区分", "開始日", "終了日", "期間", "審査会", "日数", "意見書依頼", "日数", "意見書入手", "日数", "調査依頼", "日数", "調査", "日数", "特記", "日数"}, ",")
	header, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), header)
	fmt.Println(header)

	/*
	for i, s := range sinsei {
		fmt.Print(s)
		fmt.Printf(",=\"0\"&A%d\n", i + 2)
	}
	*/
	for _, s := range sinsei {
		fmt.Println(s)
	}
}