application dynamics fixed and error handling done

This commit is contained in:
hysn99
2024-03-31 23:55:05 +03:00
parent 56fbba2ab7
commit 5ec8f05e16
5 changed files with 497 additions and 414 deletions

View File

@@ -2,12 +2,14 @@ package bot
import ( import (
"bordrobot/lib/company" "bordrobot/lib/company"
"bordrobot/lib/helper"
"bordrobot/lib/model" "bordrobot/lib/model"
"bordrobot/lib/ocr" "bordrobot/lib/ocr"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"regexp" "strconv"
"strings" "strings"
"time" "time"
@@ -16,57 +18,96 @@ import (
"github.com/go-rod/rod/lib/proto" "github.com/go-rod/rod/lib/proto"
) )
var pageErrors []string
type Luca struct { type Luca struct {
Page *rod.Page Page *rod.Page
Browser *rod.Browser Browser *rod.Browser
} }
type errorInfo struct {
func websiteMessage(page *rod.Page, selector string, searchValue string) (string, error) { Error string
// Tek bir öğe alınması, hata durumunu kontrol etmek için Index int
elemd := page.MustElements(selector)
// Eğer elem boş ise, yani nil ise, hata döndür
if len(elemd) == 0 {
err := fmt.Errorf("Sellector Bulunamadı: %v", selector)
return "", err
}
elem := page.MustElement(selector)
// Eğer elem boş ise, yani nil ise, hata döndür
if elem == nil {
err := fmt.Errorf("Sellector Bulunamadı: %v", selector)
return "", err
}
// Öğenin metnini al
//text := elem.MustEval(fmt.Sprintf(`() => this.%s`, searchValue)).String()
// text := elem.MustEval(`() => this.innerText`).String()
text := elem.MustEval(fmt.Sprintf(`() => this.%s`, searchValue)).String()
return text, nil
} }
func clickItem(frm *rod.Page, selector string, clickCount int) error {
// Sayfadan ilgili öğeyi bul func VerifyCaptcha(page *rod.Page) error {
dd, err := frm.Element(selector) captcha := "#captcha"
err = dd.Click(proto.InputMouseButtonLeft, clickCount) picturePreparation := []string{
`document.getElementsByTagName("body")[0].style.backgroundImage = "none"`,
`document.getElementsByClassName("baslik1")[0].style.display = "none"`,
`document.getElementsByClassName("baslik2")[0].style.display = "none"`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = "none"`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = "none"`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = "none"`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = "none"`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = "none"`,
}
for i := 0; i < len(picturePreparation); i++ {
wait := page.WaitRequestIdle(600*time.Millisecond, nil, nil, nil)
wait()
_, err := page.Evaluate(rod.Eval(`()=>{` + picturePreparation[i] + `}`))
if err != nil {
return err
}
fmt.Print(err)
}
datas, err := page.Screenshot(true, &proto.PageCaptureScreenshot{})
if err != nil {
panic(err)
}
err = helper.CreateFolder("./processFolder")
err = ioutil.WriteFile("./processFolder/screenshot.png", datas, 0644)
if err != nil {
panic(err)
}
captchaMessage, err := ReceiveDOMMessages(page, captcha, "src")
picturePreparation = []string{
`document.getElementsByTagName("body")[0].style.backgroundImage = ""`,
`document.getElementsByClassName("baslik1")[0].style.display = ""`,
`document.getElementsByClassName("baslik2")[0].style.display = ""`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = ""`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = ""`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = ""`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = ""`,
`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = ""`,
}
for i := 0; i < len(picturePreparation); i++ {
wait := page.WaitRequestIdle(600*time.Millisecond, nil, nil, nil)
wait()
_, err := page.Evaluate(rod.Eval(`()=>{` + picturePreparation[i] + `}`))
if err != nil {
return err
}
fmt.Print(err)
}
var captchaMsg []string
captchaMsg, err = ocr.VisionApi("./processFolder/screenshot.png")
fmt.Print(captchaMessage)
trimmedMsg := strings.ReplaceAll(captchaMsg[0], " ", "")
page.MustElement("#captcha-input").MustInput(strings.ToLower(trimmedMsg))
_, err = page.Evaluate(rod.Eval(`document.getElementById(document.forms[0].submit())`))
if err != nil {
}
err = WaitLoad(page)
if err != nil { if err != nil {
return err return err
} }
getUrl := page.MustInfo().URL
splitUrl := strings.Split(getUrl, "/")
uri := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
if uri != "main.erp" {
_, err = page.Evaluate(rod.Eval(`document.querySelector("body > div.swal2-container.swal2-fade.swal2-in > div > button.swal2-confirm.swal2-styled").click()`))
//rod.Eval(`document.querySelector("body > div.swal2-container.swal2-fade.swal2-in > div > button.swal2-confirm.swal2-styled").click()`)
VerifyCaptcha(page)
fmt.Println("captcha tekrar deneme fonksiyonuna sok")
//captcha tekrar denenecek
}
return nil return nil
} }
// func (elemSelector *rod.Element)SelectItem(frm *rod.Page, selector string, changeValue string) error {
// elemSelector.Eval(`document.getElementById("` + selector + `").value = "` + changeValue + `";`)
// elemSelector.Eval(`document.getElementById("` + selector + `").dispatchEvent(new Event('change'));`)
// // _, err := frm.Evaluate(rod.Eval(`
// // document.getElementById("` + selector + `").value = "` + changeValue + `";
// // `))
// // _, err = frm.Evaluate(rod.Eval(`
// // document.getElementById("` + selector + `").dispatchEvent(new Event('change'));
// // `))
// return err
// }
func NewLucaBot() *Luca { func NewLucaBot() *Luca {
l := launcher.New(). l := launcher.New().
Headless(false). Headless(false).
@@ -88,243 +129,177 @@ func NewLucaBot() *Luca {
func (l *Luca) Login(company company.Company) error { func (l *Luca) Login(company company.Company) error {
page := l.Page page := l.Page
page.MustElement("#musteriNo").MustInput(company.MemberNumber) err := WaitLoad(page)
page.Timeout(500)
page.MustElement("#kullaniciAdi").MustInput(company.Username)
page.Timeout(500)
page.MustElement("#parola").MustInput(company.Password)
page.Timeout(500)
page.MustWaitNavigation()
result, err := page.Evaluate(rod.Eval(`document.getElementById(girisbtn())`))
if err != nil { if err != nil {
return err
}
err = FillInput(page, "#musteriNo", company.MemberNumber)
if err != nil {
return err
} }
page.Timeout(500) page.Timeout(500)
loginDialog := "body > div.swal2-container.swal2-fade.swal2-in > div > div.swal2-content" // Örneğinizdeki CSS seçicisini buraya yazın err = FillInput(page, "#kullaniciAdi", company.Username)
loginDialogMessage, err := websiteMessage(page, loginDialog, "innerText")
if err != nil { if err != nil {
fmt.Errorf("hata verdi handle") return err
}
page.Timeout(500)
err = FillInput(page, "#parola", company.Password)
if err != nil {
return err
}
page.Timeout(500)
result, err := page.Evaluate(rod.Eval(`()=>{girisbtn()}`))
if err != nil {
return err
}
page.Timeout(500)
loginDialog := "body > div.swal2-container.swal2-fade.swal2-in > div > div.swal2-content"
loginDialogMessage, err := ReceiveDOMMessages(page, loginDialog, "innerText")
if err != nil {
errString := err.Error()
if !strings.Contains(errString, "Sellector Bulunamadı") {
return err
}
} }
if loginDialogMessage == "Müşteri No, Kullanıcı Adı veya Parola hatalıdır." { if loginDialogMessage == "Müşteri No, Kullanıcı Adı veya Parola hatalıdır." {
fmt.Println("Şifre hatalı") return errors.New("Şifre hatalı")
} }
var captchaMsg []string
getUrl := page.MustInfo().URL getUrl := page.MustInfo().URL
splitUrl := strings.Split(getUrl, "/") splitUrl := strings.Split(getUrl, "/")
splitUrlPage := strings.Split(splitUrl[len(splitUrl)-1], ";")[0] splitUrlPage := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
if splitUrlPage != "main.erp" { if splitUrlPage != "main.erp" {
captcha := "#captcha" // Örneğinizdeki CSS seçicisini buraya yazın VerifyCaptcha(page)
wait := page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err := page.Evaluate(rod.Eval(`document.getElementsByTagName("body")[0].style.backgroundImage = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik1")[0].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik2")[0].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = "none"`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
datas, err := page.Screenshot(true, &proto.PageCaptureScreenshot{})
if err != nil {
panic(err)
}
err = ioutil.WriteFile("C:/Users/huseyin/Desktop/project/notitek/BordroRobot/app/lib/ocr/screenshot.png", datas, 0644)
if err != nil {
panic(err)
}
captchaMessage, err := websiteMessage(page, captcha, "src")
_, err = page.Evaluate(rod.Eval(`document.getElementsByTagName("body")[0].style.backgroundImage = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik1")[0].style.display = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik2")[0].style.display = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = ""`))
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = ""`))
captchaMsg, err = ocr.VisionApi("C:/Users/huseyin/Desktop/project/notitek/BordroRobot/app/lib/ocr/screenshot.png")
if captchaMessage != "" {
splitUrlPage = "captcha"
}
if err != nil {
fmt.Errorf("captcha Getirilirken hata oluştu")
}
//fmt.Println(captchaMessage) //sil
}
fmt.Println(result) //sil
//page.MustElement("#captcha-input").MustInput(captchaMessage)
switch splitUrlPage {
case "giris.erp":
rod.Eval(`document.querySelector("body > div.swal2-container.swal2-fade.swal2-in > div > button.swal2-confirm.swal2-styled").click()`)
//kullanıcı adı ve şifre yanlış hatası verecek error basılacak
case "captcha":
captchaString := captchaMsg[0]
page.MustElement("#captcha-input").MustInput(strings.Trim(captchaString, " "))
captchaButton, err := page.Evaluate(rod.Eval(`document.getElementById(document.forms[0].submit())`))
if err != nil {
}
fmt.Println("Sonuç:", captchaButton)
getUrl = page.MustInfo().URL
splitUrl = strings.Split(getUrl, "/")
uri := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
if uri != "main" {
fmt.Println("captcha tekrar deneme fonksiyonuna sok")
//captcha tekrar denenecek
}
} }
fmt.Println(result)
wait := page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil) wait := page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait() wait()
_, err = page.Evaluate(rod.Eval(`gonder('formTarget');`)) _, err = page.Evaluate(rod.Eval(`()=>{gonder('formTarget');}`))
if err != nil {
return err
}
wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil) wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait() wait()
return err return err
} }
func (l *Luca) NavigateBordroGiris() error {
return nil
}
func (l *Luca) BordroYaz(data []*model.Bordro) error { func (l *Luca) BordroYaz(data []*model.Bordro, month float64, year float64) error {
page := l.Page page := l.Page
allPages, err := page.Browser().Pages() allPages, err := page.Browser().Pages()
if err != nil { if err != nil {
log.Fatal(err) return err
} }
newPage, err := allPages.FindByURL("https://auygs.luca.com.tr/Luca/luca.do") newPage, err := allPages.FindByURL("https://auygs.luca.com.tr/Luca/luca.do")
if err != nil { if err != nil {
log.Fatal(err) return err
} }
//fs4, err := newPage.Element("#frm4")
//if err != nil {
// log.Fatal(err)
//}
fs2, err := newPage.Element("#frm2") fs2, err := newPage.Element("#frm2")
if err != nil { if err != nil {
log.Fatal(err) return err
} }
frame, err := fs2.Frame() frame, err := fs2.Frame()
fs3, err := newPage.Element("#frm3") fs3, err := newPage.Element("#frm3")
if err != nil { if err != nil {
log.Fatal(err) return err
} }
frame3, err := fs3.Frame() frame3, err := fs3.Frame()
err = newPage.WaitLoad() err = newPage.WaitLoad()
//_, err = fs2.Evaluate(rod.Eval(`document.getElementById('apy1000m0i1ITD').dispatchEvent(new MouseEvent('mouseover', { 'bubbles': true }));`))
err = clickItem(frame, "#apy1000m0i1ITD", 1)
fmt.Println(err)
err = clickItem(frame3, "#apy1000m33i4ITX", 1)
fmt.Println(err)
err = newPage.WaitLoad()
wait := newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
wait()
isyeriSelectBox, err := websiteMessage(frame3, "#isyeriId", "innerHTML")
if err != nil { if err != nil {
log.Fatal(err) return err
} }
wait = newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil) err = ClickItem(frame, "#apy1000m0i1ITD", 1)
wait() if err != nil {
return err
wait = newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil) }
wait() fmt.Println(err)
err = ClickItem(frame3, "#apy1000m33i4ITX", 1)
if err != nil {
return err
}
err = newPage.WaitLoad()
if err != nil {
return err
}
Wait(newPage, 1500)
for i := 0; i < len(data); i++ { for i := 0; i < len(data); i++ {
options := strings.Split(isyeriSelectBox, "</option>") if i != 0 {
vls := "" err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(3)", 1)
bolum := "" if err != nil {
return err
for _, option := range options {
// "value" ve metin içeriğini almak için regex kullanma
re := regexp.MustCompile(`value="(.+)"[^>]*>([^<]+)`)
matches := re.FindStringSubmatch(option)
if len(matches) >= 3 {
value := matches[1]
text := matches[2]
// "BESMART" değerini içeren option öğelerini bulma
if text == data[0].Sube.Value {
vls = value
break
}
} }
} }
err = WaitLoad(frame3)
if err != nil {
return err
}
isyeriId := ""
bolumId := ""
bordroCompanySelectBox, err := frame3.Elements("#isyeriId > option")
for j := 0; j < len(bordroCompanySelectBox); j++ {
text, err := bordroCompanySelectBox[j].Text()
value, err := bordroCompanySelectBox[j].Property("value")
if err != nil {
return err
}
if strings.Trim(text, " ") == data[i].Sube.Value {
isyeriId = value.String()
break
}
fmt.Print(text, value)
}
isyeriId := vls
element, err := frame3.Element("#isyeriId") element, err := frame3.Element("#isyeriId")
if err != nil {
return err
}
selectInput := Select{Element: element, Selector: "#isyeriId"} selectInput := Select{Element: element, Selector: "#isyeriId"}
selectInput.SelectItem(isyeriId) err = selectInput.SelectItem(isyeriId)
if err != nil {
return err
}
err = WaitLoad(frame3) err = WaitLoad(frame3)
if err != nil { if err != nil {
return err return err
} }
bolumSelectBox, err := websiteMessage(frame3, "#bolumId", "innerHTML") bordroDepartmentSelectBox, err := frame3.Elements("#bolumId > option")
fmt.Println(bolumSelectBox) if err != nil {
bolums := strings.Split(bolumSelectBox, "</option>") return err
for _, option := range bolums { }
// "value" ve metin içeriğini almak için regex kullanma for j := 0; j < len(bordroDepartmentSelectBox); j++ {
re := regexp.MustCompile(`value="(.+)"[^>]*>([^<]+)`) text, err := bordroDepartmentSelectBox[j].Text()
matches := re.FindStringSubmatch(option) value, err := bordroDepartmentSelectBox[j].Property("value")
if len(matches) >= 3 { if err != nil {
value := strings.Trim(matches[1], " ") return err
text := strings.Trim(matches[2], " ")
// "BESMART" değerini içeren option öğelerini bulma
if text == "FİNANS" {
bolum = value
break
}
} }
if strings.Trim(text, " ") == data[i].Bolum.Value {
bolumId = value.String()
break
}
fmt.Print(text, value)
} }
bolumId := bolum
element, err = frame3.Element("#bolumId") element, err = frame3.Element("#bolumId")
if err != nil {
return err
}
selectInput = Select{Element: element, Selector: "#bolumId"} selectInput = Select{Element: element, Selector: "#bolumId"}
selectInput.SelectItem(bolumId) err = selectInput.SelectItem(bolumId)
if err != nil {
return err
}
err = WaitLoad(frame3) err = WaitLoad(frame3)
if err != nil { if err != nil {
return err return err
} }
// wait = newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil) aktarimDonem := strconv.FormatFloat(month, 'f', -1, 64)
// wait() err = ClickItem(frame3, "#tr"+aktarimDonem+" > td:nth-child(1)", 2)
aktarimDonem := "1"
err = clickItem(frame3, "#tr"+aktarimDonem+" > td:nth-child(1)", 2)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@@ -335,25 +310,58 @@ func (l *Luca) BordroYaz(data []*model.Bordro) error {
return err return err
} }
// wait = newPage.WaitRequestIdle(1000*time.Millisecond, nil, nil, nil) var isEmpty bool = false
// wait()
//var targetID string //var targetID string
elems, err := frame3.Elements("#scroll > table > tbody > tr > td[id^='tcKimlikNo']") elems, err := frame3.Elements("#scroll > table > tbody > tr > td[id^='tcKimlikNo']")
if err != nil {
return err
}
elemsProcess, err := frame3.Elements("#scroll > table > tbody > tr > td > a")
if err != nil {
return err
}
trs, err := frame3.Elements("#scroll > table > tbody > tr") trs, err := frame3.Elements("#scroll > table > tbody > tr")
if err != nil {
return err
}
var foundIndex int = -1 var foundIndex int = -1
for i := 0; i < len(elems); i++ { if len(elems) == 0 {
tex, err := elems[i].Text() isEmptyError := errorInfo{
Error: "Böyle Bir Kullanıcı Bulunamadı",
Index: i,
}
pageErrors = append(pageErrors, isEmptyError.Error+", Index: "+strconv.Itoa(isEmptyError.Index))
continue
}
for j := 0; j < len(elems); j++ {
tex, err := elems[j].Text()
if err != nil {
return err
}
process, err := elemsProcess[j].Text()
if err != nil { if err != nil {
return err return err
} }
if tex == data[i].TCKimlikNo.Value { if tex == data[i].TCKimlikNo.Value {
//targetID = tex foundIndex = j
foundIndex = i if process == "Bordro Sil" {
isEmpty = true
}
break break
} }
fmt.Print(elems, tex) fmt.Print(elems, tex)
} }
if isEmpty == true {
isEmptyError := errorInfo{
Error: "Yazılı Bordro Var Lütfen Siliniz",
Index: i,
}
pageErrors = append(pageErrors, isEmptyError.Error+", Index: "+strconv.Itoa(isEmptyError.Index))
continue
}
if foundIndex != -1 { if foundIndex != -1 {
trs[foundIndex].Click(proto.InputMouseButtonLeft, 2) trs[foundIndex].Click(proto.InputMouseButtonLeft, 2)
} }
err = WaitLoad(frame3) err = WaitLoad(frame3)
@@ -363,11 +371,10 @@ func (l *Luca) BordroYaz(data []*model.Bordro) error {
} }
data[i].FillBordroForm(frame3) data[i].FillBordroForm(frame3)
//err yoksa hesapla ba //err yoksa hesapla ba
calculate, err := frame3.Element("body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td.right > button") err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td.right > button", 1)
if err != nil { if err != nil {
return err log.Fatal(err)
} }
calculate.Click(proto.InputMouseButtonLeft, 1)
err = WaitLoad(frame3) err = WaitLoad(frame3)
if err != nil { if err != nil {
return err return err
@@ -383,6 +390,7 @@ func (l *Luca) BordroYaz(data []*model.Bordro) error {
} }
} }
CloseBrowser(l.Browser)
return err return err
} }

View File

@@ -1,9 +1,11 @@
package bot package bot
import ( import (
"fmt"
"time" "time"
"github.com/go-rod/rod" "github.com/go-rod/rod"
"github.com/go-rod/rod/lib/proto"
) )
type Select struct { type Select struct {
@@ -12,14 +14,73 @@ type Select struct {
} }
func (elemSelector *Select) SelectItem(changeValue string) error { func (elemSelector *Select) SelectItem(changeValue string) error {
_, err := elemSelector.Element.Evaluate(rod.Eval(`document.querySelector("` + elemSelector.Selector + `").value = "` + changeValue + `";`)) _, err := elemSelector.Element.Evaluate(rod.Eval(`()=>{document.querySelector("` + elemSelector.Selector + `").value = "` + changeValue + `";}`))
_, err = elemSelector.Element.Evaluate(rod.Eval(`document.querySelector("` + elemSelector.Selector + `").dispatchEvent(new Event('change'));`)) _, err = elemSelector.Element.Evaluate(rod.Eval(`()=>{document.querySelector("` + elemSelector.Selector + `").dispatchEvent(new Event('change'));}`))
return err return err
} }
func WaitLoad(frm *rod.Page) error { // belli bir süre redirect ten önceki js fonksiyonunun tamamlanması bekleniyor func WaitLoad(frm *rod.Page) error { // belli bir süre redirect ten önceki js fonksiyonunun tamamlanması bekleniyor
wait := frm.WaitRequestIdle(50*time.Millisecond, nil, nil, nil) wait := frm.WaitRequestIdle(100*time.Millisecond, nil, nil, nil)
wait() wait()
err := frm.WaitLoad() err := frm.WaitLoad()
return err return err
} }
func ReceiveDOMMessages(page *rod.Page, selector string, searchValue string) (string, error) {
// Tek bir öğe alınması, hata durumunu kontrol etmek için
elemd := page.MustElements(selector)
// Eğer elem boş ise, yani nil ise, hata döndür
if len(elemd) == 0 {
err := fmt.Errorf("Sellector Bulunamadı: %v", selector)
return "", err
}
elem := page.MustElement(selector)
// Eğer elem boş ise, yani nil ise, hata döndür
if elem == nil {
err := fmt.Errorf("Sellector Bulunamadı: %v", selector)
return "", err
}
// Öğenin metnini al
//text := elem.MustEval(fmt.Sprintf(`() => this.%s`, searchValue)).String()
// text := elem.MustEval(`() => this.innerText`).String()
text := elem.MustEval(fmt.Sprintf(`() => this.%s`, searchValue)).String()
return text, nil
}
func FillInput(frm *rod.Page, selector string, value string) error {
el, err := frm.Element(selector)
if err != nil {
return err
}
err = el.Input(value)
return err
}
func ClickItem(frm *rod.Page, selector string, clickCount int) error {
// Sayfadan ilgili öğeyi bul
el, err := frm.Element(selector)
err = el.Click(proto.InputMouseButtonLeft, clickCount)
return err
}
func Wait(frm *rod.Page, millisecond time.Duration) {
wait := frm.WaitRequestIdle(millisecond*time.Millisecond, nil, nil, nil)
wait()
}
func CloseBrowser(browser *rod.Browser) {
browser.Close()
}
// func (elemSelector *Select) MultipleEvalute(changeValue []string) error {
// for i := 0; i < len(changeValue); i++ {
// _, err := elemSelector.Element.Evaluate(rod.Eval(changeValue[i]))
// if err != nil {
// return err
// }
// }
// return nil
// }

30
app/lib/helper/helper.go Normal file
View File

@@ -0,0 +1,30 @@
package helper
import (
"fmt"
"os"
)
type errorInfo struct {
Error string
Index int
}
func (e *errorInfo) ErrorHandle() {
//apiden veya txt ye yaz
}
func CreateFolder(folderName string) error {
if _, err := os.Stat(folderName); os.IsNotExist(err) {
// Klasör yoksa oluştur
err := os.Mkdir(folderName, 0755)
if err != nil {
fmt.Println("Klasör oluşturulamadı:", err)
return err
}
fmt.Println("Klasör oluşturuldu:", folderName)
} else {
fmt.Println("Klasör zaten var:", folderName)
}
return nil
}

View File

@@ -107,181 +107,179 @@ type Bordro struct {
DigerIstisnalar BordroProperty //90 DigerIstisnalar BordroProperty //90
} }
func getPageId(id int) string { func getPageId(id string) string {
switch id { switch id {
case 4: case "NormalGun":
return "#normalGun0" return "#normalGun0" //Normal Gün
case 5: case "HaftaTatili":
return "#normalGun1" //, "checkbox" return "#normalGun1" //, "checkbox" Hafta Tatili
case 6: case "X75":
return "" //x7.5
case "EksikGunNeden":
return "" //Eksik Gün Neden
case "ArgeDestekVeTasarim":
return "" //ARGE-Destek ve Tasarım Faaliyeti
case "FazlaMesai":
return "#ekKazancCarpan0" //Fazla Mesai
case "GeceMesaisi":
return "#ekKazancCarpan1" //Gece Mesaisi
case "BayramMesaisi":
return "" //Bayram Mesaisi
case "Yol":
return "#ekKazancCarpan3" //Yol
case "YemekGun":
return "#ekKazancCarpan4" //Yemek (Gün)
case "YemekTutar":
return "" //Yemek (Tutar)
case "Aile":
return "#ekKazancDeger5" //Aile
case "Cocuk":
return "" //Çocuk
case "Evlenme":
return "#ekKazancDeger7" //Evlenme
case "Dogum":
return "#ekKazancDeger8" //Doğum
case "Olum":
return "#ekKazancDeger9" //Ölüm
case "Askerlik":
return "#ekKazancDeger10" //Askerlik
case "Ozelsigorta":
return "#ekKazancDeger11" //Özel Sigorta
case "BireyselEmeklilik":
return "#ekKazancDeger12" //Bireysel Emeklilik
case "HayatSigortasi":
return "#ekKazancDeger13" //Hayat Sigortası
case "PrimNet":
return "#ekKazancDeger14" //Prim (Net)
case "PrimBrut":
return "#ekKazancDeger15" //Prim (Brüt)
case "IkramiyeNet":
return "" //İkramiye (Net)
case "IkramiyeBrut":
return "" //İkramiye (Brüt)
case "KıdemTazminatı":
return "#ekKazancDeger16" //Kıdem Tazminatı
case "IhbarTazminati":
return "#ekKazancDeger17" //İhbar Tazminatı
case "Bayram":
return "#ekKazancDeger18" //Bayram
case "Yakacak":
return "#ekKazancDeger19" //Yakacak
case "HuzurHakki":
return "#ekKazancDeger23" //Huzur Hakkı
case "HediyeKart":
return "" //Hediye Kart*
case "YakitKart":
return "" //Yakıt Kart*
case "YillikIzin":
return "" //Yıllık İzin
case "MaasFarki":
return "" //Maaş Farkı
case "AyirilisPaketi":
return "" //Ayrılış Paketi
case "RamazanKumanyasi":
return "" //Ramazan Kumanyası*
case "TelefonDesteği":
return "#ekKazancDeger21" //Telefon Desteği
case "EkOdemeNet":
return "" //Ek Ödeme (Net)
case "EkOdemeBrut":
return "" //Ek Ödeme (Brüt)
case "IsAramaIzni":
return "" //İş Arama İzni
case "Prim2":
return "#ekKazancDeger20" //Prim2
case "Prim3":
return "" //Prim3
case "Prim4":
return "" //Prim4
case "CalismaIzniHarci":
return "" //Çalışma İzni Harç. Vb.*
case "OzeldurumOdenesi":
return "" //Özel Durum Ödemesi
case "EmekliSandigiCalisanPrimi":
return "" //Emekli Sandığı Çalışan Primi
case "LisanTazminati":
return "" //Lisan Tazminatı
case "OdulOdenesi":
return "" //Ödül Ödemesi
case "IsSonuTazminati":
return "" //İş Sonu Tazminatı
case "VergiIstisnasiEkOdeme":
return "" //Vergi İstisnası Ek Ödeme
case "KresYardimi":
return "#ekKazancDeger22" //Kreş Yardımı
case "EsnekYanHak":
return "" //Esnek Yan Hak
case "AracKullanim":
return "" //Araç Kullanım
case "EgitimDesteği":
return "" //Eğitim Desteği
case "DelegeUcreti":
return "" //Delege Ücreti
case "HarcTutarlari":
return "" //Harç Tutarları*
case "SendikaIscilikFarkUcretleri":
return "" //Sendika İşçilik Fark Ücretleri
case "IsinmaDesteği":
return "" //Isınma Desteği
case "SoforlukMesaisi":
return "" //Şoförlük Mesaisi
case "Avans":
return "" //Avans
case "Icra":
return "" //icra
case "Sendika":
return "" //Sendika
case "HediyeKart2":
return "" //Hediye Kart
case "YemekAyni":
return "" //Yemek (Ayni)
case "RamazanKumanyasiAyni":
return "" //Ramazan Kumanyası (Ayni)
case "BagimliOSSKesintisi":
return "" //Bağımlı (Eş-Çocuk) ÖSS Kesintisi
case "CalismaIzniHarciAyni":
return "" //Çalışma İzni Harç. Vb.(Ayni)
case "TrafikCezasiKesintisi":
return "" //Trafik Cezası Kesintisi
case "BesKesintisi":
return "" return ""
case 7: case "YakitKart2":
return "" return ""
case 8: case "GrupBesPersonelPayiKesintisi":
return "" return ""
case 9: case "IstisnadanKaynaklananKesinti":
return "#ekKazancCarpan0"
case 10:
return "#ekKazancCarpan1"
case 11:
return "" return ""
case 12: case "EmekliSandigiCalisanPrimKesintisi":
return "#ekKazancCarpan3"
case 13:
return "#ekKazancCarpan4"
case 14:
return "" return ""
case 15: case "PesinYillikIzinKesintisi":
return "#ekKazancDeger5"
case 16:
return "" return ""
case 17: case "TelefonLimitAsimKesintisi":
return "#ekKazancDeger7"
case 18:
return "#ekKazancDeger8"
case 19:
return "#ekKazancDeger9"
case 20:
return "#ekKazancDeger10"
case 21:
return "#ekKazancDeger11"
case 22:
return "#ekKazancDeger12"
case 23:
return "#ekKazancDeger13"
case 24:
return "#ekKazancDeger14" //primNet
case 25:
return "#ekKazancDeger15"
case 26:
return "" return ""
case 27: case "ZimmetTamirKesintisi":
return "" return ""
case 28: case "YakitAsimKesintisi":
return "#ekKazancDeger16"
case 29:
return "#ekKazancDeger17"
case 30:
return "#ekKazancDeger18"
case 31:
return "#ekKazancDeger19"
case 32:
return "#ekKazancDeger23"
case 33:
return "" return ""
case 34: case "DigerAvanslar":
return "" return ""
case 35: case "DigerKesintiler":
return "" return ""
case 36: case "ZorunluBesKesintisi":
return "" return ""
case 37: case "ZimmetliBilgisayarTamirUcreti":
return "" return ""
case 38: case "HarcTutarlari2":
return "" return ""
case 39: case "PrimAvansi":
return "#ekKazancDeger21"
case 40:
return "" return ""
case 41: case "MasrafKesintisi":
return "" return ""
case 42: case "BireyselEmekPrimi":
return ""
case 43:
return "#ekKazancDeger20"
case 44:
return ""
case 45:
return ""
case 46:
return ""
case 47:
return ""
case 48:
return ""
case 49:
return ""
case 50:
return ""
case 51:
return ""
case 52:
return ""
case 53:
return "#ekKazancDeger22"
case 54:
return ""
case 55:
return ""
case 56:
return ""
case 57:
return ""
case 58:
return ""
case 59:
return ""
case 60:
return ""
case 61:
return ""
case 62:
return ""
case 63:
return ""
case 64:
return ""
case 65:
return ""
case 66:
return ""
case 67:
return ""
case 68:
return ""
case 69:
return ""
case 70:
return ""
case 71:
return ""
case 72:
return ""
case 73:
return ""
case 74:
return ""
case 75:
return ""
case 76:
return ""
case 77:
return ""
case 78:
return ""
case 79:
return ""
case 80:
return ""
case 81:
return ""
case 82:
return ""
case 83:
return ""
case 84:
return ""
case 85:
return ""
case 86:
return ""
case 87:
return ""
case 88:
return "#bireyselEmeklilikIstisna" return "#bireyselEmeklilikIstisna"
case 89: case "OzelsigortaPrimi":
return "#ozelSigortaIstisna" return "#ozelSigortaIstisna"
case 90: case "DigerIstisnalar":
return "#digerIstisna" return "#digerIstisna"
default: default:
return "" return ""
@@ -332,11 +330,11 @@ func NewFromExcelLine(rows []string) (*Bordro, error) {
if len(rows) > i { if len(rows) > i {
indexField.SetInt(int64(i)) indexField.SetInt(int64(i))
valueField.SetString(rows[i]) valueField.SetString(rows[i])
idField.SetString(getPageId(i)) idField.SetString(getPageId(fieldName))
} else { } else {
indexField.SetInt(int64(i)) indexField.SetInt(int64(i))
valueField.SetString("") valueField.SetString("")
idField.SetString(getPageId(i)) idField.SetString(getPageId(fieldName))
} }
fmt.Print(field) fmt.Print(field)

View File

@@ -69,19 +69,14 @@ func (s *Srv) Rpa(companyName string, month float64, year float64) error {
} }
//todo: readb company details by name //todo: readb company details by name
b := bot.NewLucaBot() b := bot.NewLucaBot()
b.Login(user) err = b.Login(user)
//b.BordroYaz(data,b.page,,) if err != nil {
//todo: inform user about process and errors
emitLog("Şifreniz Hatalı")
return nil
//err := b.Login() }
//err := b.Login(şirket, accoun no, parola vsç..)
//şirket login bilgilerini sqlite'tan oku
//ardında BOT init et (global değişken de olmayabilir) init fonksyionu bot'u dönebilir
//bot'ta login ol
//bot'ta olması gereken veri yazma sayfasına browse et
//todo: save xls to application folder as /name/year/month.xlsx
//wails nümerik değerleri float gönderiyor.. int gönderimi araştırılmalı
slog.Debug("inputs", "year", year, "month", month) slog.Debug("inputs", "year", year, "month", month)
f, err := excelize.OpenFile(s.xlsFileName) f, err := excelize.OpenFile(s.xlsFileName)
@@ -114,22 +109,13 @@ func (s *Srv) Rpa(companyName string, month float64, year float64) error {
// //
fmt.Println(bordroSatiri, err) fmt.Println(bordroSatiri, err)
} }
b.BordroYaz(data) err = b.BordroYaz(data, month, year)
if err != nil {
//for _, row := range rows { //emitLog(err.message)
// //todo: process excel and do data input return err
// fmt.Println(row) } else {
// // satır satır execli oku, emitLog("işlem başarılı")
// }
// //yukarıda init edilen bot'ta' yazma kodunu çalıştır..
//
// bordroSatiri, err := model.NewFromExcelLine(row)
// fmt.Println(bordroSatiri, err)
// b.BordroYaz(bordroSatiri)
//
// //todo: inform user about process and errors
// emitLog(row[1])
//}
return nil return nil
} }