61
|
1 /*
|
|
2 95.go: Qfuhi Tsuchi
|
|
3
|
|
4 Last Change: 2020-09-11 金 10:42:16.
|
|
5 */
|
|
6
|
|
7 package main
|
|
8
|
|
9 /*
|
|
10 #cgo LDFLAGS: -L. -lxdwapi -static
|
|
11 ##### C_SOURCE #####
|
|
12 */
|
|
13 import "C"
|
|
14
|
|
15 import (
|
|
16 "bufio"
|
|
17 "regexp"
|
|
18 "encoding/json"
|
|
19 "flag"
|
|
20 "fmt"
|
|
21 "io/ioutil"
|
|
22 "log"
|
|
23 "os"
|
|
24 "path/filepath"
|
|
25 "sort"
|
|
26 "strings"
|
|
27
|
|
28 "golang.org/x/text/encoding/japanese"
|
|
29 "golang.org/x/text/transform"
|
|
30 )
|
|
31
|
|
32 type Hhs struct {
|
|
33 No string
|
|
34 Name string
|
|
35 Page int // sinsei page
|
|
36 Tsuchi bool
|
|
37 Kaigo string
|
|
38 Xdw []string
|
|
39 }
|
|
40
|
|
41 func(h *Hhs) AppendXdw(xdw string) {
|
|
42 h.Xdw = append(h.Xdw, xdw)
|
|
43 }
|
|
44
|
|
45 func(h *Hhs) CsvString() string {
|
|
46 q := ""
|
|
47 if h.Tsuchi {
|
|
48 q = "○"
|
|
49 }
|
|
50 k := strings.Split(h.Kaigo, "")
|
|
51 return strings.Join([]string{h.No, h.Name, q, k[1] + k[3]}, ",")
|
|
52 }
|
|
53
|
|
54 func(h *Hhs) Dump() string {
|
|
55 q := "false"
|
|
56 if h.Tsuchi {
|
|
57 q = "true"
|
|
58 }
|
|
59 p := fmt.Sprintf("%05d", h.Page)
|
|
60 x := strings.Join(h.Xdw, ",")
|
|
61 return strings.Join([]string{h.No, h.Name, q, h.Kaigo, p, x}, ",")
|
|
62 }
|
|
63
|
|
64 type Config struct {
|
|
65 Indir string
|
|
66 Outdir string
|
|
67 Workdir string
|
|
68 Hhsdb string
|
|
69 Atnfile[] string
|
|
70 }
|
|
71
|
|
72 var (
|
|
73 ver = "0.1"
|
|
74 conf Config
|
|
75 confjson = "95.json"
|
|
76 logfile = "95.log"
|
|
77 osirase = "KBPA316G.xdw"
|
|
78 sinsei = "KBPA406G.xdw"
|
|
79 rule_s = "rules.ann"
|
|
80
|
|
81 out_o = "o.xdw"
|
|
82 out_s = "s.xdw"
|
|
83 out_q = "q.xdw"
|
|
84 out_l = "l.csv"
|
|
85
|
|
86 re_hhsno, re_name, re_kaigo *regexp.Regexp
|
|
87
|
|
88 // option parameters
|
|
89 version bool
|
|
90 )
|
|
91
|
|
92 func init() {
|
|
93 /* コンフィグファイルは JSON */
|
|
94 content, err := ioutil.ReadFile(confjson)
|
|
95 if err != nil {
|
|
96 log.Fatal(err)
|
|
97 }
|
|
98 if err := json.Unmarshal(content, &conf); err != nil {
|
|
99 log.Fatal(err)
|
|
100 }
|
|
101
|
|
102 osirase = filepath.Join(conf.Indir, osirase)
|
|
103 sinsei = filepath.Join(conf.Indir, sinsei)
|
|
104
|
|
105 out_o = filepath.Join(conf.Outdir, out_o)
|
|
106 out_s = filepath.Join(conf.Outdir, out_s)
|
|
107 out_q = filepath.Join(conf.Outdir, out_q)
|
|
108 out_l = filepath.Join(conf.Outdir, out_l)
|
|
109
|
|
110 logfile = filepath.Join(conf.Workdir, logfile)
|
|
111
|
|
112 /* 一時ファイル消去 */
|
|
113 os.RemoveAll(conf.Outdir)
|
|
114 os.RemoveAll(conf.Workdir)
|
|
115 os.Mkdir(conf.Outdir, 0755)
|
|
116 os.Mkdir(conf.Workdir, 0755)
|
|
117
|
|
118 /* 変数初期化 */
|
|
119 re_hhsno = regexp.MustCompile(`0[1238]00\d{6}`)
|
|
120 re_name = regexp.MustCompile(`日.{30}`)
|
|
121 re_kaigo = regexp.MustCompile(`要((介護)|(支援)).`)
|
|
122
|
|
123 flag.BoolVar(&version, "v", false, "print version")
|
|
124 }
|
|
125
|
|
126 func main() {
|
|
127 flag.Parse()
|
|
128
|
|
129 if version {
|
|
130 fmt.Println("95 - version", ver)
|
|
131 os.Exit(0)
|
|
132 }
|
|
133
|
|
134 hash_Hhs := make(map[string]Hhs)
|
|
135
|
|
136 /* 申請書を漁り,構造体を初期化 */
|
|
137 for p, t := range xdw2txt(sinsei) {
|
|
138 hno := re_hhsno.FindString(t)
|
|
139 name := re_name.FindString(t)
|
|
140 name = strings.Replace(name, "日", "", 1)
|
|
141 kaigo := re_kaigo.FindString(t)
|
|
142 o := fmt.Sprintf("o_%05d.xdw", p + 1)
|
|
143 s := fmt.Sprintf("s_%05d.xdw", p + 1)
|
|
144 h := Hhs{No: hno, Name: name, Kaigo: kaigo, Page:p + 1, Xdw: []string{o, s}}
|
|
145 hash_Hhs[hno] = h
|
|
146 }
|
|
147
|
|
148 /* バックグラウンドで給付費通知から勧奨対象者を抽出 */
|
|
149 ch := make(chan int)
|
|
150 go func() {
|
|
151 files, err := ioutil.ReadDir(conf.Indir)
|
|
152 if err != nil {
|
|
153 log.Fatal(err)
|
|
154 }
|
|
155
|
|
156 qn := 1
|
|
157 for _, file := range files {
|
|
158 if !strings.HasSuffix(file.Name(), ".xdw") {
|
|
159 continue
|
|
160 }
|
|
161 if strings.HasPrefix(file.Name(), "KDPK016G") || strings.HasPrefix(file.Name(), "KDPK126G") {
|
|
162 qtsuchi := filepath.Join(conf.Indir, file.Name())
|
|
163 tmptxt := filepath.Join(conf.Workdir, "tmp95.txt")
|
|
164 for p, t := range xdw2txtb(qtsuchi, tmptxt) {
|
|
165 hno := re_hhsno.FindString(t)
|
|
166 if h, ok := hash_Hhs[hno]; ok {
|
|
167 h.Tsuchi = true
|
|
168 q := fmt.Sprintf("q_%05d.xdw", qn)
|
|
169 h.AppendXdw(q)
|
|
170 hash_Hhs[hno] = h
|
|
171 q = filepath.Join(conf.Workdir, q)
|
|
172 C.xdwextpage(C.CString(qtsuchi), C.int(p + 1), C.CString(q))
|
|
173 qn++
|
|
174 //fmt.Println(qtsuchi, p, hno, h.Kaigo, h.Xdw)
|
|
175 }
|
|
176 }
|
|
177 }
|
|
178 }
|
|
179
|
|
180 ch <- 1
|
|
181 }()
|
|
182
|
|
183 /* そのあいだにバラす */
|
|
184 C.xdwsplit1(C.CString(osirase), C.CString(conf.Workdir), C.CString("o_"))
|
|
185 C.xdwsplit1(C.CString(sinsei), C.CString(conf.Workdir), C.CString("s_"))
|
|
186 <-ch
|
|
187
|
|
188 /* ソート & マージ */
|
|
189 var slice_Hhs []Hhs
|
|
190 for _, h := range hash_Hhs {
|
|
191 slice_Hhs = append(slice_Hhs, h)
|
|
192 }
|
|
193 sort.Slice(slice_Hhs, func(i, j int) bool {
|
|
194 if slice_Hhs[i].Tsuchi != slice_Hhs[j].Tsuchi {
|
|
195 return slice_Hhs[i].Tsuchi
|
|
196 }
|
|
197 if slice_Hhs[i].Kaigo != slice_Hhs[j].Kaigo {
|
|
198 return slice_Hhs[i].Kaigo < slice_Hhs[j].Kaigo
|
|
199 }
|
|
200 if slice_Hhs[i].Page != slice_Hhs[j].Page {
|
|
201 return slice_Hhs[i].Page < slice_Hhs[j].Page
|
|
202 }
|
|
203 return false
|
|
204 })
|
|
205
|
|
206 var list_o, list_s, list_q []string
|
|
207 for _, h := range slice_Hhs {
|
|
208 list_o = append(list_o, filepath.Join(conf.Workdir, h.Xdw[0]))
|
|
209 list_s = append(list_s, filepath.Join(conf.Workdir, h.Xdw[1]))
|
|
210 if h.Tsuchi {
|
|
211 for i, x := range h.Xdw {
|
|
212 if i > 1 {
|
|
213 buf := filepath.Join(conf.Workdir, x)
|
|
214 list_q = append(list_q, buf)
|
|
215 }
|
|
216 }
|
|
217 }
|
|
218 }
|
|
219 xdwmerge(list_o, out_o)
|
|
220 xdwmerge(list_s, out_s)
|
|
221 xdwmerge(list_q, out_q)
|
|
222
|
|
223 /* リスト出力 & ログダンプ */
|
|
224 csvtxt := ""
|
|
225 logtxt := ""
|
|
226 for _, h := range slice_Hhs {
|
|
227 csvtxt += h.CsvString() + "\n"
|
|
228 logtxt += h.Dump() + "\n"
|
|
229 }
|
|
230 csvtxt, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), csvtxt)
|
|
231 if err := ioutil.WriteFile(out_l, []byte(csvtxt), 0644); err != nil {
|
|
232 log.Fatal(err)
|
|
233 }
|
|
234 if err := ioutil.WriteFile(logfile, []byte(logtxt), 0644); err != nil {
|
|
235 log.Fatal(err)
|
|
236 }
|
|
237
|
|
238 /* バックグラウンドで給付費通知を校正 */
|
|
239 ch2 := make(chan int)
|
|
240 go func() {
|
|
241 for _, a := range conf.Atnfile {
|
|
242 xdwaddatn(out_q, a)
|
|
243 }
|
|
244 ch2 <- 1
|
|
245 } ()
|
|
246
|
|
247 /* そのあいだに申請書に枠付け */
|
|
248 xdwaddatntool(out_s, rule_s, 2, 1497, 803)
|
|
249 <-ch2
|
|
250 }
|
|
251
|
|
252 func xdw2txt(file string) (txt []string) {
|
|
253 s := C.GoString(C.xdw2txt(C.CString(file)))
|
|
254 r := strings.NewReader(s)
|
|
255 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder())
|
|
256 buf := bufio.NewScanner(tr)
|
|
257 for buf.Scan() {
|
|
258 txt = append(txt, buf.Text())
|
|
259 }
|
|
260 return
|
|
261 }
|
|
262
|
|
263 func xdw2txtb(xdwfile, txtfile string) (txt []string) {
|
|
264 if _, err := os.Stat(txtfile); os.IsExist(err) {
|
|
265 os.Remove(txtfile)
|
|
266 }
|
|
267
|
|
268 C.xdw2txtb(C.CString(xdwfile), C.CString(txtfile))
|
|
269 content, err := ioutil.ReadFile(txtfile)
|
|
270 if err != nil {
|
|
271 return nil
|
|
272 }
|
|
273
|
|
274 r := strings.NewReader(string(content))
|
|
275 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder())
|
|
276 buf := bufio.NewScanner(tr)
|
|
277 for buf.Scan() {
|
|
278 txt = append(txt, buf.Text())
|
|
279 }
|
|
280 return
|
|
281 }
|
|
282
|
|
283 func xdwmerge(list []string, outfile string) (err error) {
|
|
284 order := strings.Join(list, "\n")
|
|
285 order, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), order)
|
|
286 orderfile := filepath.Join(conf.Workdir, "order95.txt")
|
|
287 if err := ioutil.WriteFile(orderfile, []byte(order), 0644); err != nil {
|
|
288 return err
|
|
289 }
|
|
290 C.xdwmerge(C.CString(orderfile), C.CString(outfile))
|
|
291 return nil
|
|
292 }
|
|
293
|
|
294 func xdwaddatn(xdwfile, atnfile string) (err error) {
|
|
295 C.xdwaddatn(C.CString(xdwfile), C.CString(atnfile))
|
|
296 return nil
|
|
297 }
|
|
298
|
|
299 func xdwaddatntool(xdwfile, toolfile string, n, x, y int) (err error) {
|
|
300 C.xdwaddatntool(C.CString(xdwfile), C.CString(toolfile), C.int(n), C.int(x), C.int(y))
|
|
301 return nil
|
|
302 }
|
|
303
|