package paxan import ( "io" "log" "net/http" "net/http/cookiejar" "net/url" "os" "strconv" "strings" "time" "github.com/PuerkitoBio/goquery" ) type paxanWebOrder struct { InvoiceNumber int Type string Date string } type paxanWebOrderEntry struct { Position string ArticleNumber int Description string Amount string Price string Total string Amount2 string Price2 string Total2 string } func downloadFile(filepath string, resp *http.Response) error { // Create the file file, err := os.Create(filepath) if err != nil { return err } defer file.Close() // Write the body to file _, err = io.Copy(file, resp.Body) if err != nil { return err } return nil } // NewClient - Login func NewClient(user string, password string) (*http.Client, error) { // New http client with cookie cookieJar, _ := cookiejar.New(nil) client := &http.Client{ Jar: cookieJar, } loginvalues := make(url.Values) loginvalues.Set("performAction", "processLogin") loginvalues.Set("personlogin", user) loginvalues.Set("personpwd", password) loginvalues.Set("firma", "paxan") _, err := client.PostForm("https://www.hakopaxan-shop.de/html/login.html", loginvalues) if err != nil { return nil, err } return client, nil } // CloseClient - Logout func CloseClient(client *http.Client) error { // Logout _, err := client.Get("https://www.hakopaxan-shop.de/html/logout-performAction-processLogout.html") if err != nil { return err } return nil } // DownloadPricelists - Download both price lists func DownloadPricelists(client *http.Client) error { // Download preisliste r, err := client.Get("https://www.hakopaxan-shop.de/csv/preisliste.csv") if err != nil { return err } downloadFile(("preisliste-" + time.Now().Format("20060102150405") + ".csv"), r) // Download spreisliste r, err = client.Get("https://www.hakopaxan-shop.de/csv/spreisliste.csv") if err != nil { return err } downloadFile(("spreisliste-" + time.Now().Format("20060102150405") + ".csv"), r) return nil } func paxanGetOrders(client *http.Client) ([]paxanWebOrder, error) { var list []paxanWebOrder kvs := make(map[string]string) r, err := client.Get("https://www.hakopaxan-shop.de/html/customerDocumentList.html?customerDocumentListId=invoice&requestedPeriod=365") if err != nil { return nil, err } doc, err := goquery.NewDocumentFromReader(io.Reader(r.Body)) if err != nil { return nil, err } var headline []string // Find the table header doc.Find(".tableHeader").Each(func(i int, s *goquery.Selection) { s.Find(".tableCell").Each(func(i int, s *goquery.Selection) { title := s.Contents().Text() title = strings.Replace(title, "\n", "", -1) title = strings.TrimSpace(title) headline = append(headline, title) }) }) // Find the table items doc.Find(".tableRowGroup").Each(func(i int, s *goquery.Selection) { s.Find(".tableCell").Each(func(j int, s *goquery.Selection) { title := "undefined" if j < len(headline) { title = headline[j] } text := s.Contents().Text() text = strings.Replace(text, "\n", "", -1) text = strings.Split(text, ":")[1] text = strings.TrimSpace(text) kvs[title] = text //fmt.Printf("%s - %s\n", title, text) }) //fmt.Println(kvs) num, _ := strconv.Atoi(kvs["Beleg-Nr."]) n := paxanWebOrder{InvoiceNumber: num, Type: kvs["Belegart"], Date: kvs["Datum"]} list = append(list, n) }) return list, nil } func paxanGetOrderDetails(client *http.Client, orderNumber int) ([]paxanWebOrderEntry, error) { var list []paxanWebOrderEntry url := "https://www.hakopaxan-shop.de/html/customerDocument-customerDocumentId-" + strconv.Itoa(orderNumber) + "-customerDocumentListId-invoice-requestedPeriod-365.html" r, err := client.Get(url) if err != nil { return nil, err } doc, err := goquery.NewDocumentFromReader(io.Reader(r.Body)) if err != nil { return nil, err } // Go through table row by row doc.Find(".tableRowGroup").Each(func(i int, s *goquery.Selection) { var row []string s.Find(".tableCell").Each(func(j int, s *goquery.Selection) { text := s.Contents().Text() if j == 2 { text = s.Find(".lineItemName").Text() } text = strings.Replace(text, "\n", "", -1) text = strings.TrimSpace(text) row = append(row, text) }) num, _ := strconv.Atoi(row[1]) n := paxanWebOrderEntry{Position: row[0], ArticleNumber: num, Description: row[2], Amount: row[3], Price: row[4], Total: row[5], Amount2: row[6], Price2: row[7], Total2: row[8]} list = append(list, n) }) return list, nil } // ExportNewOrders - Export new orders into orders.csv func ExportNewOrders(client *http.Client, lastOrder int) error { f, err := os.OpenFile("orders.csv", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) if err != nil { return err } defer f.Close() orders, err := paxanGetOrders(client) if err != nil { return err } i, j := 0, 0 for _, order := range orders { if order.InvoiceNumber <= lastOrder { continue } orderDetails, err := paxanGetOrderDetails(client, order.InvoiceNumber) if err != nil { return err } for _, orderDetail := range orderDetails { text := strconv.Itoa(order.InvoiceNumber) + ";" + order.Type + ";" + order.Date + ";" + orderDetail.Position + ";" + strconv.Itoa(orderDetail.ArticleNumber) + ";" + orderDetail.Description + ";" + orderDetail.Amount + ";" + orderDetail.Price + ";" + orderDetail.Total + ";" + orderDetail.Amount2 + ";" + orderDetail.Price2 + ";" + orderDetail.Total2 + "\n" _, err = f.WriteString(text) if err != nil { return err } j++ } i++ } log.Printf("Added %d order(s) with %d article(s)", i, j) return nil }