skilld-labs / go-odoo

Golang wrapper for Odoo API
Apache License 2.0
86 stars 62 forks source link

Is it possible to paginate a table? #17

Closed allealdine closed 6 years ago

allealdine commented 6 years ago

Is it possible to paginate a table?

ahuret commented 6 years ago

Hi @allealdine :) Yes it's currently possible but IMHO not in a good way. You can use the low level api functions as SearchRead then define "offset" and "limit".

Example if you want to get the 5 first results of a res.partner GetAll() request:

partners := &types.ResPartners{}
err := c.SearchRead("res.partner", []interface{}{[]interface{}{}}, map[string]int{"offset": 1, "limit": 5}, partners)
if err != nil {
        fmt.Println(err.Error())  
}
fmt.Println(len(*partners))

So we didn't provide limit and offset on high level functions yet, but it would be a great contribution ! :)

allealdine commented 6 years ago

Hi @antony360 Thanks for the answer. I have made it half way now.

Here is my go script

// customer.go
package customers
import (
    "fmt"
    "net/http"
    "adsoft/lib/flight"
    "adsoft/core/router"
    "adsoft/core/pagination"
    "github.com/skilld-labs/go-odoo/api"
)

// Load the routes.
func Load() {
    router.Get("/customers", Index)
}

func Index(w http.ResponseWriter, r *http.Request) {
    d, err := api.NewClient("http://localhost:8069", nil)
    if err != nil {
        fmt.Println(err.Error())
    }
    err = d.Login("dbname", "admin", "password")
    if err != nil {
        fmt.Println(err.Error())
    }

    //get customers data with pagination instance with a max of 10 results.
    s := api.NewResPartnerService(d)
    p := pagination.New(r, 10)
    items, err := s.GetByPaginate(p.PerPage, p.Offset)
    if err != nil {
        c.FlashErrorGeneric(err)
    }
    v := c.View.New("customers/index")
    v.Vars["items"] = items
    v.Vars["pagination"] = p
    v.Render(w, r)
}

Here I added inside exisiting go-odoo/api/res_partner.go

// go-odoo/api/res_partner.go
func (svc *ResPartnerService) GetByPaginate(max int, page int) (*types.ResPartners, error) {
    r := &types.ResPartners{}
    return r, svc.client.SearchRead("res.partner", []interface{}{[]interface{}{}}, map[string]int{"offset": page, "limit": max}, r)
}

And here is inside the template

\\ customer.tmpl
{{range $n := .items}}
    <div class="panel panel-default">
        <div class="panel-body">
            <p>
                <span>{{.Name}}</span>
                <span>{{.Email}}</span>
            </p>
            <img src="data:image/png;base64, {{.ImageSmall}}" alt="{{.Name}}" />
        </div>
    </div>
{{end}}

{{PAGINATION .pagination .}}

Bingo! 10 data appear

However, I am still unable to get the SearchCount working.


// customer.go
count, err := s.GetByPaginateCount()
fmt.Println("============",len(*count))

// go-odoo/api/res_partner.go
func (svc *ResPartnerService) GetByPaginateCount() (*types.ResPartners, error) {
    r := &types.ResPartners{}
    return r, svc.client.SearchCount("res.partner", []interface{}{[]interface{}{[]string{}}}, r)
}

Above script return 0 record instead total of res.partner records. Any ideas?

ahuret commented 6 years ago

SearchCount return an integer, so your r should be an int or int64 since r is load by the function SearchCount. SearchCount hasn't exactly the same args structure as SearchRead, so you got to write it like this:

var r int
err = c.SearchCount("res.partner", []interface{}{[]interface{}{}}, &r)

And bingo ! It needs an high level function too. :)

allealdine commented 6 years ago

Awesome! Now the pagination works like a charm. Thanks @antony360