Pocketbiz Android Printing Reports Dashboard GR
ESPocketBiz – Printing, Reports & Dashboard
Entersoft Business Suite® | Entersoft CRM® | Entersoft Mobile Suite®
Τεχνικό εγχειρίδιο
Περιεχόμενα
- 1 Ταυτότητα
- 2 Copyright
- 3 = Εκτυπώσεις – Printing
- 4 Reports
- 5 Dashboard
Ταυτότητα
Έκδοση κειμένου 2.0
Τελ. ενημέρωση Ιούνιος 2021
Copyright
© Copyright 2011 Entersoft A.E. Με την επιφύλαξη όλων των νόμιμων δικαιωμάτων.
Δεν επιτρέπεται η αναδημοσίευση ή μετάδοση με οποιαδήποτε μορφή και για οποιοδήποτε λόγο μέρους ή όλου του παρόντος εγχειριδίου, χωρίς τη ρητή άδεια της Entersoft Α.Ε.
Όσον αφορά το περιεχόμενο του παρόντος…
- Μπορεί να μεταβληθεί οποιαδήποτε στιγμή.
- Εξυπηρετεί αποκλειστικά πληροφοριακούς σκοπούς.
- Δεν παρέχεται εγγύηση για την ύπαρξη τυχόν λαθών ή για τη λανθασμένη χρήση ή για μη επιθυμητά αποτελέσματα από τη χρήση των προτεινόμενων στο παρόν διαδικασιών.
= Εκτυπώσεις – Printing
Γενικά
Το module Printing.apk δίνει τη δυνατότητα των εκτυπώσεων στο PocketBiz.
Η εκτύπωση από το PocketBiz γίνεται με την χρήση πρότυπων αρχείων εκτύπωσης, τα οποία βρίσκονται στον πίνακα tblPrintouts. Αυτά τα αρχεία περιέχουν το σταθερό κείμενο της εκτύπωσης και ειδικές λέξεις (tokens) οι οποίες αντικαθίστανται κατά την εκτύπωση με τα ανάλογα data.
Σχετικοί Πίνακες
| Πίνακας | Περιγραφή | Article Type | Sync Type |
|---|---|---|---|
| tblPrintouts | Πίνακας εκτυπώσεων | DOWNLOAD | PUBLIC |
| SDT | Τύποι παραστατικών πώλησης | DOWNLOAD | PUBLIC |
| XDT | Τύποι παραστατικών αποθήκης | DOWNLOAD | PUBLIC |
Tα πεδία του tblPrintouts που μας ενδιαφέρουν είναι τα εξής:
| Πεδίο | Περιγραφή | Παρατηρήσεις |
|---|---|---|
| PrintoutID | Μοναδικό ID έγγραφής | |
| PrintoutDescr | Περιγραφή Εκτύπωσης | |
| PrintoutHeader | Template του Header | μπορώ να βάλω είτε ειδικά tokens, είτε πεδία που βρίσκονται στο select του PrintoutHeaderSQL |
| PrintoutDetail | Template του Detail | μπορώ να βάλω είτε ειδικά tokens, είτε πεδία που βρίσκονται στο select του PrintoutDetailSQL |
| PrintoutFooter | Template Footer | |
| PrintoutDetailLines | Πλήθος γραμμών Detail (ΠΡΟΣΟΧΗ αν το χαρτί χωράει πχ. 10 γραμμές εκτύπωσης και κάθε προϊόν καταλαμβάνει 2 γραμμές, θα πρέπει να βάλουμε την τιμή 5) | Αν δεν θέλουμε να γίνεται σελιδοποίηση τότε θέτουμε στο πεδίο την τιμή 1000. |
| PrintoutHeaderAlways | Εκτύπωση Header σε κάθε σελίδα | |
| PrintoutFooterAlways | Εκτύπωση Footer σε κάθε σελίδα | |
| PrintoutFont | Font Name | Δεν χρησιμοποιείται |
| PrintoutFontSize | Μέγεθος Font | Δεν χρησιμοποιείται |
| PrintoutHeaderSQL | Γράφω το sql για τα πεδία που θέλω να εμφανίσω στο header. Θα πρέπει να βάλω το $ID$ σε κάθε select ώστε να παίρνω στοιχεία για το συγκεκριμένο παρ/κο. | |
| PrintoutDetailSQL | Γράφω το sql για τα πεδία που θέλω να εμφανίσω στο detail. Θα πρέπει να βάλω το $ID$ σε κάθε select ώστε να παίρνω στοιχεία για το συγκεκριμένο παρ/κο. |
Τα πεδία των πινάκων XDT & SDT που μας ενδιαφέρουν είναι τα εξής:
| Πεδίο | Περιγραφή |
|---|---|
| PrintoutID | FK tblPrintouts (PrintoutID) H πρότυπη εκτύπωση που θα χρησιμοποιηθεί κατά τις εκτυπώσεις του παραστατικού |
| Allowprint |
Aν η εκτύπωση του παραστατικού είναι υποχρεωτική (θεωρημένο)
|
| Copies | Πόσα Αντίγραφα θα εκτυπωθούν |
Πώς Λειτουργεί ο tblPrintouts
Η εκτύπωση χωρίζεται σε τρία μέρη:
- Το header (πεδίο PrintoutHeader) που τυπώνεται στο πάνω μέρος κάθε σελίδας,
- Το detail (πεδίο PrintoutDetail) που τυπώνεται για κάθε γραμμή παραστατικού, καρτέλας, κτλ
- το footer (πεδίο PrintoutFooter) που τυπώνεται στο τέλος της σελίδας.
- Τα details του footer (PrintoutFooterDetail)
Tα πεδία header, detail, footer και footer-details περιέχουν κωδικοποιημένες λέξεις (tokens) οι οποίες αντιστοιχούν σε πεδία του προγράμματος και ελεύθερο κείμενο, το οποίο τυπώνεται ως έχει.
Τα tokens τοποθετούνται ανάμεσα σε 2 χαρακτήρες δολαρίου ($) ή δίεσης (#), ανάλογα αν επιθυμούμε να γίνει alignment $αριστερά$ ή #δεξιά# αντίστοιχα.
Για παράδειγμα, το token cuscode αντιστοιχεί στον κωδικό πελάτη. Επομένως, αν θέλουμε να εμφανίσουμε τον κωδικό πελάτη με alignment στα αριστερά γράφουμε: $cuscode $.
Οι θέσεις από το πρώτο token delimiter ($ ή #) μέχρι και το δεύτερο token delimiter αποτελούν τον χώρο του token. Το πρόγραμμα θα «σεβαστεί» τον χώρο που έχουμε ορίσει για το token και θα προσπαθήσει να χωρέσει το token σε αυτό τον χώρο. Αν το μήκος του πεδίου είναι μεγαλύτερο από το μήκος του token, τότε θα εμφανιστούν μόνο οι πρώτοι χαρακτήρες που χωράνε στον χώρο. Αν το μήκος του πεδίου είναι μικρότερο από του token, τότε θα γεμίσει τον υπόλοιπο χώρο με κενά.
Για την αποστολή escape χαρακτήρα στον εκτυπωτή χρησιμοποιούμε το σύμβολο ~ π.χ.
~29~. (στο windows mobile ο αντίστοιχος χαρακτήρας ήταν ο ^)
Τα 2 select για header και details είναι πεδία στον tblPrintouts. Θα πρέπει να βάλω το $ID$ σε κάθε select ώστε να παίρνω στοιχεία για το συγκεκριμένο παραστατικό.
PrintoutHeaderSQL nvarchar(MAX) Checked
PrintoutDetailSQL nvarchar(MAX) Checked
Αν τα αφήσει null τότε θα έχουμε κάποια defaults.
Επομένως, στο PrintoutHeader και στο PrintoutFooter μπορώ να βάλω είτε ειδικά tokens, είτε πεδία που βρίσκονται στο select του PrintoutHeaderSQL
Επομένως, στο PrintoutDetail μπορώ να βάλω είτε ειδικά tokens, είτε πεδία που βρίσκονται στο select του PrintoutDetailSQL
| Πεδίο PrintoutAction | |
|---|---|
| Τιμή | Ενέργεια |
| 1 | Εκτύπωση παραστατικού |
| 2 | Εμφάνιση |
| 3 | Αποστολή email με περιεχόμενο το κείμενο του παραστατικού |
| 4 | Αποστολή email με επισυναπτόμενο html αρχείο, με περιεχόμενο το κείμενο του παραστατικού |
| 5 | Αποστολή email με επισυναπτόμενο PDF αρχείο, με περιεχόμενο το κείμενο του παραστατικού |
| Άλλη τιμή | Εμφανίζεται μία οθόνη με επιλογές, που εκτελούν τις ενέργειες των παραπάνω τιμών |
PrintDesigner
Είναι το πρόγραμμα με το οποίο μπορούμε να φτιάξουμε εκτυπώσεις.
Για να το λειτουργήσουμε, ρυθμίζουμε πρώτα το connection string στο .ini αρχείο του ώστε να συνδεθεί στη βάση του PocketBiz, το τρέχουμε και επιλέγουμε την εκτύπωση που θέλουμε να επεξεργαστούμε.
Μας δίνει τη δυνατότητα να κάνουμε αλλαγές σε header, detail ή footer, καθώς επίσης και να δοκιμάσουμε την εκτύπωση απευθείας σε κάποιον εκτυπωτή που έχουμε συνδεδεμένο στο PC μας.
Προσοχή, δε μας δίνει τη δυνατότητα να προσθέσουμε νέα εγγραφή στον tblPrintouts, ούτε να επεξεργαστούμε το πεδίο PrintoutDetailLines.
Σχετικές παράμετροι πίνακα CONFIGURATION
| ΠΑΡΑΜΕΤΡΟΣ |
ΠΕΡΙΓΡΑΦΗ ΛΕΙΤΟΥΡΓΙΑΣ ΤΗΣ ΠΑΡΑΜΕΤΡΟΥ |
Τιμές για την παράμετρο |
ΠΕΡΙΓΡΑΦΗ ΛΕΙΤΟΥΡΓΙΑΣ ΤΗΣ ΤΙΜΗΣ |
|---|---|---|---|
| PRINTER_NAME |
Ουσιαστικά, ορίζει την κωδικοσελίδα ελληνικών χαρακτήρων που χρησιμοποιεί ο εκτυπωτής |
Cp1253 ή αν δεν οριστεί τιμή |
Θα χρησιμοποιηθεί η codepage Windows 1253 |
| CPCL | Στην εκτύπωση θα χρησιμοποιηθεί φορητός εκτυπωτής Zebra, ο οποίος χρησιμοποιεί τη γλώσσα προγραμματισμού CPCL (όπως πχ ο MZ320). | ||
| MyPrinter | Στην εκτύπωση θα χρησιμοποιηθεί ο εκτυπωτής Custom MyPrinter (ουσιαστικά, αυτή η τιμή δηλώνει απλά τη χρήση codepage Windows 1253) | ||
| Epson1253 | Στην εκτύπωση θα χρησιμοποιηθούν με codepage 1253 οι εκτυπωτές της Epson (πχ LX-300-II και LX-350-II) ή όσοι υποστηρίζουν EPSON Emulation. | ||
| Epson437 | Στην εκτύπωση θα χρησιμοποιηθούν με codepage 437 οι εκτυπωτές της Epson (πχ LX-300-II και LX-350-II) ή όσοι υποστηρίζουν EPSON Emulation. | ||
| Seiko437 | Στην εκτύπωση θα χρησιμοποιηθεί ο Seiko Precidsion εκτυπωτής. Μπορεί να χρησιμοποιηθεί και για άλλους εκτυπωτές που χρησιμοποιούν το codepage 437, απλά οι χαρακτήρες Ϊ και Ϋ θα εκτυπωθούν σαν Ι και Υ αντίστοιχα, μιας και δεν τους υποστηρίζει ο seiko. | ||
|
Printhand PrinthandTrial PrinterShare |
Θα χρησιμοποιηθεί η αντίστοιχη εξωτερική εφαρμογή. Mπορούμε να ορίσουμε τον τύπο του αρχείου που θα δημιουργηθεί και θα αποσταλεί στον εκτυπωτή. Οι επιτρεπόμενες τιμές είναι html ή pdf. Για το σκοπό αυτό, μετά το όνομα του εκτυπωτή, θέτουμε σαν διαχωριστή τον χαρακτήρα : και ακολουθεί η λέξη html ή pdf (π.χ. PrinterShare:PDF). Αν δεν οριστεί ο τύπος του αρχείου, χρησιμοποιείται html αρχείο. | ||
| Printer6820 | Θα χρησιμοποιηθεί ο εκτυπωτής Intermec 6820\6822 | ||
| Οποιαδήποτε άλλη τιμή | Η τιμή αυτή θα πρέπει να ορίζει ένα charset, που υποστηρίζει το Android. Αν δεν συμβεί αυτό, τότε θα προκύψει σφάλμα UnsupportedEncodingException |
Ρυθμίσεις Εκτυπωτών
- My Printer της Custom
Στον εκτυπωτή My Printer της Custom, μπορούμε να μεγεθύνουμε την γραμματοσειρά που χρησιμοποιούμε, προσθέτοντας στην αρχή του header την ακόλουθη escape ακολουθία:
~29~!~(H-1)+(W-1)*16~
Το τμήμα της παραπάνω ακολουθίας, που είναι bold, αντικαθίσταται με τον αριθμό που προκύπτει κάνοντας την αριθμητική πράξη που αυτό περιγράφει.
Είναι:
H ο αριθμός που δηλώνει την επιθυμητή μεγέθυνση του ύψους της γραμματοσειράς. Λαμβάνει τιμές 1-8.
W ο αριθμός που δηλώνει την επιθυμητή μεγέθυνση του πλάτους της γραμματοσειράς. Λαμβάνει τιμές 1-8.
Παράδειγμα:
Αν θέλουμε να διπλασιάσουμε το ύψος της γραμματοσειράς, έχουμε H = 2 και W=1, οπότε η escape ακολουθία που θα χρησιμοποιήσουμε είναι: ~29~!~1~
Epson LX-300-II και LX-350-II
Για τους συγκεκριμένους εκτυπωτές πριν δοκιμάσετε οποιαδήποτε εκτύπωση πρέπει να σιγουρευτείτε ότι το ύψος του χαρτιού στο οποίο είναι ρυθμισμένος να τυπώνει ο εκτυπωτής είναι ίδιο με το ύψος του χαρτιού εκτύπωσης. Για να γίνει αυτό θα πρέπει να εκτυπώσετε τις ρυθμίσεις του εκτυπωτή όπως αναφέρεται στο εγχειρίδιο χρήσης του.
Zebra MZ320
Ο εκτυπωτής αυτός δεν έχει κάποια προεγκατεστημένη γραμματοσειρά που να υποστηρίζει ελληνικά. Επομένως θα πρέπει να του περάσει κάποια ο υλοποιών την εγκατάσταση. Στον φάκελο: \\sharepointsrv\Common\Development\Pocketbiz\Documentation\Επίσημοι οδηγοί\Updated\Manuals για Administrators\How-to\Android\PocketBizPrinting\Zebra\ Software υπάρχουν οδηγίες για την παραπάνω διαδικασία.
Tokens Εκτυπώσεων
Δυναμική χρήση Tokens
Η υλοποίηση δυναμικής χρήσης tokens χρησιμοποιείται στις εκτυπώσεις παραστατικών. Ο εγκαταστάτης της εφαρμογής, μπορεί να χρησιμοποιήσει σαν token εκτύπωσης οποιοδήποτε πεδίο πίνακα (ή και συνδυασμό πεδίων) αρκεί το όνομα του στο select να έχει ακριβώς το ίδιο όνομα με το token.
Στην συνέχεια, τα tokens αυτά αντικαθίστανται από τις τιμές των αντίστοιχων πεδίων.
Για παράδειγμα, αν χρησιμοποιήσω το token $CUSDirector$ στο header θα τυπωθεί το πεδίο CUSDirector αν υπάρχει στο ερώτημα του header.
ΠΡΟΣΟΧΗ: Δεν λαμβάνουμε υπόψη μας τυχόν αλλαγές στοιχείων πελάτη (πίνακας tblSLMRequest). Για το λόγο αυτό, υπάρχει περίπτωση η χρήση των αντίστοιχων tokens να μην έχει τα επιθυμητά αποτελέσματα. Αυτό είναι εν γνώσει μας. Για την αποφυγή μιας τέτοιας περίπτωσης, πρέπει να χρησιμοποιήσουμε μη δυναμικά tokens (αυτά που περιγράφονται παρακάτω), ή να χρησιμοποιήσουμε δυναμικά tokens με πεδία που δεν λαμβάνουν χώρα στην αίτηση αλλαγής στοιχείων πελάτη.
Περιορισμοί
Το παραπάνω δεν ισχύει για τα token που μπαίνουν στο PrintoutDetail και συμμετέχουν στο υπολογισμό αξιών και συνόλων είτε στo Detail είτε στο Footer. Αυτά τα token θα πρέπει να έρχονται με το όνομα που υπάρχει στους παρακάτω πίνακες. Αν λόγω χώρου αυτό δεν είναι δυνατό τότε θα πρέπει υποχρεωτικά το πεδίο να υπάρχει 2 φορές στο ερώτημα.
Για παράδειγμα:
Tο πεδίο tblInvDetail.ssditemdiscpcnt αντιστοιχεί στο token D1. Αν θέλουμε στο printout να το εμφανίσουμε ως DIS1 τότε το ερώτημα θα διαμορφωθεί ως εξής:
Select tblInvDetail.ssditemdiscpcnt as DIS1 …. From …. Where …
Με το ερώτημα αυτό ναι μεν το token DIS1 θα αντικατασταθεί με την τιμή του πεδίου tblInvDetail.ssditemdiscpcnt αλλά κάποια token που αναπαριστούν σύνολα (π.χ. DISCA) δεν θα υπολογιστούν σωστά. Επομένως η λύση σε αυτό το πρόβλημα είναι να προστεθεί στο παραπάνω select η στήλη tblInvDetail.ssditemdiscpcnt είτε με το πλήρες όνομα της είτε με κάποιο από τα γνωστά alias που υπάρχουν στους παρακάτω πίνακες.
Παραστατικά
Σε περίπτωση που tblPrintouts.PrintoutDetailLines=1000, τότε δεν γίνεται σελιδοποίηση.
Header:
| CANCELLING | DOS.doscode, tblInvMaster.docnumber, tblInvMaster.dockatahorisidate | Περιγραφή του τύπου: “Ακυρώνει το ΤΔΑ 13 της 15/4/2004” |
|---|---|---|
| CANCELDOC | DOS.doscode, tblInvMaster.docnumber |
Περιγραφή του τύπου: «ΤΔΑ 13» Αφορά είτε ακυρωτικό παραστατικό, είτε το πρώτο παραστατικό που εκδώθηκε, κατά τη διαδικασία έκδοσης διπλού παραστατικού στο Exvan (πεδίο previousinvmasterid) |
| CANCELDATE | tblInvMaster.dockatahorisidate | Π.χ. 15/4/2004 |
| SDTCODE | SDT.sdtcode | Κωδικός Παραστατικού |
| SDTDESCR | SDT.sdtdescription | Περιγραφή Παραστατικού |
| DOS | DOS.doscode | Σειρά Παραστατικού |
| SEN | tblInvMaster.docnumber | Αρίθμηση Σειράς Παραστατικού |
| DATE | tblInvMaster.dockatahorisidate | Ημερομηνία καταχώρησης (χωρίς ώρα) |
| RDATE | tblInvMaster.docrequestdate | Ημερομηνία Παράδοσης |
| TIME | tblInvMaster.dockatahorisidate | H Ώρα από το πεδίο dockatahorisidate |
| CUSCODE, CC | CUS.Cuscode | Κωδικός Πελάτη |
| DCUSCODE, DCC | CUS.Cuscode | Κωδικός Πελάτη debit |
| SLMCODE | SLM.Slmcode | Κωδικός Πωλητή |
| LEENAME | LEE.Leename | Επωνυμία Πελάτη |
| DLEENAME | LEE.Leename | Επωνυμία Πελάτη debit |
| PLATES | Vehicles.Plates ή Vehicles.AlternativePlates | Πινακίδες Οχήματος (αν υπάρχουν εναλλακτικές, αλλιώς οι κανονικές) |
| PRFDESCR | PRF.prfdescr | Επάγγελμα Πελάτη |
| DPRFDESCR | PRF.prfdescr | Επάγγελμα Πελάτη debit |
| FORTOSI | “ΕΔΡΑ ΜΑΣ” | |
| ADRSTREET | ADR.adrstreet | Διεύθυνση Πελάτη |
| DADRSTREET | ADR.adrstreet | Διεύθυνση Πελάτη debit |
| PROORISMOS | Διεύθυνση Προορισμού: Διαβάζει το adrstreet από το tblSLMRequest αν νέος πελάτης, αλλιώς αν adridlogistiriou <> adridproorismou τότε adrstreet+adrnumber+adrcity από ADR προορισμού, αλλιώς εμφανίζει «ΕΔΡΑ ΠΕΛΑΤΗ» | |
| ADRCITY | ADR.Adrcity | Πόλη |
| DADRCITY | ADR.Adrcity | Πόλη πελάτη debit |
| ADRDISTRICT | ADR.Adrdistrict | Περιοχή |
| ADRPHONE | Nvl(adrphone1, adrphone2) | Τηλέφωνο |
| DADRPHONE | Nvl(adrphone1, adrphone2) | Τηλέφωνο πελάτη debit |
| CPMTITLE | CPM.cpmtitle | Τρόπος Πληρωμής |
| AFM | LEE.leeafm | Α.Φ.Μ. Πελάτη |
| DAFM | LEE.leeafm | Α.Φ.Μ. Πελάτη debit |
| DOY | TXO.txoname | Δ.Ο.Υ. Πελάτη |
| DDOY | TXO.txoname | Δ.Ο.Υ. Πελάτη debit |
| PAYD | tblInvMaster.tdopaymentdisc | Έκπτωση Τρ. Πληρωμής (αξία) |
| CUSD | tblInvMaster.tdotraderdiscpcnt | Έκπτωση Πελάτη (ποσοστό) |
| COMMENTS | tblInvMaster.doccomment | Σχόλια |
| REASON | To ίδιο με CANCELLING | To ίδιο με CANCELLING |
| BALANCE | Το υπόλοιπο πελάτη, χωρίς να υπολογίσουμε το τρέχον παραστατικό | |
| NEWBAL | Το νέο υπόλοιπο πελάτη, υπολογίζοντας και το τρέχον παραστατικό | |
| SLM | SLM.SLMName | Όνομα πωλητή |
| SENDWAY | TPM.tpmdescr | Τρόπος αποστολής |
| << (άνοιγμα πίκα) | ||
| >> (κλείσιμο πίκα) | ||
| DOSD | DOS.dosdescr | Περιγραφή σειρας |
| ADRDESCR | ADR.Adrdescription | Όνομα Διευθ. Λογιστηρίου |
| ADRDPR | ADR.Adrdescription | adrdescription από ADR προορισμού αν adridlogistiriou <> adridproorismou, αλλιώς «» |
| EAFDSS | Vehicles.eafdss | s/n του φορολογικού μηχανισμού |
| COMMENTS1, 2, 3, 4, 5 | Σπάει τα σχόλια σε 5 κομμάτια των 50 χαρακτήρων | |
| DEBIT1, 2, 3 | Παρουσιάζουν στοιχεία του debit πελάτη. Αυτά μπορεί να είναι CUS.cuscode, LEE.leename, LEE.leeafm, TXO.txoname (ΔΟΥ) | |
| RCODE | tblReasons.Reasoncode | |
| RDESCR | tblReasons.ReasonDescr | |
| CITY2 |
ADR.adrcity (tblSLMRequest.adrcity2) Όταν διεύθυνση λογιστηρίου<> διεύθυνσης προορισμού |
Πόλη προορισμού (αν αίτηση αλλαγής στοιχείων πελάτη, τότε το παίρνει από τον tblSLMRequest) |
| STREET2 |
ADR.adrstreet + ADR.adrnumber (tblSLMRequest.adrstreet2 + tblSLMRequest Όταν διεύθυνση λογιστηρίου<> διεύθυνσης προορισμού.adrnumber2) |
Διεύθυνση προορισμού (οδός & αριθμός) (αν αίτηση αλλαγής στοιχείων πελάτη, τότε τα παίρνει από τον tblSLMRequest) |
| ZIPCODE2 |
ADR.adrzipcode Όταν διεύθυνση λογιστηρίου<> διεύθυνσης προορισμού |
Ταχυδρομικός Κώδικας (διεύθυνσης προορισμού) |
| CITY3 |
ADR.adrcity (tblSLMRequest.adrcity2) Όταν διεύθυνση λογιστηρίου= διεύθυνσης προορισμού, τότε δίνει τη διεύθυνση λογιστηρίου |
Πόλη προορισμού (αν αίτηση αλλαγής στοιχείων πελάτη, τότε το παίρνει από τον tblSLMRequest) |
| STREET3 |
ADR.adrstreet + ADR.adrnumber (tblSLMRequest.adrstreet2 + tblSLMRequest.adrnumber2) Όταν διεύθυνση λογιστηρίου= διεύθυνσης προορισμού, τότε δίνει τη διεύθυνση λογιστηρίου |
Διεύθυνση προορισμού (οδός & αριθμός) (αν αίτηση αλλαγής στοιχείων πελάτη, τότε τα παίρνει από τον tblSLMRequest) |
| ZIPCODE3 |
ADR.adrzipcode Όταν διεύθυνση λογιστηρίου= διεύθυνσης προορισμού, τότε δίνει τη διεύθυνση λογιστηρίου |
Ταχυδρομικός Κώδικας (διεύθυνσης προορισμού) |
| ZIPCODE | ADR.adrzipcode | Ταχυδρομικός Κώδικας (διεύθυνσης λογιστηρίου) |
| DZIPCODE | ADR.adrzipcode | Ταχυδρομικός Κώδικας (διεύθυνσης λογιστηρίου) πελάτη debit |
| CASHCREDIT | Περιγραφές «ΜΕΤΡΗΤΟΙΣ», «ΕΠΙ ΠΙΣΤΩΣΕΙ» | Αν ειναι μετρητοίς ή επι πιστώσει, ανάλογα με τα πεδία updclearancecash και updclearancecredit του SDT |
| SDTUDFCH1 | SDT.sdtudfchar1 | |
| MASTERCH1 | tblInvMaster.udfchar1 | |
| ADRCODE | ADR.adrcode | Κωδικός Διευθ. Λογιστηρίου |
| ADRCPR | ADR.adrcode | Κωδικός Διευθ. Προορισμού |
| LC | tblInvMaster.EntryField2 | Πεδίο EntryField2 του tblInvMaster (για Αυτόματους Πωλητές) |
| PC | Πεδίο EntryField2 του tblInvMaster για το προηγούμενο παραστατικό στον ίδιο ΑΠ (για Αυτόματους Πωλητές) | |
| BN | tblInvMaster. EntryField1 | Πεδίο EntryField1 του tblInvMaster (για Αυτόματους Πωλητές) |
| EF1 - EF8 | tblInvMaster. EntryField1 - tblInvMaster. EntryField8 | Πεδία EntryField1 - EntryField8 |
| RCITY2 | tblSLMRequest.adrcity2 | Πόλη προορισμού Αίτησης |
| RSTREET2 | tblSLMRequest.adrstreet2 + tblSLMRequest.adrnumber2 | Οδός προορισμού Αίτησης |
| RZIPCODE2 | tblSLMRequest.adrzipcode2 | Ταχυδρ. Κώδικας προορισμού Αίτησης |
| RDISTRICT2 | tblSLMRequest.district2 | Περιοχή προορισμού Αίτησης |
| ADR.adremail ή tblSLMRequest.adremail | Email πελάτη ή αίτησης | |
| FAX | ADR.adrfax ή tblSLMRequest.adrfax | Fax πελάτη ή αίτησης |
| PHONE3 | ADR.adrphone3 ή tblSLMRequest.adrphone3 | Τηλέφωνο 3 πελάτη ή αίτησης |
| SUC1 | SLM.udfchar1 | |
| SUC2 | SLM.udfchar2 | |
| SUC3 | SLM.udfchar3 | |
| SUI1 | SLM.udfint1 | |
| CTODAY | Ημερομηνία στην μορφή 30/11/2008 | |
| CTIME | Ώρα στην μορφή 10:15 μμ | |
| CNOW | Ημερομηνία και ώρα στην μορφή 30/11/2008 10:15 μμ | |
| SOUDF | Udf πεδίο για Field Service | tbServiceOrders.SOudfchar1 |
| COPY |
Για Field Service, αν είναι το πρώτο αντίγραφο τυπώνει «ΠΕΛΑΤΗ» ενώ αν είναι το δεύτερο τυπώνει «ΛΟΓΙΣΤΗΡΙΟ». Αλλιώς το πρώτο τυπώνει «ORIGINAL» ενώ το δεύτερο τυπώνει «COPY». | |
| PON | tblInvMaster. PONumber | Σχετικό παραστατικό |
| PAGENO | Αριθμός σελίδας εκτύπωσης στην μορφή 2/6 | |
| ADRDIST | ADR.adrdistrict | περιοχή της διεύθυνσης προορισμού |
| CUDFC2 | CUS.udfchar2 | |
| LFINTERMEC | Line Feed σε εκτυπωτή Intermec 6820 (NPCP, Serial, Bluetooth). Αν ο εκτυπωτής που χρησιμοποιείται δεν είναι Intermec, τότε το συγκεκριμένο token αντικαθίσταται με κενό αλφαριθμητικό. | |
| LFONEIL | Line Feed σε εκτυπωτή O’Neil. Αν ο εκτυπωτής που χρησιμοποιείται δεν είναι O’Neil, τότε το συγκεκριμένο token αντικαθίσταται με κενό αλφαριθμητικό. |
Lines:
| CODCODE, CC |
STI.codcode ή STI.basecode Ή tblServices.ServiceCode (Field Service) |
Κωδικός Ή αν PRINTMULTIPLESIZES<>0, basecode |
|---|---|---|
| COLOR | STI.colorcode | Αν PRINTMULTIPLESIZES<>0, χρώμα |
| SYNTH | STI.udfchar3 | Αν PRINTMULTIPLESIZES<>0, Σύνθεση |
| STINAME | STI.stiname Ή tblServices.ServiceDescription (Field Service) | Περιγραφή |
| UNIA, UA, U | UNI.unishortname | Μονάδα Μέτρησης Α |
| QTYA, Q | tblInvDetail.stdqtya | Ποσότητα Α |
| UNIB | UNI.unishortname | Μονάδα Μέτρησης Β |
| QTYB | tblInvDetail.stdqtyb | Ποσότητα Β |
| CQTYA, CA | Ποσότητα Α σε συμμιγή αριθμό (έχουμε ορίσει σαν ποσότητα Α τη μεγάλη ποσότητα, δηλαδή το ακέραιο μέρος της διαίρεσης) | |
| CQTYB, CB | Ποσότητα Β σε συμμιγή αριθμό (έχουμε ορίσει σαν ποσότητα Β τη μικρή ποσότητα, δηλαδή το υπόλοιπο της διαίρεσης) | |
| BINA | STI.stiratiofrom/STI.stiratioto | |
| PRICE | tblInvDetail.ssdunitprice | Τιμή Μονάδος |
| TOTAMOUNT, ΤΟΑΜ | tblInvDetail.ssdunitprice*tblInvDetail.stdqtya | Καθαρή αξία προ εκπτώσεων |
| DISC | 100 - ((100 – tblInvDetail.ssdpricelistdiscpcnt) * (100 – tblInvDetail.ssditemdiscpcnt) / 100) | Έκπτωση |
| DISCA | tblInvDetail.ssditemdisc + tblInvDetail.ssdpricelistdisc + tblInvDetail .ssdtraderdisc + tblInvDetail.ssdpaymentdisc + tblInvDetail.disc1 + tblInvDetail.disc2 | Άθροισμα αξίας όλων των εκπτώσεων |
| D1 | tblInvDetail.ssditemdiscpcnt | Ποσοστό έκπτωσης είδους |
| D2 | tblInvDetail.ssdpricelistdiscpcnt | Ποσοστό έκπτωσης τιμοκαταλόγου |
| LOTN | tblLots.Lotnumber | Αριθμός παρτίδας |
| LOTD | tblLots.Lotdate | Ημερομηνία παρτίδας |
| SNF | Serialnumber+1 | To πρώτο serial number που κόπηκε για το συγκεκριμένο προϊόν |
| SNL | Serialnumber+ stdqtya | To τελευταίο serial number που κόπηκε για το συγκεκριμένο προϊόν |
| FINALA | Αξία γραμμής μετά τις εκπτώσεις είδους και τιμοκαταλόγου | |
| FINEFK | (tblInvDetail.ssdunitprice + tblInvDetail.efk) * tblInvDetail.stdqtya- tblInvDetail.ssditemdisc- tblInvDetail.ssdpricelistdisc | Αξία γραμμής μετά τις εκπτώσεις είδους και τιμοκαταλόγου και αφού προστεθεί ο ειδικός φόρος κατανάλωσης (ROUNDLINEVALUES=3) |
| VAT, V | tblInvDetail.ssdvatpcnt | Ποσοστό Φ.Π.Α. γραμμής |
| VATVA | tblInvDetail.ssdvatvalue | Αξία Φ.Π.Α. γραμμής |
| ITEMD | tblInvDetail.ssditemdiscpcnt | Ποσοστό έκπτωσης είδους |
| PRCD | tblInvDetail.ssdpricelistdiscpcnt | Ποσοστό έκπτωσης τιμοκαταλόγου |
| PAYD | tblInvMaster.tdopaymentdiscpcnt | Ποσοστό έκπτωσης τρόπου πληρωμής |
| CUSD | tblInvMaster.tdotraderdiscpcnt | Ποσοστό έκπτωσης πελάτη |
| SUMD | Συνολικό ποσοστό εκπτώσεων | |
| NETV | tblInvDetail.ssdnetvalue | Τελική αξία μετά εκπτώσεων |
| NVD | tblInvDetail.ssdnetvalue/ stdqtya | Εφαρμογή έκπτωσης στην τιμή |
| NETVGIFT, NVG | tblInvDetail.ssdnetvalue | Τελική αξία μετά εκπτώσεων. Αν 100% έκπτωση τότε γράφει «ΔΩΡΟ» |
| EXPIRE | tblInvDetail. udfchar1 | Ημερομηνία Λήξης(udfchar1 πεδίο του tblInvDetail) |
| LINESUM, LSUM | tblInvDetail.ssdnetvalue + tblInvDetail.ssdvatvalue | Αξία γραμμής με Φ.Π.Α. |
| S0, 1, 2, …, 20 | Νούμερα παπουτσιών | |
| RCODE | tblReasons.Reasoncode | ReasonCode |
| CTGD | CTG.ctgdescr | Περιγραφή κατηγορίας από CTGID του STI |
| UDF2 | tblInvDetail.udfchar2 | Udfchar2 πεδίο του tblInvDetail |
| UDF3 | tblInvDetail.Udfchar3 | Udfchar3 πεδίο του tblInvDetail |
| RDESCR | tblReasons.ReasonDescr | ReasonDescr |
| EFK | STI.efk | |
| RFR | STI.stiratiofrom | |
| UC1 | STI.stiudfchar1 | |
| UC2 | STI.stiudfchar2 | |
| UC3 | STI.stiudfchar3 | |
| LCN | tblInvDetail. Linecounter | Linecounter πεδίο του tblInvDetail |
| ITMVD | tblInvDetail. ssditemdisc | Πεδίο ssditemdisc του tblInvDetail |
| PRCVD | tblInvDetail.ssdpricelistdisc | Πεδίο ssdpricelistdisc του tblInvDetail |
| LN | tblInvDetail. LineNumber | Πεδίο LineNumber του tblInvDetail |
| EF1 – EF7 | tblInvDetail.EntryField1 - tblInvDetail. EntryField7 | Πεδία EntryField1 – EntryField7 |
| RT | Round(tblInvDetail.stdqtya/ tblInvDetail.stdqtyb,4) | Συντελεστής που συνδέει ποσότητα Α με ποσότητα Β |
| CLN, A | αρίθμηση γραμμών παραστατικού με βάση το looping | |
| FRQTY | tblInvDetail.freshqty | |
| EXPQTY | tblInvDetail.expiredqty | |
| OTHQTYA, OTHQTY | tblInvDetail.otherqty | |
| MU | multiuniqty – είναι η ποσότητα Α ή η ποσότητα Β ανάλογα με το defaultuniid | |
| VNE | tblInvDetail.ssdunitprice* tblInvDetail.stdqtya – (εκπτώσεις) | Σύνολο καθαρής αξίας (χωρίς να υπολογίσουμε το efk) |
| FNE | (tblInvDetail.ssdunitprice* tblInvDetail.stdqtya – (εκπτώσεις))* tblInvDetail.ssdvatpcnt/100 | Αξία ΦΠΑ (χωρίς να υπολογίσουμε το efk) |
| VFE | (tblInvDetail.ssdunitprice* tblInvDetail.stdqtya – (εκπτώσεις))* (1+tblInvDetail.ssdvatpcnt/100) | Συνολική αξία (χωρίς να υπολογίσουμε το efk) |
| EFF | Abs(tblInvDetail.efk *(1+ tblInvDetail.ssdvatpcnt/100)) | ΕΦΚ και ΦΠΑ (απόλυτη τιμή) |
| QEF | Abs(tblInvDetail.efk* tblInvDetail.stdqtya *(1+ tblInvDetail.ssdvatpcnt/100)) | ΕΦΚ και ΦΠΑ και ποσότητα (απόλυτη τιμή) |
| QE | Abs(tblInvDetail.efk* tblInvDetail.stdqtya) | ΕΦΚ και ποσότητα (απόλυτη τιμή) |
| FQ | tblInvDetail.freeqty | Δωρεάν |
Lines for groups(Cosmos Mobile)(XVN_PRINTGROUPS=1):
| STINAME | STI.stiname | Περιγραφή |
|---|---|---|
| UNIA, UA | UNI.unishortname | Μονάδα Μέτρησης Α |
| QTYA | tblInvDetail.stdqtya | Ποσότητα Α (άθροισμα) |
| PRICE | tblInvDetail.ssdunitprice | Τιμή Μονάδος |
| NETV | tblInvDetail.ssdnetvalue | Τελική αξία μετά εκπτώσεων (άθροισμα) |
| NVD | tblInvDetail.ssdnetvalue/ stdqtya | Εφαρμογή έκπτωσης στην τιμή (άθροισμα) |
| LINESUM, LSUM | tblInvDetail.ssdnetvalue + tblInvDetail.ssdvatvalue | Αξία γραμμής με Φ.Π.Α. (άθροισμα) |
| VATVA | tblInvDetail.ssdvatvalue | Αξία Φ.Π.Α. γραμμής (άθροισμα) |
| VVANR | tblInvDetail.ssdnetvalue*tblInvDetail.ssdvatpcnt/100 | Αξία Φ.Π.Α. γραμμής (άθροισμα χωρίς στρογγυλοποίηση των τιμών που αθροίζονται) |
| CLN | αρίθμηση γραμμών παραστατικού με βάση το looping |
Footer:
| PAGENO | Αριθμός Σελίδας | |
|---|---|---|
| TOTAL | Αξία Προ Έκπτ. (very old) - άκυρο, έχει πάντα τιμή 0 | |
| TOTAL0 | Καθαρή Αξία 0% | |
| TOTAL6 | Καθαρή Αξία 6% | |
| TOTAL8 | Καθαρή Αξία 8% | |
| TOTAL13 | Καθαρή Αξία 13% | |
| TOTAL15 | Καθαρή Αξία 15% | |
| TOTAL18 | Καθαρή Αξία 18% | |
| VATVAL0 | Αξία Φ.Π.Α. 0% | |
| VATVAL6 | Αξία Φ.Π.Α. 6% | |
| VATVAL8 | Αξία Φ.Π.Α. 8% | |
| VATVAL13 | Αξία Φ.Π.Α. 13% | |
| VATVAL15 | Αξία Φ.Π.Α. 15% | |
| VATVAL18 | Αξία Φ.Π.Α. 18% | |
| TOTALCD | Σύνολο Έκπτωσης Πελάτη | |
| FINALTOT | Αξία Μετά Την Έκπτ. , χωρίς Φ.Π.Α. | |
| TOTALVAT | Σύνολο Φ.Π.Α. | |
| TOTVATNR | Σύνολο Φ.Π.Α. (που έχει υπολογιστεί χωρίς στρογγυλοποιήσεις, από το VVANR) | |
| TOTWITHVAT, TWV | Τελική Αξία με Φ.Π.Α. | |
| COMMENTS, COMMENTS1,2,3,4,5 | tblInvMaster.doccomment | Σχόλια |
| BALANCE | Το υπόλοιπο πελάτη, χωρίς να υπολογίσουμε το τρέχον παραστατικό | |
| NEWBAL | Το νέο υπόλοιπο πελάτη, υπολογίζοντας και το τρέχον παραστατικό | |
| TOTQTYA | Συνολική ποσότητα Α | |
| TOTCQTYA, TCA | Συνολική ποσότητα Α σε συμμιγή αριθμό | |
| TOTCQTYB, TCB | Συνολική ποσότητα Β σε συμμιγή αριθμό | |
| TOTNODISC | ssdunitprice * stdqtya | Αξία Προ Έκπτωσης |
| TOTDISC | ssditemdisc + ssdpricelistdisc + ssdpaymentdisc + ssdtraderdisc | Συνολική αξία έκπτωσης |
| PLATES | Vehicles.Plates ή Vehicles.AlternativePlates | Πινακίδες Οχήματος (αν υπάρχουν εναλλακτικές, αλλιώς οι κανονικές) |
| PROORISMOS | Διεύθυνση Προορισμού: Διαβάζει το adrstreet από το tblSLMRequest αν νέος πελάτης, αλλιώς αν adridlogistiriou <> adridproorismou τότε adrstreet+adrnumber+adrcity από ADR προορισμού, αλλιώς εμφανίζει «ΕΔΡΑ ΠΕΛΑΤΗ» | |
| CPMTITLE | CPM.cpmtitle | Τρόπος Πληρωμής |
| EAFDSS | Vehicles.eafdss | s/n του φορολογικού μηχανισμού |
| DEBIT1, 2, 3 | Παρουσιάζουν στοιχεία του debit πελάτη. Αυτά μπορεί να είναι CUS.cuscode, LEE.leename, LEE.leeafm, TXO.txoname (ΔΟΥ) | |
| CUSD | tblInvMaster.tdotraderdiscpcnt | Έκπτωση Πελάτη (ποσοστό) |
| ADRSTREET | ADR.adrstreet | Διεύθυνση Πελάτη |
| ADRCITY | ADR.Adrcity | Πόλη |
| ADRDISTRICT | ADR.Adrdistrict | Περιοχή |
| DOY | TXO.txoname | Δ.Ο.Υ. Πελάτη |
| EGG | ||
| COPY | Για Field Service, αν είναι το πρώτο αντίγραφο τυπώνει «ΠΕΛΑΤΗ» ενώ αν είναι το δεύτερο τυπώνει «ΛΟΓΙΣΤΗΡΙΟ» | |
| TOTQTYB | Συνολική ποσότητα Β | |
| TOTAL9 | Καθαρή Αξία 9% | |
| TOTAL19 | Καθαρή Αξία 19% | |
| TOTAL4_5 | Καθαρή Αξία 4.5% | |
| VATVAL9 | Αξία Φ.Π.Α. 9% | |
| VATVAL19 | Αξία Φ.Π.Α. 19% | |
| VATVAL4_5 | Αξία Φ.Π.Α. 4.5% | |
| TWV9 | Αξία συνολική με Φ.Π.Α. 9% | |
| TWV19 | Αξία συνολική με Φ.Π.Α. 19% | |
| TWV4_5 | Αξία συνολική με Φ.Π.Α. 4.5% | |
| ADRPHONE | Το τηλέφωνο της διεύθυνσης λογιστηρίου | |
| VAT | Ποσοστό ΦΠΑ (όταν υπάρχει μόνο μία κατηγορία ΦΠΑ στο παραστατικό) | |
| Ανάλογα tokens (TOTALx και VATVALx και TWVx και VDx) για οποιοδήποτε ακέραιο ή δεκαδικό ΦΠΑ χρησιμοποιούμε | Καθαρή αξία και Αξία ΦΠΑ x% και Αξία με ΦΠΑ x% και ο αριθμός του ΦΠΑ (π.χ αν ΦΠΑ 8%, τότε VD8=8, αν 4.5% τότε VD4_5=4.5) | |
| EXCHR | Τυπώνει την τιμή της παραμέτρου exchangerate. Δηλαδή την ισοτιμία συναλλάγματος. | |
| EXCHR2 | Τυπώνει την τιμή της παραμέτρου exchangerate, δηλαδή την ισοτιμία συναλλάγματος, χωρίς να στρογγυλοποιεί | |
| EXCHΤ | Τυπώνει το αποτέλεσμα της διαίρεσης τελική Αξία με Φ.Π.Α. προς την τιμή της παραμέτρου exchangerate | |
| EF8 | tblInvMaster.EntryField8 | Πεδίο EntryField8 |
| SUC1 | SLM.udfchar1 | |
| SUC2 | SLM.udfchar2 | |
| SUC3 | SLM.udfchar3 | |
| SUI1 | SLM.udfint1 | |
| CTODAY | Ημερομηνία στην μορφή 30/11/2008 | |
| CTIME | Ώρα στην μορφή 10:15 μμ | |
| CNOW | Ημερομηνία και ώρα στην μορφή 30/11/2008 10:15 μμ | |
| SLM | Το όνομα το πωλητή | |
| SLMCODE | SLM.slmcode | |
| TMU | Άθροισμα του multiuniqty – δηλαδή άθροισμα της ποσότητας Α ή της ποσότητας Β ανάλογα με το defaultuniid του προϊόντος κάθε γραμμής | |
| TVNE | Total του VNE | Σύνολο καθαρής αξίας (χωρίς να υπολογίσουμε το efk) |
| TFNE | Total του FNE | Αξία ΦΠΑ (χωρίς να υπολογίσουμε το efk) |
| TVFE | Total του VFE | Συνολική αξία (χωρίς να υπολογίσουμε το efk) |
| TEFF | Total του EFF | ΕΦΚ και ΦΠΑ (απόλυτη τιμή) |
| TQEF | Total του QEF | ΕΦΚ και ΦΠΑ και ποσότητα (απόλυτη τιμή) |
| TQE | Total του QE | ΕΦΚ και ποσότητα (απόλυτη τιμή) |
| TFE | Total του FINEFK | Αξία γραμμών μετά τις εκπτώσεις είδους και τιμοκαταλόγου και αφού προστεθεί ο ειδικός φόρος κατανάλωσης |
| TFQ | Total του FQ | Σύνολο του tblInvDetail.freeqty |
| PADP | tblInvMaster.tdopaymentdiscpcnt | Έκπτωση τρόπου πληρωμής (ποσοστό) |
| LFINTERMEC | Line Feed σε εκτυπωτή Intermec 6820 (NPCP, Serial, Bluetooth). Αν ο εκτυπωτής που χρησιμοποιείται δεν είναι Intermec, τότε το συγκεκριμένο token αντικαθίσταται με κενό αλφαριθμητικό. | |
| LFONEIL | Line Feed σε εκτυπωτή O’Neil. Αν ο εκτυπωτής που χρησιμοποιείται δεν είναι O’Neil, τότε το συγκεκριμένο token αντικαθίσταται με κενό αλφαριθμητικό. |
Δυναμικές εκτυπώσεις
Πλέον στο android δίνεται η δυνατότητα του συνδυασμού διαφορετικών εγγραφών του tblPrintouts για την κατασκευή του τελικού printout που θα εκτυπωθεί. Στον πίνακα που ακολουθεί δίνεται ένα ενδεικτικό παράδειγμα:
| PrintoutID | PrintoutDescr | PrintoutHeader | PrintoutDetail | PrintoutHeaderSQL | PrintoutDetailSQL |
|---|---|---|---|---|---|
| 1 | Κεντρικό report |
$Printout.2$
$Printout.3$ |
|||
| 2 | Sub report 1 | Επίσκεψη: $visittime$ | Select visittime from tblVisits where visitID=$ID$ | ||
| 3 | Sub report 2 |
Ημ/νια: $docekdosidate$ $Printout.4$ |
Select invmasterid, docekdosidate from tblInvMaster where visitid=$ID$ | ||
| 4 | Sub report 3 | Είδος: $stiname$ Ποσότητα: $stdqtya$ |
Select stiname, stdqtya from tblInvDetail where InvMasterID
[Δεν έχει υλοποιηθεί] |
Όπως φαίνεται παραπάνω υπάρχει ένα κεντρικό printout στον tblPrintouts το οποίο περιέχει ένα ή περισσότερα token στη μορφή $PRINTOUT.X$ όπου Χ είναι το id της εγγραφής του tblPrintouts στην οποία υπάρχουν οι πληροφορίες για την μορφή της εκτύπωσης η οποία θα αντικαταστήσει το token $PRINTOUT.X$. Τα ειδικά αυτά token μπορούν να υπάρχουν σε οποιοδήποτε από τα πεδία PrintoutHeader, PrintoutDetail, PrintoutFooter.
Έτσι λοιπόν αν βρεθεί ένα τέτοιο token γίνεται ένα ερώτημα στον tblPrintouts για να ανακτηθούν όλες οι απαραίτητες πληροφορίες της πρότυπης εκτύπωσης (PrintoutHeader, PrintoutDetail, PrintoutFooter κτλ) και γίνεται η αντικατάσταση των token που υπάρχουν σε αυτή. Αν κατά την αντικατάσταση των token βρεθεί εκ νέου κάποιο $PRINTOUT.X$ ακολουθείται η παραπάνω διαδικασία μέχρι ότου να ολοκληρωθεί η αντικατάσταση όλων των tokens.
Οι εκτυπώσεις μπορούν να γίνουν trigger μέσω scripting (Javascript event για εκτύπωση στο κλείσιμο της επίσκεψης), από τα παραστατικά του xvan, από τα reports με ActionType='Printout'. Για την εκτύπωση μέσω reports, η ActionParameter1 αντικαθιστά το $ID$ στα SQL Query του printout.
Ενέργεια printreport στα reports με παράμετρο το $ID$.
Το $ID$ ανάλογα με το από πού γίνεται trigger η εκτύπωση μπορεί να είναι το invmasterid, το ID που προκύπτει από το report κλπ
Και για αυτή τη μορφή των εκτυπώσεων ισχύουν όλοι οι περιορισμοί και οι διαδικασίες που έχουν αναφερθεί στο παρόν έγγραφο.
Υπολογιζόμενα tokens
Μπορούν να χρησιμοποιηθούν ειδικά tokens τα οποίο υποδηλώνουν μια αριθμητική παράσταση μεταξύ άλλων tokens. Κατά την δημιουργία του εγγράφου υπολογίζεται το αποτέλεσμα της παράστασης, χρησιμοποιώντας τις τιμές που επέστρεψαν από το ερώτημα για τα άλλα tokens του printout pattern μας, και αντικαθιστά το συγκεκριμένο token.
- Αρχικά επιλέγουμε τα tokens τα οποία θέλουμε να χρησιμοποιήσουμε στην αριθμητική μας παράσταση. Έστω #ΤΟΚΕΝ1# και $ΤΟΚΕΝ2$
Δημιουργούμε την αριθμητική παράσταση μεταξύ των tokens. Έστω #TOKEN1#+$TOKEN2$-125 (Σε αυτό το παράδειγμα τo 125 είναι ένας σταθερός αριθμός)
Περικλείουμε το αλφαριθμητικό που δημιουργήσαμε ανάμεσα σε δύο σύμβολα ±. Στο παράδειγμά μας ±#ΤΟΚΕΝ1#+$ΤΟΚΕΝ2$-125±. Το σύμβολο ± δηλώνει ότι είναι αριθμητική παράσταση μεταξύ tokens και θα πρέπει να υπολογιστεί το αποτέλεσμά της για να αντικατασταθεί.
Περικλείουμε το αλφαριθμητικό που δημιουργήσαμε ανάμεσα σε κάποιο από τα σύμβολα # ή $ ή ~. Έστω ότι στο παράδειγμα μας επιλέγουμε το # τότε το token μας θα γίνει #±#ΤΟΚΕΝ1#+$ΤΟΚΕΝ2$-125±#. Τα σύμβολα αυτά (# ή $ ή ~) υποδηλώνουν στο πρόγραμμά μας ότι είναι token και άρα θα πρέπει να αντικατασταθεί ενώ επίσης χρησιμεύουν στην στοίχιση
Παρατήρηση: Τα tokens που χρησιμοποιούνται στην αριθμητική παράσταση δεν είναι υποχρεωτικό να υπάρχουν στο printout pattern μας αλλά είναι υποχρεωτικό να υπάρχουν στο ερώτημά μας για να επιστρέφουν τιμή και να γίνει ο υπολογισμός. Δηλαδή στο παράδειγμά μας δεν χρειάζεται το #TOKEN1# να υπάρχει κάπου στο έγγραφο αλλά χρειάζεται να υπάρχει στο ερώτημα (π.χ. SELECT x AS TOKEN1...)
Σημεία Προσοχής:
- Τα tokens που χρησιμοποιούνται μέσα στην μαθηματική παράσταση πρέπει να ανήκουν στο ίδιο τμήμα του printout pattern. Δηλαδή όλα τα tokens της παράστασης πρέπει να είναι είτε tokens των details είτε tokens του header/footer.
- Μπορούν να χρησιμοποιηθούν και ειδικά tokens που υπολογίζονται αυτόματα από το πρόγραμμα (όπως τα TOTAL0, VATVAL23, TWV κτλπ) υπό την προϋπόθεση ότι έχουν υπολογιστεί τιμές για αυτά (Βλ. επόμενο bullet)
- Aν δεν υπάρχει τιμή για κάποιο token της αριθμητικής παράστασης είτε η τιμή αυτή δεν μπορεί να γίνει parse σε αριθμό τότε το token αριθμητική παράσταση αντικαθίσταται από ένα κενό string. Δηλαδή, δεν πετάει κάποιο exception
Πηγές / Βιβλιοθήκες: Χρησιμοποιήθηκε η exp4j - http://www.objecthunter.net/exp4j/ που υποστηρίζει:
Built-in operators
- Addition: '2 + 2'
- Subtraction: '2 - 2'
- Multiplication: '2 * 2'
- Division: '2 / 2'
- Exponentation: '2 ^ 2'
- Unary Minus,Plus (Sign Operators): '+2 - (-2)'
- Modulo: '2 % 2'
Built-in functions
- abs: absolute value
- acos: arc cosine
- asin: arc sine
- atan: arc tangent
- cbrt: cubic root
- ceil: nearest upper integer
- cos: cosine
- cosh: hyperbolic cosine
- exp: euler's number raised to the power (e^x)
- floor: nearest lower integer
- log: logarithmus naturalis (base e)
- sin: sine
- sinh: hyperbolic sine
- sqrt: square root
- tan: tangent
- tanh: hyperbolic tangent
Automated Printing (Αυτοματοποιημένη εκτύπωση)
Αντί να περιμένουμε από τον χρήστη να διαλέξει κάποια από τις επιλογές στο αρχικό menu (print, view, send email, send as attachment) μπορούμε να παρακάμψουμε αυτό το βήμα και να προκαθορίσουμε κάποια ενέργεια.
Αν δεν υπάρχει, πρέπει να προστεθεί το πεδίο PrintoutAction στον tblPrintouts.
Το πεδίο PrintoutAction παίρνει τις εξής τιμές:
1 : To printing ανοίγει στην οθόνη της εκτύπωσης
2 : Το printing ανοίγει στην οθόνη της προβολής
3 : Το printing ζητάει να επιλέξεις application για να στείλεις την εκτύπωση μέσω email
4 : Το printing ζητάει να επιλέξεις application για να στείλεις την εκτύπωση ως html αρχείο συνημμένο σε email
Οποιαδήποτε άλλη τιμή: ανοίγει το αρχικό μενού
Επίσης, εκτύπωση μπορούμε να εκτελέσουμε αυτόματα μετά από την αποθήκευση της παραγγελίας εάν στον SDT.allowPrint=1 και
με report, σε περίπτωση που έχουμε ορίσει 'printout' as ActionType και στο ActionData συμπληρώνουμε το ID του εκτυπωτικού από τον tblPrintOuts
π.χ.
select DISTINCT strftime('%d/%m/%Y',visittime) AS IMEROMINIA, 'printout' as ActionType, '7' as ActionData, date(visittime) as ActionParameter1, 'printingType' as ActionParameter2 from tblVisits order by visittime desc
Υποστήριξη Intermec Εκτυπωτών
Δίνεται η δυνατότητα να τυπώνουμε ελληνικούς χαρακτήρες σε intermec εκτυπωτές.
Για να μπορούμε να τυπώσουμε ελληνικά σε εκτυπωτές intermec πρέπει να ορίσουμε στον πίνακα configuration την παράμετρο printer_name με την τιμή Printer6820
Όταν υπάρχει στην εκτύπωση κάποιο token το οποίο δεν υποστηρίζουμε, τότε δεν θα βγάζει "!" αλλά θα μένει κενό. Θα πρέπει ο implementor να εξετάσει αν το token δεν υπάρχει ή απλώς το ανάλογο πεδίο από το οποίο διαβάζει έχει την τιμή null.
PrintoutHeaderSQL
SELECT m.INVMASTERID, SDT.SDTPrintDescr AS SDTDESCR, M.docnumber AS DOCNUMBER,DOS.dosPrintDescr AS DOS, strftime('%d/%m/%Y',M.dockatahorisidate) AS IMEROMINIA, strftime('%H:%M:%S', M.dockatahorisidate) as TIME, SLM.slmcode,SLM.slmname as slmname, LEE.leename, CUS.cuscode,CUS.Epaggelma,CUS.Balance , PRF.prfdescr AS PRF, ADR.adrdescription AS ADRDESCR, ADR.adrcity, ADR.adrphone1 AS PHONE, LEE.leeafm AS AFM,LEE.txoname as txoname, CPM.cpmtitle AS PAYMENT,M.tdoqtya AS SQA,M.tdoqtyb AS SQB, M.tdonetstock AS TOTNET, ROUND(M.tdosumvalue,2) AS TOTVALUE, M.tdovatstock AS VAT, M.tdogrossvalue as GROSS,ifnull(M.CollectionValue,'ΕΠΙ ΠΙΣΤΩΣΕΙ') as CollectionValue, Round(ifnull(CUS.Balance,0)+ifnull(M.CollectionValue,0)-ROUND(M.tdosumvalue,2),2) as PreBalance, round((M.tdogrossvalue - M.tdonetstock),2) as DISC,vehicles.plates FROM tblInvMaster M inner join SDT on SDT.sdtid=M.sdtid inner join CUS on CUS.cusid=M.cusid inner join ADR on ADR.adrid=CUS.adriddest inner join LEE on lee.leeid=CUS.leeid inner join SLM on SLM.slmid=M.slmid inner join vehicles on SLM.slmid=vehicles.slmid inner join DOS ON M.DOSID=DOS.DOSID left outer join PRF on lee.prfid=PRF.prfid LEFT OUTER JOIN CPM ON CPM.cpmid=CUS.cpmid where M.invmasterid=$ID$
- PrintoutHeader
ΚΡΙ-ΚΡΙ Α.Β.Ε.Ε.
ΒΙΟΜΗΧΑΝΙΑ
$SDTDESCR $$DOS $$DOCNUMBER$
ΗΜ/ΝΙΑ:$IMEROMINIA$ ΩΡΑ:$TIME $ΟΔΗΓΟΣ:$SLMNAME $ΌΧΗΜΑ :$PLATES $
ΚΩΔ. ΠΕΛ.: $CUSCODE $ΠΕΛΑΤΗΣ : $LEENAME $
ΕΙΔΟΣ ΕΠ.: $EPAGGELMA $ΠΟΛΗ : $ADRCITY $
ΚΩΔ. ΠΕΡΙΓΡΑΦΗ ΠΟΣ.A ΠΟΣ.Β. ΤΙΜΗ ΕΚΠΤ ΚΑΘΑΡΗ ΦΠΑ
SELECT cus.cusid, CUS.cuscode, LEE.leename, tblInvMaster.dockatahorisidate, as doccomment, tblInvMaster.invmasterid,
'printout' AS ActionType, '7' AS ActionData, tblInvMaster.invmasterid AS ActionParameter1,'Invoice' as ActionParameter2
FROM tblInvMaster INNER JOIN CUS ON CUS.cusid =tblInvMaster.cusid INNER JOIN LEE ON LEE.leeid = CUS.leeid
ORDER BY tblInvMaster.dockatahorisidate DESC
<AndroidLayout> <columns> <column position="2" caption="Customer" datamember="leename" width="220" alignment="C"/> <column position="1" caption="Customer Code" datamember="cuscode" width="100" alignment="C"/> <column position="3" caption="Date" datamember="dockatahorisidate" width="100" alignment="C"/> <column position="4" caption="InvMasterID" datamember="invmasterid" width="70" alignment="C"/><column position="5" caption="Comments" datamember="doccomment" width="300" alignment="C"/></columns> </AndroidLayout>
Η υποστήριξη της χρήσης PDF αρχείων, αφορά:
την δημιουργία και εκτύπωση PDF αρχείου
την δημιουργία και αποστολή email με επισυναπτόμενο το PDF αρχείο
Δημιουργία PDF αρχείου
Το PDF αρχείο δημιουργείται με τα ακόλουθα χαρακτηριστικά:
- Μέγεθος σελίδας = Α4
- Πλήθος γραμμών ανά σελίδα = 66
- Πλήθος χαρακτήρων ανά γραμμή = 80
- Γραμματοσειρά = Courier New (για να έχουμε τη δυνατότητα στοίχισης κειμένου σε στήλες)
- Υποστήριξη λογότυπου (βλέπε παράγραφο Tokens)
- Υποστήριξη υπογραφής (βλέπε παράγραφο Tokens)
Tokens
Τα tokens που μπορούν να χρησιμοποιηθούν στην δημιουργία του PDF, αφορούν την εμφάνιση εικόνων σε αυτό και είναι τα ακόλουθα:
#himg.scale<κλίμακα>.<όνομα πεδίου με δεδομένα εικόνας>#, για την εκτύπωση λογότυπου στην αρχή κάθε σελίδας
#fimg.scale<κλίμακα>.<όνομα πεδίου με δεδομένα εικόνας>#, για την εκτύπωση υπογραφής στο τέλος της τελευταίας σελίδας
όπου:
himg: δηλώνει τη χρήση της εικόνας σαν λογότυπο.
fimg: δηλώνει τη χρήση της εικόνας σαν υπογραφή.
Κλίμακα: το ποσοστό (%) κλιμάκωσης (σμίκρυνση ή μεγέθυνση) του μεγέθους της εικόνας. Λαμβάνει τιμές μεταξύ 1 και 100. Οποιαδήποτε άλλη τιμή θα έχει σαν αποτέλεσμα να χρησιμοποιηθεί η εικόνα με το πραγματικό της μέγεθος. Αν δεν οριστεί, η εικόνα θα χρησιμοποιηθεί με το πραγματικό της μέγεθος.
Όνομα πεδίου με δεδομένα εικόνας: τα δεδομένα της εικόνας λαμβάνονται με εκτέλεση του ερωτήματος που ορίζεται σαν τιμή στο πεδίο tblPrintouts.PrintoutHeaderSQL, οπότε αναφερόμαστε σε αυτά με το όνομα του πεδίου που χρησιμοποιείται σε αυτή την τιμή.
Π.χ. το ερώτημα "SELECT CustomLogoTable.Logo As logo, ...", επιστρέφει τα δεδομένα της εικόνας σαν τιμή του πεδίου logo. Αν θέλουμε να χρησιμοποιήσουμε την εικόνα αυτή σαν λογότυπο, τότε το token θα είναι #himg.scale<κλίμακα>.logo#. Στον πίνακα CustomTableLogo, το πεδίο “logo” πρέπει να είναι ορισμένο ως “string” και η αποθήκευση να γίνει σε Base64 frormat.
ΠΑΡΑΤΗΡΗΣΕΙΣ:
Το φορμάτ των εικόνων που μπορούν να εμφανιστούν ως logo και υπογραφή είναι αποκλειστικά Base64 string representation. Οποιοδήποτε άλλο format θα προκαλέσει exception με μήνυμα Index 0 out of bounds [0…0).
Τα παραπάνω tokens μπορούν να οριστούν μόνο στον header της εκτύπωσης, δηλαδή μόνο στο πεδίο tblPrintouts.PrintoutHeader. Αν και δεν έχει σημασία σε ποιο σημείο του header θα οριστούν, καλό είναι να ορίζονται στην αρχή του, έτσι ώστε να είναι εύκολα διακριτά με το μάτι.
Ο διαχωρισμός των σελίδων γίνεται με χρήση του control χαρακτήρα Form Feed (ASCII τιμή = 12). Αν δεν χρησιμοποιηθεί ο χαρακτήρας Form Feed, τότε η εικόνα του λογότυπου θα εμφανιστεί μόνο στην πρώτη σελίδα. Η παράμετρος PrintA4, του πίνακα Configuration, φροντίζει για την αυτόματη εισαγωγή του χαρακτήρα Form Feed στο προς εκτύπωση παραστατικό, οπότε μπορεί να χρησιμοποιηθεί στην περίπτωση που είναι επιθυμητή η χρήση πολλών σελίδων.
Παράμετροι για αποστολή PDF αρχείου
Για να δημιουργηθεί το Pdf σωστά με υπογραφή και logo και να σταλθεί σαν attachment πρέπει να βάλουμε στον configuration πίνακα την τιμή DBMaxMediaSize = 2000 όπου υποδηλώνει το μέγεθος της εικόνας της υπογραφής.
Εκτύπωση PDF αρχείου
Η εκτύπωση PDF αρχείων, γίνεται με χρήση των εξωτερικών εφαρμογών PrintHand και PrinterShare, θέτοντας την κατάλληλη τιμή στην παράμετρο PRINTER_NAME του πίνακα Configuration. Με την τελευταία υλοποίηση, η τιμή αυτή περιέχει το όνομα της εξωτερικής εφαρμογής εκτύπωσης, καθώς και ένα αλφαριθμητικό που ορίζει τον τύπο του αρχείου που θα δημιουργηθεί και θα αποσταλεί στον εκτυπωτή. Το αλφαριθμητικό αυτό μπορεί να λάβει μία εκ των τιμών html ή pdf και διαχωρίζεται, από το όνομα της εξωτερικής εφαρμογής, με χρήση του συμβόλου ":", π.χ. PrinterShare:PDF. Αν δεν οριστεί ο τύπος του παραγόμενου αρχείου, θα χρησιμοποιηθεί html αρχείο.
Το αρχείο που θα εκτυπωθεί, δημιουργείται με το όνομα printhand.pdf κάτω από τον φάκελο printHand της εφαρμογής PocketBiz.
ΠΑΡΑΤΗΡΗΣΗ:
Αν είναι tblPrintouts.PrintoutAction = 1, τότε γίνεται άμεσα η εκτύπωση του παραστατικού.
Αν είναι tblPrintouts.PrintoutAction <> [1 - 5], τότε εμφανίζεται μενού επιλογών.
Αποστολή email με επισυναπτόμενο PDF αρχείο
Η αποστολή PDF αρχείων με email, γίνεται όταν το πεδίο tblPrintouts.PrintoutAction έχει την τιμή 5 ή με την αντίστοιχη επιλογή που εμφανίζεται όταν tblPrintouts.PrintoutAction <> [1 - 5].
Το PDF αρχείο δημιουργείται, κάτω από τον φάκελο "Printing Attachments", με όνομα την τιμή του πεδίου tblPrintouts.PrintoutDescr. Αν το πεδίο αυτό δεν έχει τιμή, τότε το PDF αρχείο θα έχει όνομα attachment.pdf. Επίσης, αν η κατάληξη του αρχείου δεν είναι σωστή (PDF), τότε αυτή προσαρμόζεται αυτόματα.
Reports
Οι διαθέσιμοι τύποι Reports για το Pocketbiz Android είναι
- Grid Reports
- Charts
- Gauges Dashboard
Σχετικοί Πίνακες
| Πίνακας | Περιγραφή | Article Type | Sync Type |
|---|---|---|---|
| tblReports | Πίνακας αναφορών | DOWNLOAD | PUBLIC |
| tblReportCriteria | Πίνακας κριτηρίων αναφοράς | DOWNLOAD | PUBLIC |
Tα πεδία του tblReports που μας ενδιαφέρουν είναι τα εξής:
| Πεδίο | Περιγραφή |
|---|---|
| ReportID | Μοναδικό ID έγγραφής |
| Description | Περιγραφή όπως θα φαίνεται στην εφαρμογή |
| Entity | Την οντότητα που αφορά το Report. Αν είναι γενικό Report το αφήνουμε κενό. (όχι NULL) |
| Pos | Σειρά εμφάνισης στη λίστα των Reports στην εφαρμογή |
| SQLQuery | Το query που αφορά το Report μας |
| ReportOfflineBehavior | Εάν το Report εκτελείται τοπικά συμπληρώνουμε AVAILABLE. Σε άλλη περίπτωση NOTAVAILABLE |
| ReportOnlineBehavior | Εάν το Report εκτελείται στο server συμπληρώνουμε AVAILABLE. Σε άλλη περίπτωση NOTAVAILABLE |
| ReportCode | Ένας χαρακτηριστικός κωδικός για το Report. Συνήθως η περιγραφή του με λατινικούς χαρακτήρες |
| ReportType | Τύπος Report |
| ReportGridLayout | Το XML όπου θα παρουσιάσει τα data και τη μοφή του report |
| VisibleInMenu | Εάν θέλουμε το Report να είναι διαθέσιμο στα αντίστοιχα menu και στον CUS συμπληρώνουμε 1. Διαφορετικά, 0 |
Tα πεδία του tblReportCriteria που μας ενδιαφέρουν είναι τα εξής:
| Πεδίο | Περιγραφή |
|---|---|
| ReportCriteriaID | Μοναδικό ID έγγραφής |
| ReportCode | Ο κωδικός του Report που αφορά το κριτήριο. Προσοχή είναι case sensitive |
| EntityName | Αν το κριτήριο αφορά οντότητα συμπληρώνουμε αντίστοιχα |
| RCFieldName | Το πεδίο της σχετικής οντότητας |
| RCDefaultValue | Η Default τιμή του κριτηρίου |
| RCPos | Σειρά εμφάνισης |
| RCAllowMultiple | Για το Android βάζουμε 0 |
| RCAllowEmpty | Για το Android βάζουμε 0 |
| RCExternalTableName | Για το Android το αφήνουμε κενό ή Null |
| RCPrompt | Σχετικό μήνυμα |
| RCCrystalParameterName | Η παράμετρος όπως είναι στο script |
| RCEntityFilter | Αν το κριτήριο αφορά οντότητα μπορούμε να φιλτράρουμε την οντότητα |
| RCAffectedDatasets | Για το Android το αφήνουμε κενό ή Null |
| RCQueryFieldName | Για το Android το αφήνουμε κενό (όχι Null) |
| RCFieldType | Τύπος κριτηρίου |
Grid Reports
Τα Grid Reports εμφανίζουν την πληροφορία που επιθυμούμε σε μορφή λίστας και ο χρήστης έχει τη δυνατότητα να μετακινηθεί στη λίστα σειριακά, μετακινούμενο προς τα πάνω ή προς τα κάτω. Επίσης, υπάρχει η δυνατότητα πατώντας πάνω σε μια γραμμή να μετακινηθεί σε ένα άλλο report, λαμβάνοντας την πληροφορία που επιθυμεί δυναμικά, σε επίπεδο γραμμής. Η γραμμή που επιλέγεται για να μεταβούμε σε ένα άλλο report, θα λειτουργήσει σαν κριτήριο για το επόμενο
Οι αναφορές τύπου Grid, μπορούν να δημιουργηθούν:
- Στο μενού των αναφορών της κεντρικής οθόνης,
- Στο μενού αναφορών στην καρτέλα του πελάτη
- Στο header της παραγγελίας.
Παράδειγμα (Report Επισκέψεων – πεδία tblReports)
- Description - Επισκέψεις Αναλυτικά
- Entity – ‘’ (Θα εμφανιστεί στα γενικά Reports)
- Filename – ’’
- Pos – 1 (Θα εμφανιστεί πρώτο στη λίστα)
- ReportData- ’_’
- ReportCategoryID – ‘_’
- ReportOfflineBehavior – ‘AVAILABLE’ (Για να εκτελεστεί offline τοπικά)
- ReportOnlineBehavior – ‘NOTAVAILABLE’
- ReportCode – ‘Visits’
- ReportType – ‘GRID’
- VisibleInMenu – 1
Στο πεδίο Record Selection Formula γράφουμε το SQL ερώτημα που θα εκτελεστεί στη βάση και τα αποτελέσματα του ερωτήματος εμφανίζονται σε μία λίστα. Μπορούμε να παραμετροποιήσουμε τη λίστα και να αποθηκεύσουμε το layout ώστε να της δώσουμε τη μορφή που θέλουμε. Επίσης, μπορείτε να χρησιμοποιήσετε aliases στα πεδία του select ώστε να ονομάσετε τα πεδία όπως θέλετε π.χ.
SELECT cuscode as 'Κωδικός πελάτη', leename as 'Επωνυμία'
FROM CUS INNER JOIN LEE ON CUS.leeid=LEE.leeid
WHERE cusid NOT IN (select cusid from tblVisits where datediff(d,visittime,getdate())<=30)
(Εμφανίζει τους πελάτες που δεν έχουν επίσκεψη τις τελευταίες 30 ημέρες)
- SQLQuery
- select '<b><font color="#0a4879">' || ifnull(cusname,leename) || '</font></b>' as leename,cus.cusid, cuscode, ifnull(adrstreet,) as adrstreet, strftime('%d-%m-%Y',visittime) as mydate, strftime('%H:%M',StartTime) as start, strftime('%H:%M',EndTime) as endtime ,abs(((strftime('%H',EndTime)-strftime('%H',StartTime))* 60) + (strftime('%M',EndTime)-strftime('%M',StartTime))) as duration from tblvisits inner join cus on cus.cusid= tblvisits.cusid inner join lee on lee.leeid = cus.leeid inner join adr on adr.adrid = ifnull(cus.adriddest,cus.adridmain) inner join slm on tblvisits.slmid=slm.slmid where date(visittime)>=$from$ and date(visittime)<=$to$ order by slmname,visittime desc
- ReportGridLayout
- <AndroidLayout> <columns> <column position="1" caption="Ημ\νία" datamember="mydate" width="120" alignment="C"/><column position="2" caption="Κωδ. Πελάτη" datamember="cuscode" width="140" alignment="C"/><column position="3" caption="Πελάτης" datamember="leename" width="320" alignment="L"/><column position="4" caption="Ώρα έναρξης" datamember="start" width="115" alignment="C"/><column position="5" caption="Ώρα λήξης" datamember="endtime" width="115" alignment="C"/><column position="6" caption="Διάρκεια" datamember="duration" width="115" alignment="C"/></columns> </AndroidLayout>
Drill down reports
Έχοντας εμφανίσει τις πληροφορίες που επιθυμούμε στην αναφορά, μας δίνεται η δυνατότητα πατώντας σε μια εγγραφή να μεταφερθούμε σε μια άλλη αναφορά. Με αυτό τον τρόπο μπορούμε να αναλύσουμε την αρχική πληροφορία σε όσα επίπεδα επιθυμούμε.
Για την κλήση μιας αναφοράς μέσω της αρχικής μας αναφοράς, είναι απαραίτητο να προστεθούν οι παρακάτω παράμετροι στο αρχικό ερώτημά μας:
ActionType: Παίρνει σαν παράμετρο την λέξη ‘report’ για την κλήση της επόμενης αναφοράς.
ActionData: Παίρνει σαν παράμετρο το πεδίο reportcode της αναφοράς που επιθυμούμε να ανοίξει.
ActionParameter1, ActionParameter2, ActionParameter3, ActionParameter4, ActionParameter5: Αυτές οι παράμετροι αντικαθίστανται στο ερώτημα της αναφοράς που ανοίγει. Στην δεύτερη αναφορά που θα ανοίξει, θα πρέπει να υπάρχει το αντίστοιχο λεκτικό που θα περιέχει την τιμή της πρώτης αναφοράς.
Π.χ. Για το ActionParameter1, το sql για να αντικατασταθεί θα πρέπει να περιέχει εσωτερικά το εξής: $ActionParameter1$, το οποίο θα αντικατασταθεί με την αντίστοιχη εγγραφή που αναφέρθηκε προηγουμένως. Η χρήση της παραπάνω μεταβλητής είναι προαιρετική.
ΠΡΟΣΟΧΗ: Σε όλα τα παραπάνω τονίζεται ότι όλες οι ονομασίες είναι case sensitive και θα πρέπει να δηλωθούν όπως ακριβώς αναφέρονται.
Παράδειγμα:
Το παρακάτω Report καλεί το report DailySales με παράμετρο την ημερομηνία
select 2 as pos ,'<b><u>'||strftime('%d-%m-%Y',dockatahorisidate)||'</u><b>' as mydate ,strftime('%Y-%m-%d',dockatahorisidate) as fororder , ifnull(count(tblinvmaster.invmasterid),0) as myoforders , ifnull(round(sum(tdonetstock),2),0) as netvalue , ifnull(round(sum(tdosumvalue),2),0) as sumvalue , ifnull(round(sum(tdoqtya),2),0) as sumqtya ,ifnull(round(sum(tdoqtyb),2),0) as sumqtyb , strftime('%d-%m-%Y',dockatahorisidate) , ifnull(round(sum(tdogrossvalue),2),0) as tdogrossvalue , round(ifnull(round(sum(tdogrossvalue),2),0) - ifnull(round(sum(tdonetstock),2),0) ,2) as discount , ifnull(round(sum(tdovatstock),2),2) as vat , 'report' as ActionType , 'dailysales' as ActionData , date(dockatahorisidate) as ActionParameter1 from tblinvmaster where date(dockatahorisidate)>=$from$ and date(dockatahorisidate)<=$to$
Το report DailySales:
select '<b><u>'||docnumber||'</u><b>' as docnumber,leename, cuscode, docnumber, strftime('%H:%M',dockatahorisidate) as mytime ,round(tdosumvalue,2) as sumvalue,ifnull(round(tdoqtya,2),0) as tdoqtya, ifnull(round(tdoqtyb,2),0) as tdoqtyb, ifnull(round(tdonetstock,2),0) as netvalueround((round(tdosumvalue,2) - ifnull(round(tdonetstock,2),0) ),2) as vat ,tdogrossvalue as tdogrossvalue , round((tdogrossvalue - tdonetstock),2) as discount ,doccomment from tblinvmaster inner join cus on cus.cusid = tblinvmaster.cusid inner join lee on lee.leeid = cus.leeid inner join slm on tblinvmaster.slmid=slm.slmid where date(dockatahorisidate)= '$ActionParameter1$' dockatahorisidate desc
Κριτήρια report (πεδία πίνακα tblReportCriteria)
Για να εμφανιστεί η παρακάτω οθόνη κριτηρίων, πρέπει να παραμετροποιηθεί σχετική εγγραφή στον πίνακα tblReportCriteria.
- ReportCode – Visits (Προσοχή Case sensitive)
- EntityName –’’
- RCFieldName – ‘’
- RCDefaultValue – ‘$TODAY$’
- RCPOS – 1
- RCAllowEmpty – 0
- RCAllowMultiple – 0
- RCPrompt – ‘Από:’
- RCCrystalParameterName – ‘$from$’
- RCFieldType – ‘DATETIME’
RCPrompt: Ο τίτλος
RCAllowEmpty: Αν μπορεί να το αφήσει κενό
RCCrystalParameterName: Αυτό που θα γίνει replace στο SQLQuery (case sensitive)
RCFieldType: NVARCHAR, DATETIME, FLOAT, BOOLEAN
RCExternalTableName: Αν έχει συμπληρωθεί τότε κατά την αντικατάσταση βάζεις αυτό μπροστά
RCQueryFieldName: Αν έχει συμπληρωθεί τότε κατά την αντικατάσταση βάζεις αυτό μετά το RCExternalTableName
RCDefaultValue: Η default τιμή (literal, $NOW$, $TODAY$). Αν δεν έχει οριστεί τότε εμφανίζεται κενό.
RCEntityFilter: Αν διαβάζει από οντότητα τότε εδώ μπαίνει το where (χωρίς το where) που θα κολλήσει δίπλα στο query που θα διαβάσει τα δεδομένα προς επιλογή
Παράδειγμα:
Α. SQLQuery="select … where days>$days$"
RCExternalTableName=""
RCQueryFieldName=""
RCCrystalParameterName=$days$
RCAllowEmpty=0
RCFieldType=FLOAT
Αν ο χρήστης γράψει π.χ. 30 τότε select … where days>30
Β. SQLQuery="select … where days>$days$"
RCExternalTableName=""
RCQueryFieldName=""
RCCrystalParameterName=$days$"
RCAllowEmpty=1
RCFieldType=FLOAT
Αν ο χρήστης το αφήσει κενό τότε select … where days> ->ERROR
Γ. SQLQuery="select … where $days$"
RCExternalTableName="SLD"
RCQueryFieldName="days"
RCCrystalParameterName=$days$"
RCAllowEmpty=1
RCFieldType=FLOAT
Αν ο χρήστης γράψει π.χ. 30 τότε select … where SLD.days=30
Αν ο χρήστης το αφήσει κενό και δεν γράψει μέρες τότε: select … where 1=1
select year(visittime) as visityear, month(visittime) as vitimonth, count(visitid) as noofvisits
from tblvisits
inner join CUS ON CUS.cusid=tblvisits.cusid
inner join ADR on ADR.adrid=CUS.adriddest
where ADR.adrdistrict like N'%' and visittime>=$startdate$
group by year(visittime), month(visittime) order by 1,2
select year(visittime) as visityear, month(visittime) as vitimonth, count(visitid) as noofvisits
from tblvisits
inner join CUS ON CUS.cusid=tblvisits.cusid
inner join ADR on ADR.adrid=CUS.adriddest
where ADR.adrdistrict like N'ΜΑΡΟΥΣΙ%' and visittime>='2010-1-30'
group by year(visittime), month(visittime) order by 1,2
Αν έχει οριστεί EntityName και RCFieldName (δηλαδή αν EntityName<> και '-' και null) τότε εμφανίζεις combo box και κάνεις
select από τον tblEntities με EntityName=αυτό που έχει ορίσει και παίρνεις το EntitySource, από αυτόν τον πίνακα θα φέρεις τα στοιχεία να επιλέξει.
Μετά κάνεις ένα select από τον tblEntityMembers για να πάρεις το κύριο πεδίο.
Select top 1 EntityMemberFieldName from tblEntityMembers where EntityName='SLM' AND EntityMemberFieldIsMain=1 order by EntityMemberFieldDisplayOrder
Τελικά θα φτιάξεις ένα select σαν αυτό (στο select χρειάζεσαι το πεδίο που έχει οριστεί στο RCFieldName και το κύριο που πήρες από πάνω):
Select slmid, slmname from slm where {RCEntityFilter} order by slmname
Select {rcfieldname}, {main} from {EntitySource} where {RCEntityFilter} order by {main}
Και θα εμφανίσεις το combo (στο combo το slmname), αλλά θα αντικαταστήσεις με το slmid της γραμμής που θα επιλέξει.
Στο RCEntityFilter αντικαθιστώ κανονικά τα $SLMID$, $TODAY$, κτλ
BOOLEAN:
Όσο αφορά την περίπρτωση RCFieldType = BOOLEAN δεν υπάρχει περίπτωση μη συμπλήρωσης του. Στο panel με τα criteria θα εμφανίζεται ένα check box το οποίο θα είναι checked αν RCDefaultValue = true και not checked αν RCDefaultValue = false.
Για τα criteria τύπου BOOLEAN η τιμή που έχει οριστεί στο RCCrystalParameterName θα αντικαθίσταται με την τιμή ‘true’ αν το check box είναι checked ή ‘false’ αν not checked.
SCRIPT:
Υπάρχει και δυνατότητα να μπει η τιμή SCRIPT στο RCFieldType, αλλά δεν είναι κανονικό είδος criteria και λειτουργεί διαφορετικά από τα υπόλοιπα. Υπάρχει αναλυτική περιγραφή στην παράγραφο Multi seletct & scripting.
DROPDOWN:
Από την έκδοση 8.16 και πάνω υποστηρίζονται drop down filters. Η λειτουργικότητα μοιράζεται στους πίνακες tblReports και tblReportCriteria.
Πιο συγκεκριμένα, στον tblReports γράφεται όπως πάντα το query. Στο query αυτό μπορείτε (και επιβάλλεται αν θέλετε drop down φίλτρα) να αντικαταστήσετε την συνθήκη που θα προκύψει από το drop down φίλτρο με ένα δικό σας token περικλεισμένο με $, για παράδειγμα $MYCUSID$.
Στον tblReportCriteria η εγγραφή που θα αντιπροσωπεύει το drop down φίλτρο πρέπει να έχει τα παρακάτω.
- RCFieldType = SQL
- RCSql = το sql που φέρνει κατά τα γνωστά, 2άδες storevalue, displayvalue
- RCQueryFieldName = το πεδίο που αντιστοιχεί στο storevalue του παραπάνω query
- RCExternalTableName = το όνομα του πίνακα στον οποίο ανήκει το παραπάνω column
ΠΡΟΣΟΧΗ Η ΚΟΛΩΝΑ ΠΡΠΕΙ ΝΑ ΥΠΑΡΧΕΙ ΣΤΗ ΒΑΣΗ.
Παράδειγμα.
Έστω ότι θέλουμε όλα τα παραστατικά του πελάτη Χ. Το query στον tblReports είναι
Select * from tblInvMaster where $MYCUSID$
Στον tblReportCriteria ορίζουμε το φίλτρο με
- RCFieldType = SQL
- RCSql = select CUSID as storevalue, cusname as displayvalue from CUS order by cusname
- RCQueryFieldName = cusid
- RCExternalTableName = tblInvMaster
Στην ουσία λέμε στο μηχανισμό ότι θέλουμε να φιλτράρουμε το query του Report με το πεδίο tblInvMaster.CUSID = την τιμή που θα έρθει από το drop down.
Επιλέγοντας για παράδειγμα τον πελάτη ΧΧΧ με storevalue (=cusid για το παράδειγμά μας) 121, τότε το τελικό query του Report θα μετατραπεί από
Select * from tblInvMaster where $MYCUSID$
Σε αυτό
Select * from tblInvMaster where tblInvMaster.CUSID = 121
Παρατηρείστε ότι ΟΛΗ η συνθήκη μετά το where σχηματίστηκε από τις κολώνες του tblReportCriteria.
Report που εκτυπώνει τιμολόγια
/* Παρακάτω βρίσκεται το query ενός report που απεικονίζει τιμολόγια. Πατώντας όμως σε αυτό το report επιθυμούμε να εκτυπώνουμε το τιμολόγιο, δηλαδή θέλουμε να συνδέσουμε το id του παρόντος τιμολογίου με το id που θα λάβει ως παράμετρο στο 'WHERE' το query του πίνακα tblPrintouts.
Τα σχόλια που υπάρχουν μέσα στο query για τα: ActionParameter1 και ActionData υποδεικνύουν τα σημεία τα οποία πρέπει να προσέξει κάποιος για να γίνει η μεταβίβαση του ID. */
SELECT codcode AS CODCODE
,stiname AS STINAME
,UNI.unishortname AS UNIA
,tblInvDetail.stdqtya AS QTYA
,tblInvDetail.ssdunitprice AS PRICE
,ROUND(tblInvDetail.stdqtya * tblInvDetail.ssdunitprice, 2) AS TOAM
,tblInvDetail.ssdpricelistdisc AS DISCA
,tblInvDetail.ssdnetvalue AS NETV
,tblInvDetail.ssdvatpcnt AS VAT
,M.tdogrossvalue AS TOTNODISC
,ROUND(M.tdogrossvalue - M.tdonetstock, 2) AS TOTDISC
,M.tdonetstock AS TOTAL24
,M.tdovatstock AS VATVAL24
,M.tdosumvalue AS TOTWITHVAT
,'printout' AS ActionType
,(
CASE
WHEN SDT.sdtid = 306577551
THEN '13'
WHEN SDT.sdtid = 1924010988
THEN '13'
WHEN SDT.sdtid = 101953508
THEN '14'
WHEN SDT.sdtid = 1555028828
THEN '14'
END
) AS ActionData /*Το alias ActionData προσδιορίζει το Printout που θα πάει να εκτυπώσει η εφαρμογή. Εδώ επειδή πρόκειται για τιμολόγια με διαφορετικές μορφοποιήσεις χρησιμοποιούμε case για τα διαφορετικά printout ids που θέλουμε να εκτυπώνουμε*/
,'Invoice' AS ActionParameter2
,M.invmasterid AS ActionParameter1 /*Απαραίτητο στο ActionParameter1 να ορίσουμε το id που θέλουμε να περάσουμε στο where του printout που θέλουμε να εκτυπώσουμε. Δηλαδή το M.invmasterid AS ActionParameter1 θα περαστεί σαν $ID$ στο query του επιθυμητού printout. Αυτή η παράμετρος δεν επηρεάζει το where του παρόντος query*/
FROM tblInvDetail
INNER JOIN tblInvMaster M ON M.invmasterid = tblInvDetail.InvMasterID
INNER JOIN STI ON tblInvDetail.stiid = STI.stiid
INNER JOIN UNI ON STI.uniida = UNI.uniid
INNER JOIN SDT ON SDT.sdtid = M.sdtid
INNER JOIN CUS ON CUS.cusid = M.cusid
INNER JOIN ADR ON ADR.adrid = CUS.adriddest
INNER JOIN LEE ON lee.leeid = CUS.leeid
INNER JOIN ADR ADRLEE ON ADRLEE.adrid = LEE.adridmain
INNER JOIN SLM ON SLM.slmid = M.slmid
INNER JOIN vehicles ON SLM.slmid = vehicles.slmid
INNER JOIN DOS ON M.DOSID = DOS.DOSID
INNER JOIN SEN ON SEN.dosid = DOS.dosid
INNER JOIN TXO ON TXO.txoid = LEE.txocode
LEFT OUTER JOIN PRF ON lee.prfid = PRF.prfid
LEFT OUTER JOIN CPM ON CPM.cpmid = m.cpmid
WHERE M.invmasterid = $ActionParameter1$
Report που επεξεργάζεται ερωτηματολόγια
Η συγκεκριμένη λειτουργία επιτρέπει στον χρήστη να επεξεργάζεται ερωτηματολόγια που έχουν πραγματοποιηθεί σε συναντήσεις και δεν έχουν συγχρονιστεί.
Για να ενεργοποιηθεί η λειτουργία πρέπει να δημιουργηθεί ένα νέο Report στον πίνακα tblReports. Το report λειτουργεί offline συνεπώς το πεδίο ReportOffilineBehavior πρέπει να έχει τιμή AVAILABLE και αντίστοιχα το πεδίο ReportOnlineBehavior να έχει τιμή NOT AVAILABLE.
Έπειτα πρέπει να οριστεί σωστά το SQL Query στο αντίστοιχο πεδίο SQLQuery. Παρακάτω ακολουθεί ένα ενδεικτικό query:
select Survey_Title,
CreateDate,
CusName,
'survey' AS ActionData, 'form' AS ActionType,
Survey_ID as ActionParameter1,
SurveyData_ID as ActionParameter2,
visitid as ActionParameter3,
SLMTaskID as ActionParameter4,
tblSurveyDataHeader.cusid as ActionParameter5
from tblSurveyDataHeader
inner join tblSurveys on tblSurveys.SurveyID=tblSurveyDataHeader.Survey_ID
inner join CUS on tblSurveyDataHeader.cusid=cus.cusid
inner join tblSLMTasks on tblSurveyDataHeader.Survey_ID = tblSLMTasks.SurveyID
where tblSurveyDataHeader.slmid = (select PBUserData.slmid from PBUserData)
AND tblSurveyDataHeader.REPLID IS NULL.
Το σημαντικό στο παραπάνω query είναι πως τα πεδίο ActionData, ActionType, ActionParameter1, ActionParameter2, ActionParameter3, ActionParameter4 και ActionParameter5 πρέπει να οριστούν με ακριβώς αυτόν τον τρόπο. Δηλαδή, αναμένουμε πως σαν ActionParameter1 θα δούμε το Survey_ID που θα φέρουμε στο Report.
Επιπλέον, τα πεδία Survey_Title, CreateDate, CusName είναι πεδία τα οποία επιλέγουμε να χρησιμοποιήσουμε στο πεδίο ReportGridLayout του Report ως datamembers. Αυτά τα πεδία μπορούμε να τα αλλάξουμε ανάλογα με το τι στοιχεία θέλουμε να δείχνουμε στην εφαρμογή σε κάθε γραμμή του Report που αντιστοιχεί σε ένα Survey.
Τέλος, αν ένα Survey είναι υποχρεωτικό να υπάρχει σε μια συνάντηση τότε ο χρήστης μπορεί να το επεξεργαστεί αλλά δεν μπορεί να το διαγράψει. Το αν ένα Survey είναι υποχρεωτικό φαίνεται στον πίνακα tblSLMTasks όπου ένα SLMTask μπορεί να συνδεθεί με ένα SurveyID και παράλληλα στο πεδίο Mandatory να υπάρχει η τιμή 1.
Multiselect Drill down Report
Έχουμε ένα master και ένα detail report. Στο master report μπορούμε να επιλέξουμε μια ή περισσότερες γραμμές και, πατώντας το κουμπί στο action bar, ανοίγει το detail report, με περιεχόμενα που φιλτράρονται ανάλογα με τις επιλεγμένες εγγραφές του master. Για να επιλέξεις μια γραμμή στο master report, κάνεις κλικ πάνω σε αυτήν και χρωματίζεται με μπλε χρώμα, αν ξανακάνεις κλικ η εγγραφή αποεπιλέγεται.
Το master report πρέπει να έχει:
Στο πεδίο ReportType την τιμή «GRID_MULTI». Αυτό σημαίνει ότι θα εμφανίσει grid στο οποίο θα εφαρμόζεται πολλαπλή επιλογή.
Στο πεδίο SQLQuery, πρέπει το πεδίο ActionType στο select, πρέπει να έχει την τιμή «multi».
Στο πεδίο SQLQuery, πρέπει το πεδίο ActionParameter1 στο select, πρέπει να έχει την τιμή του primary key της εγγραφής που εμφανίζεται.
Το detail report πρέπει να έχει:
Στο πεδίο ReportType την τιμή «GRID».
Στο πεδίο ReportCode την τιμή που έχει το πεδίο ActionData στο sql του master report.
Στο πεδίο SQLQuery, πρέπει να φιλτραριστούν οι εγγραφές με την τιμή της παραμέτρου ActionParameter1. Την τιμή της παραμέτρου την παίρνει το report από το πεδίο ActionParameter1 για όλες τις επιλεγμένες εγγραφές στο master report. Π.χ. το sql θα έχει τη μορφή
«WHERE MUDocumentHeader.ID IN ($ActionParameter1$)»
Το οποίο μετά την αντικατάσταση θα έχει τη μορφή
«WHERE MUDocumentHeader.ID IN (123,251,357)»
Report Drill Down Invmaster/detail
Παράδειγμα drill down για tblinvmaster και detail. Αυτό που εμφανίζεται στον χρήστη είναι οι παραγγελίες μήνα και πατώντας στην ημέρα, ανοίγουν οι παραγγελίες ημέρας. Πατώντας σε μια συγκεκριμένη ανοίγει το detail της.
Παραγγελίες Μήνα - Σύνολα Ανά Ημέρα
select strftime('%d-%m-%Y',dockatahorisidate) as mydate, count(invmasterid) as myoforders, sum(tdosumvalue) as sumvalue, sum(tdoqtyb) as sumqtyb, 'report' as ActionType, 'dailysales' as ActionData, date(dockatahorisidate) as ActionParameter1 from tblinvmaster where date(tblInvMaster.docekdosidate) > date('now','-30 day') group by strftime('%d-%m-%Y',dockatahorisidate) union select '<b><font color="#FF7F24">' || 'Σύνολο' || '</font></b>' as mydate , '<b><font color="#FF7F24">' || count(invmasterid) || '</font></b>' as myoforders, '<b><font color="#FF7F24">' || sum(tdosumvalue) || '</font></b>' as sumvalue, '<b><font color="#FF7F24">' || sum(tdoqtyb) || '</font></b>' as sumqtyb, as ActionType, as ActionData, as ActionParameter1 from tblinvmaster where date(tblInvMaster.docekdosidate) > date('now','-30 day') order by strftime('%d-%m-%Y',dockatahorisidate) desc
<AndroidLayout> <columns> <column position="1" caption="Ημ/νία Κατ." datamember="mydate" width="100" alignment="C"/> <column position="2" caption="Σύνολο Παρ" datamember="myoforders" width="150" alignment="C"/><column position="3" caption="Σύνολο Αξίας" datamember="sumvalue" width="200" alignment="C"/><column position="4" caption="Σύνολο Ποσ." datamember="sumqtyb" width="200" alignment="C"/></columns> </AndroidLayout>
Παραγγελίες ανά Ημέρα (1ο drill down)
select docnumber, strftime('%H:%M:%S',dockatahorisidate) as mytime,tdosumvalue,tdoqtyb, 'report' as ActionType, 'cusinvoicesub' as ActionData, invmasterid as ActionParameter1 from tblinvmaster where date(dockatahorisidate)= '$ActionParameter1$' order by dockatahorisidate desc
Reportcode: dailysales
<AndroidLayout> <columns> <column position="1" caption="Αρ.Παραστ." datamember="docnumber" width="100" alignment="C"/> <column position="2" caption="Ώρα" datamember="mytime" width="100" alignment="C"/> <column position="3" caption="Συνολική Αξία" datamember="tdosumvalue" width="120" alignment="C"/> <column position="4" caption="Συνολική Ποσ." datamember="tdoqtyb" width="100" alignment="C"/> </columns> </AndroidLayout>
Παραγγελίες Ημέρας (detail drill down)
select stiname,stdqtyb,ssdnetvalue from tblinvdetail inner join sti on tblinvdetail.stiid = sti.stiid where invmasterid ='$ActionParameter1$'
Reportcode: Cusinvoicesub
<AndroidLayout> <columns> <column position="1" caption="Είδος" datamember="stiname" width="280" alignment="L"/> <column position="2" caption="Ποσότητα" datamember="stdqtyb" width="80" alignment="C"/> <column position="3" caption="Καθαρή Αξία" datamember="ssdnetvalue" width="100" alignment="C"/></columns> </AndroidLayout>
Report Task
Υπάρχει η δυνατότητα προσθήκης ενός visit task, το οποίο ανοίγει ένα report. Για να γίνει αυτό χρειάζονται τα παρακάτω:
- Προσθήκη εγγραφής στον tblSlmTasks με Action = Report
- Πρέπει στην παράμετρο sqlOffGetCustomerTasks να προστεθεί μια στήλη ActionParameter1 η οποία θα καθορίζει το id του report που θέλουμε να ανοίξει
(π.χ. select SLMTaskID,TaskDescription,Action,MerchScenarioID,MerchCategoryID, MerchCompanyID, SurveyID, Pos, ParentSLMTaskID, Mandatory, sdtid, Badge, '20' as ActionParameter1 FROM tblSLMTasks … )
Στο sql του report, γίνονται πλέον replace τα $REQUESTID$, $VISITID$, $CUSID$.
Multi-Select & scripting
Έχουμε προσθέσει την δυνατότητα πολλαπλής επιλογής γραμμών και χρήσης των επιλεγμένων γραμμών μέσα σε script του tblCodeUnits.
Για να μπει σε multi select mode αρκεί να πατήσει παρατεταμένα με το δάχτυλο του κάποια από τις γραμμές του report.
Το script φυσικά ορίζεται στον πίνακα tblCodeUnits και έχει συμπληρωθεί σχετικό documentation στο αρχείο που αφορά τα scripts.
Τις επιλογές για script που μπορεί να τρέξει ο χρήστης τι ορίζουμε στον πίνακα tblReportCriteria όπου:
- ReportCode το tblReports.ReportCode που αφορά
- Σαν RCFieldType βάζουμε SCRIPT
- RCCrystalParameterName την τιμή που θα περνιέται ως crystalParameter στο script (περισσότερα για αυτό στο documentation των scripts)
- RCPrompt τον τίτλο της ενέργειας που θα βλέπει ο χρήστης
Αφού προστεθεί κατάλληλη εγγραφή στον tblReportCriteria τότε στο report στο οποίο αντιστοιχεί θα εμφανίζεται επιπλέον επιλογή στο menu ένα «i»
Πατώντας το κουμπί αυτό ο χρήστης θα βλέπει μια (searchable) λίστα με όλες τις διαθέσιμες SCRIPT ενέργειες που έχουν οριστεί στον tblReportCriteria για το συγκεκριμένο report και μπορεί να επιλέξει ποια από αυτές θέλει να τρέξει.
Για να εκτελεστεί script αρκεί να επιλέξει μια από τις επιλογές.
Σημειώσεις:
- Η λειτουργικότητα αυτή είναι ανεξάρτητη από την λειτουργικότητα multiselect που περιγράφεται στο 2.6
- Το feature αυτό απαιτεί έκδοση Core >= 8.14.0.0
Υβριδικά report
Από την έκδοση 8.16 και εφεξής, υποστηρίζονται υβριδικά reports για την οντότητα INVMASTER. Η ιδιαιτερότητα αυτών των reports είναι ότι εκτελούν ένα query τοπικά και με το dataset που δημιουργείται, εκτελείται ένα query online. Η όλη διαδικασία από πλευράς interface με τον χρήστη είναι σαν αν εκτελεί ένα online report.
Αρχικά για να λογιστεί ένα report ως υβριδικό, θα πρέπει να ορίσετε στον πίνακα tblReports την τιμή «AVAILABLE» τόσο στη στήλη ReportOfflineBehavior όσο και στην ReportOnlineBehavior.
Επίσης θα πρέπει να δώσετε query και στο SQLQuery αλλά και στο SQLServerQuery. Η διαδικασία θα ξεκινήσει εκτελώντας το SQLQuery στην τοπική βάση. Αυτό το query θα πρέπει να επιστρέφει ΜΙΑ κολώνα από τον πίνακα στον οποίο εκτελείται και αυτό γιατί το αποτέλεσμα του query αυτού θα δημιουργήσει ένα comma separated αλφαριθμητικό, το οποίο θα αντιστοιχεί στο token $VALUES$ του SQLServerQuery.
Κατόπιν, το SQLServerQuery θα εκτελεστεί στον server και θα επιστρέψει αποτέλεσμα.
Παράδειγμα: Έστω ότι θέλουμε να ρωτήσουμε το στοκ για τα προϊόντα που υπάρχουν στο καλάθι.
SQLQuery:
“select stiid as ActionParameter from tblInvDetail where InvMasterid = $INVMASTERID$”
Με βάση το παραπάνω, ο κώδικας θα φτιάξει το εξής: 5001,5002,…,5010
SQLServerQuery: “select * from tblStock where stiid in ($VALUES$)”
Το token $VALUES$ θα αντικατασταθεί από το αλφαριθμητικό 5001,5002,…,5010 δίνοντας τελικά το «select * from tblStock where stiid in 5001,5002,…,5010)», το οποίο και θα εκτελεστεί Online.
Παρατηρήσεις:
- Το «as ActionParameter» είναι απαραίτητο στο SQLQuery για να δουλέψει η αντικατάσταση του token με τις σωστές τιμές
- Θα πρέπει να ορίσετε τόσο το ReportOfflineBehavior όσο και το ReportOnlineBehavior ως “AVAILABLE”
- Η σειρά εκτέλεσης είναι πάντα offlineonline χωρίς παραμετροποίηση.
- Τα διαθέσιμα tokens για τα query πέρα από το $VALUES$ είναι τα $SCID$, $INVMASTERID$, $REQUESTID$, $CUSID$, $VISITID$
- Τα υβριδικά reports εφαρμόζονται ΜΟΝΟ για τα reports που έχουν entity = INVMASTER στον πίνακα tblReports. Επίσης, προφανώς, για να έχει χρησιμότητα ένα τέτοιο report, θα πρέπει να υπάρχουν προϊόντα στο καλάθι.
- Η υλοποίηση είναι ουσιαστικά ένας container στο online query που περιλαμβάνει τις τιμές που προκύπτουν από το offline query. Η ορθότητα της αναπαράστασης των τιμών του $VALUES$ αλλά και των queries των ίδιων επαφίεται στους consultants.
Γενικά
- Αν θέλουμε ένα report να εμφανιστεί στην οθόνη των πελατών στο πεδίο Entity συμπληρώνουμε CUS. Υποστηρίζεται το token $CUSID$ (όπου αφορά το συγκεκριμένο πελάτη που έχουμε επιλέξει)
- Σε περίπτωση που το report θέλουμε να είναι διαθέσιμο στην παραγγελία συμπληρώνουμε στο πεδίο Entity->INVMASTER. Υποστηρίζεται το token $ID$ ή $INVMASTERID$ (όπου αντιστοιχεί στην τρέχουσα παραγγελία αν το AutoSaveDraft είναι ενεργοποιημένο)
- Υποστηρίζεται HTML format
- Στα κριτήρια υποστηρίζονται φίλτρα τύπου NVARCHAR, DATETIME, FLOAT, INT (?), LIST
- Αν έχει οριστεί EntityName και RCFieldName (δηλαδή αν EntityName<> και '-' και null ) τότε εμφανίζει combo box και κάνεις
- select από τον tblEntities με EntityName=αυτό που έχει ορίσει και παίρνεις το EntitySource, από αυτόν τον πίνακα θα φέρεις τα στοιχεία να επιλέξει.
- Μετά κάνει ένα select από τον tblEntityMembers για να πάρεις το κύριο πεδίο.
- Select top 1 EntityMemberFieldName from tblEntityMembers where EntityName='SLM' AND EntityMemberFieldIsMain=1 order by EntityMemberFieldDisplayOrder
- Online/Offline reports Αν δεν υπάρχει η στήλη SQLServerQuery (online) στον πίνακα tblReports ή είναι null τότε η εφαρμογή χρησιμοποιεί την στήλη SQLQuery (εκτελείται offline).
Σημεία προσοχής
- Στο XML προσέχουμε τα κελιά να έχουν συνεχόμενο και σωστό Position attribute.
- Τα πεδία Datamember είναι case sensitive
- Στα SQL queries να γίνεται χρήση της ifnull για να μην έχουμε null πεδία.
CHARTS
Έχουμε την δυνατότητα να ενσωματώσουμε γραφήματα για εντυπωσιακότερο αποτέλεσμα. Η παραμετροποίηση είναι παρόμοια με αυτή των GRID Reports.
Bar chart
Για την χρήση του Bar Chart, θα πρέπει στο SQL ερώτημα που θα δημιουργήσουμε, να περιέχονται τα εξής:
- Ένα πεδίο με alias series, το οποίο θα περιέχει τις σειρές που θα εμφανίζονται στο chart (από 1 έως 3).
- Ένα πεδίο με alias argument, το οποίο θα περιέχει τις τιμές του άξονα x, είτε αριθμητικές είτε σαν λεκτικό.
- Ένα πεδίο με alias value, το οποίο θα περιέχει τις τιμές του άξονα y, πάντα αριθμητικές
Για την εμφάνιση του Bar Chart, στην στήλη ReportType του πίνακα tblReports, πρέπει να εισάγουμε την τιμή CHART
Παράδειγμα:
- select 10 as series, valueCY as value,[Month] as argument,monthcode from DashboardSales union select 20 as series,ValueLY as value,[Month] as argument,monthcode from DashboardSales order by [MonthCode] desc
- <string> <AndroidLayout subtype="VBAR" title="" labelmode="serieslabels" showlegend="labels" initialvisible="7" > <axis name="x" title="Ημ\νία"/> <axis name="y" title="Επισκέψεις"/> </AndroidLayout> <HTML5Layout subtype="VBAR" initialvisible="5"> <axis name="x" title="Ημ\νία"/> <axis name="y" title="Επισκέψεις"/> </HTML5Layout> </string>
Παρατηρήσεις:
- Το πεδίο Subtype μπορεί να πάρει τις παρακάτω τιμές:
- HBAR (οριζόντιο bar chart)
- HSBAR (οριζόντιο bar chart, όπου όλες οι σειρές εμφανίζονται στην ίδια στήλη)
- VBAR (κάθετο bar chart)
- VSBAR (κάθετο bar chart, όπου όλες οι σειρές εμφανίζονται στην ίδια στήλη)
- Το πεδίο title προσδιορίζει τον τίτλο του chart. Αν δεν υπάρχει θα χρησιμοποιηθεί σαν τίτλος η περιγραφή της αναφοράς που υπάρχει στον πίνακα tblReports.
- Το πεδίο initialvisible προσδιορίζει πόσα bars θα υπάρχουν στην οθόνη του Chart.
- Το πεδίο title (x και y άξονας), προσδιορίζει το όνομα των αξόνων του Chart.
- Το πεδίο labelmode καθορίζει τι θα εμφανίζεται στον x άξονα και παίρνει τις τιμές:
- nolabels (default): Εμφανίζεται μόνο το λεκτικό.
- Serieslabels: Εμφανίζεται το λεκτικό και η τιμή
- Rangelabels: Εμφανίζεται το λεκτικό και το range
- Hybridlabels: Εμφανίζεται το λεκτικό και το range
Παρατήρηση: Όταν φτιάχνουμε Bar Chart CY/LY πρέπει να υπάρχουν τιμές για όλους τους μήνες και για τα δύο χρόνια για να εμφανιστεί σωστά.
Pie chart
Για την χρήση του Pie Chart, θα πρέπει στο SQL ερώτημα που θα δημιουργήσουμε, να περιέχονται τα εξής:
- Ένα πεδίο με alias argument, το οποίο θα περιέχει τις περιγραφές για κάθε στοιχείο που δίνει μια ξεχωριστή φέτα του chart.
- Ένα πεδίο με alias value, το οποίο θα περιέχει τις τιμές για κάθε στοιχείο που δίνει μια φέτα στο chart. Το σχετικό μέγεθος κάθε τιμής καθορίζει και το μέγεθος που θα έχει η φέτα αυτή στο chart.
Παράδειγμα:
- select as series,case strftime('%m', dockatahorisidate) when '01' then 'January' when '02' then 'Febuary' when '03' then 'March' when '04' then 'April' when '05' then 'May' when '06' then 'June' when '07' then 'July' when '08' then 'August' when '09' then 'September' when '10' then 'October' when '11' then 'November' when '12' then 'December' else end as argument,sum(tdosumvalue)as value from tblinvmaster where strftime('%Y',dockatahorisidate)=strftime('%Y','now') group by strftime('%m', dockatahorisidate) order by strftime('%m', dockatahorisidate)
- <string> <AndroidLayout subtype="PIE" title="" labelmode="nolabels" showlegend="NONE" > </AndroidLayout> <HTML5Layout subtype="PIE"> </HTML5Layout> </string>
Donut chart
Για την χρήση του Donut Chart, θα πρέπει στο SQL ερώτημα που θα δημιουργήσουμε, να περιέχονται τα εξής:
Ένα κενό πεδίο (‘’) με alias series, το οποίο θα περιέχει τα κομμάτια του donut.- Ένα πεδίο με alias argument, το οποίο θα περιέχει την περιγραφή του εκάστοτε επιλεγμένου κομματιού του donut (είτε αριθμητικές είτε σαν λεκτικό).
- Ένα πεδίο με alias value, το οποίο θα περιέχει τις τιμές βάση του οποίου θα χωριστεί το donut σε κομμάτια, πάντα αριθμητικές
Για την εμφάνιση του Donut Chart, στην στήλη ReportType του πίνακα tblReports, πρέπει να εισάγουμε την τιμή CHART
Παράδειγμα:
- select as series, d.stiid, stiname, d.stiid||' ('||stiname||')' as argument, ifnull(round(sum(stdqtya),2),0) as quant, ifnull(round(sum(ssdgrossvalue),2),0) as value, strftime('%d-%m-%Y', dockatahorisidate) as dateorder from tblinvmaster m
inner join tblinvdetail d on m.invmasterid=d.InvMasterID inner join sti s on s.stiid=d.stiid where cusid=$CUSID$ group by d.stiid order by sum(ssdgrossvalue) desc, sum(stdqtya) limit 10
- <string> <AndroidLayout subtype="DONUT" title="" labelmode="nolabels" showlegend="NONE" > </AndroidLayout> <HTML5Layout subtype="DONUT"> </HTML5Layout> </string>
Dashboard
Γενικά
Με το Dashboard μπορούμε να παρουσιάσουμε μια εντυπωσιακή αρχική οθόνη με διάφορα Metrics, KPIs και πληροφορίες που αφορούν τον πωλητή και την δουλειά του.
Το dashboard περιγράφεται στον πίνακα tblReports.
Χωρίζεται σε header και detail
Παραμετροποίηση dashboard
H παραμετροποίηση του Dashboard γίνεται στον Configuration με την παράμετρο dashboardXML (Το Pocketbiz έχει κάποιο defaulXML αν δεν βρει την παράμετρο)
Υπάρχει και η παράμετρος DashboardID με default τιμή '-1'. Για -1 παίρνει το dashboardXml που θα βρει στον Configuration. Αλλιώς παίρνει σαν όρισμα το reportId από τον tblReports που θα περιέχει το xml στο πεδίο 'ReportGridLayout'.
Υποχρεωτικά πρέπει το ReportType = 'DASHBOARD' .
Παράδειγμα DashBoardXML:
<Androidlayout>
<Header>
<Item type="Welcome" position="1" src=""/>
<Item type="Shortcuts" src="reportid:71" position="2"/>
</Header>
<Grid layoutmethod="autoarrange" showdrawer="false">
<Item position="1" type="CHARTS" widthSpan="4" heightSpan="2" src="reportid:72" target="reportid:78" title="Πωλήσεις CY vs LY" />
<Item position="2" type="Gaugespeedometer" widthSpan="2" heightSpan="2" src="reportid:73" target="" title="Στόχος Μήνα" />
<Item position="3" type="List" widthSpan="2" heightSpan="2" src="reportid:74" target="reportid:57" title="News Feed"/>
<Item position="4" type="Gaugebar" widthSpan="2" heightSpan="2" src="reportid:77" target="" title="Παραγ./Επισκ."/>
<Item position=“5" type="WEB" widthSpan="2" heightSpan="1" src="reportid:82" target="" title="Sync"/>
<Item position="6" type="SPACE" widthSpan="1" heightSpan="1" src="" target="" title=""/>
<Item position="7" type="Text" widthSpan="2" heightSpan="2" src="reportid:132" target="" title="Tasks"/>
<Item position="8" type="Shortcuts" widthSpan="2" heightSpan="2" src="reportid:130" target="reportid:107" title="Στόχος"/>
<Item position="9" type="YAMMER" widthSpan="4" heightSpan="4" title="Yammer" src="" target="" group="1113404" network="sieben.gr" />
</Grid>
</Androidlayout>
Optional Attribute: layoutmethod
values="fillscreen", "autoarrange" (default:autoarrange)
Αν χρειάζεται τα κουτάκια 6x4 να καλύπτουν ακριβώς όλη την οθόνη επιλέγουμε fillscreen (προσοχή θα τα κάνει μικρότερα για να χωρέσουν ακριβώς).
Optional Attribute: showdrawer
values="true", "false" (default: true)
Καθορίζει αν θα εμφανιστεί το drawer από τα δεξιά με την έναρξη του dashboard ή όχι.
Σχεδιασμός Layout
Η λογική είναι έχουμε στην οθόνη ένα grid με κουτάκια συνολικού χώρου 6x4 (landscape) και το γεμίζεις με τα κουτάκια που θες τα οποία μπορεί να είναι 1x1 (το μικρότερο), 2x2, 3x4, 5x2 κλπ. (παράμετρος widthspan, heightspan) και το πρόγραμμα αναλαμβάνει να τα βάλει στη σωστή θέση, ανάλογα με τη σειρά που έρθουν (παράμετρος position) όπου βρει τον πρώτο διαθέσιμο ελεύθερο χώρο. Για να «σπρώξεις» κάποιο κουτί σε μια πιο όμορφη θέση μπορείς να βάλεις κάποιο κουτί τύπου SPACE (στο μέγεθος που θες) που είναι «νεκρό» σημείο, ώστε να πετύχεις την επιθυμητή εμφάνιση (TETRIS game)
Υποστηρίζονται οι εξής τύποι από κουτάκια:
- WebView (Βλέπε Dashboard Web View Fragment )
- Gaugespeedometer - Gaugebar (Επιταχυντής) (Βλέπε Gauges)
- ΤΕΧΤ (υποστηρίζει HTML στο src reportid)
- SPACE (κενό κουτί)
- LIST (υποστηρίζει HTML στο src reportid με select, υποχρεωτικές στήλες στο query =header, details-2 lines)) (παραδείγματα λιστών: Εισπράξεις, Customers List, Visits List)
- CHARTS (για πιο όμορφα αποτελέσματα βγάλτε τον τίτλο από το chart) src=reportid
- IMAGE
- WELCOME (μήνυμα)
- SHORTCUTS
- Yammer (επιτρέπει την σύνδεση στο Yammer και την ανάκτηση feeds)
Στο src βάζουμε το reportid που θα δείχνει, στο target αυτό που θα γίνεται με κλικ στον τίτλο (αυτή τη στιγμή υποστηρίζει να δείχνει άλλα reportid). Πάντα γράφουμε reportid:'reportid' που περιέχει την κατάλληλη μορφοποίηση για τον τύπο που βάλαμε.
Για τίτλο κενό, εξαφανίζεται ο τίτλος και αντίστοιχα δεν μπορείς να κάνεις κλικ για target.
Στo Header, αν δεν βάλουμε παιδιά εξαφανίζεται εντελώς.
Target actions in grid
Στο grid υποστηρίζονται πια οι εξής δυνατότητες:
- target="reportid:''reportid"
Χρησιμοποιείται για να ορίζετε ποιο report θέλετε να ανοίξει όταν πατάτε τον τίτλο, βάζοντας το reportid του.
- target="action:sync"
Χρησιμοποιείται για να μπορείτε να ανοίξετε κάποια βασική οθόνη του PB, πατώντας το τίτλο. Έχετε τις παρακάτω επιλογές:
Customer list με action customers
Reports με action reports
Xvan με action xvan
Messages με action messages
Οθόνη συγχρονισμού με action sync
Agenda με action agenda
Start Day με action start_day
Customer Details με action customerdetails,cusid:id (π.χ. action:customerdetails, cusid:999)
Available Shortcuts:
START_DAY, CUSTOMERS, REPORTS, XVAN, MESSAGES, SYNC,END_DAY,TNT_MASSPICKUP,
TNT_DELIVERIES, TNT_RECEIPT, AGENDA, DASHBOARD, CUSTOMERDETAILS, LOGOUT,
INTENT, DOCUMENTS_LIST_SALES
- target="intent:actionintent" πχ. intent:com.shazam.android.intent.actions.START_TAGGING
(θα ανοίξει την εφαρμογή του shazam για να ακούσει απευθείας το τραγούδι)
Χρησιμοποιείται για να ανοίξετε όποιο πρόγραμμα θέλετε πατώντας τον τίτλο εφόσον μπορείτε να προμηθεύσετε το κατάλληλο text. Βασίζεται στην λογική του αντίστοιχου visit action task. Προσοχή στο case και στις τελείες.
Π.χ. για να ανοίξει ερωτηματολόγιο:
<Item type="INTENT" icon="faw_calculator" extras="android.intent.action.MAIN,setComponent:gr.sieben.surveys:gr.sieben.surveys.SurveysIntroActivity,visitid:1,slmid:70007014,cusid:1,taskDescription:test,scid:1,surveyid:1"/>
Προστέθηκε η δυνατότητα αποστολής και intent extras (strings) πχ
intent:android.intent.action.SEND,setType:text/html,android.intent.extra.EMAIL:info@sieben.gr,android.intent.extra.SUBJECT:Important info
Προστέθηκε η δυνατότητα αποστολής και intent component
Intent: ….,setComponent:{packageName}:{className},…
---***---***--- ΣΤΟ Intent ΧΩΡΙΣ ΑΓΚΥΛΕΣ!!! "{" και "}" ---***---***---
Gauges
Τα dashboards υποστηρίζουν εκτός από τα κλασσικά reports και Gauges. Όλα τα gauges είναι animated οπότε μπορεί να επιτευχθεί ένα πολύ ωραίο αποτέλεσμα.
Gauge bar (μπαταρία)
Ο χρήστης έχει την δυνατότητα να ενσωματώσει ένα gauge μπαταρίας όπως φαίνεται στο παρακάτω screenshot
Η βασική λειτουργία της μπαταρίας είναι ουσιαστικά μπάρες οι οποίες συμπληρώνονται ανάλογα με μία τιμή.
Υπάρχουν 3 ειδών states για την μπαταρία (κόκκινο - κίτρινο - πράσινο)
Παραμετροποίηση
Χρειάζεται να ενσωματώσετε μία νέα εγγραφή στο tblReports καθώς και ένα επιπλέον <Item> στο xml του dashboard.
Συγκεκριμένα για το dashboard η μορφή εν τέλει θα είναι κάπως έτσι:
<Androidlayout>
<Header>
...
</Header>
<Grid>
...
<Item position="2" type="Gaugebar" widthSpan="1" heightSpan="1" src="reportid:26" target="" title=""/>
...
</Grid>
</AndroidLayout>
Το reportid:26 αντιπροσωπεύει την εγγραφή στον tblReports που θα πάει το πρόγραμμα να κοιτάξει.
Συγκεκριμένα, το πρόγραμμα χρησιμοποιεί τα πεδία SQLQuery, ReportType, ReportGridLayout.
- Στο πεδίο SQLQuery υπάρχει ένα select το οποίο επιστρέφει πίσω μία τιμή με όνομα value που θα είναι τύπου float με range τιμών [0,1]. Υποχρεωτικό
- Στο πεδίο ReportType πρέπει να είναι συμπληρωμένο με το λεκτικό “GAUGEBAR”. Υποχρεωτικό
- Στο πεδίο ReportGridLayout μπορείτε να γράψετε ένα xml στο οποίο να μπορείτε να παραμετροποιήσετε την εμφάνιση του gauge. Προαιρετικό
Παραμετροποίηση SQL
Παράδειγμα: «select 0.9 as value».
Το πρόγραμμα θα υπολογίσει αυτόματα πόσες μπάρες πρέπει να δείξει στρογγυλοποιώντας στον πιο κοντινό ακέραιο.
Παραμετροποίηση XML
Ένα παράδειγμα xml μπορεί να είναι το παρακάτω:
<AndroidLayout>
<gauge height="600" width="100" sumblocks="20" redblocks="5" greenblocks="5" />
</AndroidLayout>
- Height: εάν για εμφανισιακούς λόγους δεν θέλετε να πιάσει όλο το μέγεθος του κουτιού στο dashboard τότε μπορείτε να του ορίσετε συγκεκριμένο ύψος. (default: ανάλογα με το ύψος του κουτιού στο dashboard) Προαιρετικό
- Width: παρομοίως με το height αλλά για το πλάτος (default: ανάλογα με το πλάτος του κουτιού στο dashboard) Προαιρετικό
- Sumblocks: Το συνολικό πλήθος για τις μπάρες (default:10) Προαιρετικό
- Redblocks: Το πλήθος για τις κόκκινες μπάρες (default:3) Προαιρετικό
- Greenblocks: Το πλήθος για τις πράσινες μπάρες (default:3) Προαιρετικό
- NOTES: Μην τοποθετήσετε πολλές μπάρες σε πολύ μικρό ύψος καθώς είναι πιθανό να μην εμφανιστούν. Οι κίτρινες μπάρες υπολογίζονται αυτόματα με βάση το συνολικό πλήθος και με βάση το πλήθος των πράσινων/κόκκινων. Εάν ορίσετε συνολικό πλήθος είναι υποχρεωτικό να ορίσετε και το πλήθος για τις επιμέρους μπάρες.
Gauge lights
Ο χρήστης έχει την δυνατότητα να ενσωματώσει ένα gauge φαναριών όπως φαίνεται στο screenshot
Παραμετροποίηση
Χρειάζεται να ενσωματώσετε μία νέα εγγραφή στο tblReports καθώς και ένα επιπλέον <Item> στο xml του dashboard.
Συγκεκριμένα για το dashboard η μορφή εν τέλει θα είναι κάπως έτσι:
<Androidlayout>
<Header>
...
</Header>
<Grid>
...
<Item position="2" type="Gaugelights" widthSpan="2" heightSpan="3" src="reportid:26" target="" title=""/>
...
</Grid>
</AndroidLayout>
Το reportid:26 αντιπροσωπεύει την εγγραφή στον tblReports που θα πάει το πρόγραμμα να κοιτάξει.
Συγκεκριμένα το πρόγραμμα χρησιμοποιεί τα πεδία SQLQuery, ReportType, ReportGridLayout.
- Στο πεδίο SQLQuery υπάρχει ένα select το οποίο επιστρέφει πίσω μία τιμή με όνομα value που θα είναι τύπου int με range τιμών 0,1,2. Υποχρεωτικό
- Στο πεδίο ReportType πρέπει να είναι συμπληρωμένο με το λεκτικό “GAUGELIGHTS”. Υποχρεωτικό
- Στο πεδίο ReportGridLayout μπορείτε να γράψετε ένα xml στο οποίο να μπορείτε να παραμετροποιήσετε την εμφάνιση του gauge. Προαιρετικό
Παραμετροποίηση SQL
Παράδειγμα: «select 1 as value» Όπου 0=κόκκινο, 1=κίτρινο, 2=πράσινο
Παραμετροποίηση XML
Ένα παράδειγμα xml μπορεί να είναι το παρακάτω:
<AndroidLayout>
<gauge dimension="80" form="1" />
</AndroidLayout>
- Dimension: εάν για εμφανισιακούς λόγους δεν θέλετε να πιάσει όλο το μέγεθος του κουτιού στο dashboard τότε μπορείτε να του ορίσετε συγκεκριμένες διαστάσεις. (default: ανάλογα με το ύψος του κουτιού στο dashboard) Προαιρετικό
- Form: 0 = το full form, όπου φαίνονται όλα τα φανάρια είναι ανοιχτό το επιλεγμένο και είναι γκρι τα υπόλοιπα. 1 = το compact form, όπου φαίνεται μόνο το φανάρι που είναι επιλεγμένο. Προαιρετικό
Gauge Speedometer
Ο χρήστης έχει την δυνατότητα να ενσωματώσει ένα gauge Speedometer όπως φαίνεται στο παρακάτω screenshot
Παραμετροποίηση
Χρειάζεται να ενσωματώσετε μία νέα εγγραφή στο tblReports καθώς και ένα επιπλέον <Item> στο xml του dashboard.
Συγκεκριμένα για το dashboard η μορφή εν τέλει θα είναι κάπως έτσι:
<Androidlayout>
<Header> ... </Header>
<Grid> ...
<Item position="2" type="Gaugespeedometer" widthSpan="3" heightSpan="2" src="reportid:26" target="" title=""/>
... </Grid>
</AndroidLayout>
Το reportid:26 αντιπροσωπεύει την εγγραφή στον tblReports που θα πάει το πρόγραμμα να κοιτάξει.
Το πρόγραμμα χρησιμοποιεί τα πεδία SQLQuery, ReportType, ReportGridLayout.
- Στο πεδίο SQLQuery υπάρχει ένα select το οποίο επιστρέφει πίσω μία τιμή με όνομα value που θα είναι τύπου int . Υποχρεωτικό
- Στο πεδίο ReportType πρέπει να είναι συμπληρωμένο με το λεκτικό “GAUGESPEEDOMETER”. Υποχρεωτικό
- Στο πεδίο ReportGridLayout μπορείτε να γράψετε ένα xml στο οποίο να μπορείτε να παραμετροποιήσετε την εμφάνιση του gauge. Προαιρετικό
Παραμετροποίηση SQL
Παράδειγμα: «select 40 as value». Όπου αυτή θα είναι η τιμή που θα δείχνει η βελόνα. Πρέπει να είναι μέσα στο διαθέσιμο range.
Παραμετροποίηση XML
Ένα παράδειγμα xml μπορεί να είναι το παρακάτω:
<AndroidLayout><gauge height=”80” width=”200” greenColorRange="40" redColorRange="20" maxRange="200" minRange="100" labelStep="20" />
</AndroidLayout>
- Height: εάν για εμφανισιακούς λόγους δεν θέλετε να πιάσει όλο το μέγεθος του κουτιού στο dashboard τότε μπορείτε να του ορίσετε συγκεκριμένες διαστάσεις. (default: ανάλογα με το ύψος του κουτιού στο dashboard) Προαιρετικό
- Width: παρομοίως με το height αλλά για το πλάτος (default: ανάλογα με το πλάτος του κουτιού στο dashboard) Προαιρετικό
- MaxRange: το maximum range που θα φαίνεται πάνω στο gauge.(default:100) Προαιρετικό
- MinRange: το minimum range που θα φαίνεται πάνω στο gauge.(default=0) Προαιρετικό
- GreenColorRange: το range που θα φαίνεται το πράσινο χρώμα.(default=30) Προαιρετικό
- RedColorRange: το range που θα φαίνεται το κόκκινο χρώμα.(default=30) Προαιρετικό
- LabelStep: κάθε πόσες τιμές θα εμφανίζεται η ένδειξη πάνω στο gauge (π.χ. ανά 10 από 0 άρα 0-10-20-30-40 κτλ) (default=10) Προαιρετικό
NOTES: To range για το κίτρινο υπολογίζεται αναλογικά με τα maxRange, minRange, RedColorRange και GreenColorRange. Προτείνεται το labelStep να είναι ακέραιο πολλαπλάσιο της συνολικής απόστασης.
Mπορούμε να βάλουμε width και height = "-1" και θα παίρνουν όσο χώρο μπορούν αυτόματα.
List Type
Στο tblReports πρέπει να είναι συμπληρωμένα τα παρακάτω πεδία:
- SQLQuery = εδώ μπαίνει το select query σας
- ReportType = 'LIST' (υποχρεωτικό)
Αυτή τη στιγμή υποστηρίζει header/detail σε κάθε γραμμή
Οπότε ένα query πρέπει να έχει την εξής μορφή:
select ifnull(msgtitle,) as header, ifnull(msgtext,) as details from tblmessages where messagetype='Ενημέρωση ενέργειας'
Υποχρεωτικά πρέπει να υπάρχουν στήλες header, details, αλλιώς θα σκάσει.
Text Type
Στο tblReports πρέπει να είναι συμπληρωμένα τα παρακάτω πεδία:
- ReportGridLayout = εδώ μπαίνει το κείμενο
- ReportType = 'ΤΕΧΤ' (υποχρεωτικό)
Για src="reportId:-1" στο dashboardsxml δείχνει τo default κείμενο ("welcome to PB")
Shortcuts
Στο tblReports πρέπει να είναι συμπληρωμένα τα παρακάτω πεδία:
- ReportGridLayout = εδώ μπαίνει το xml όπως παρακάτω
- ReportType = 'SHORTCUTS' (υποχρεωτικό)
Για src="reportId:-1" στο dashboardsxml δείχνει τα default shortcuts
Δηλ. για παράδειγμα για shortcuts
(στο Header)
<Item type="Shortcuts" src="reportid:-1" position="2"/>
(στο Grid)
<Item position="1" type=" Shortcuts" widthSpan="4" heightSpan="2" src="reportid:30" target="reportid:30" title="Shortcuts"/>
Εδώ δουλεύει κανονικά το target. Δηλαδή με κλικ στον τίτλο, οδηγεί σε ένα report που έχει δηλωθεί. Χωρίς τίτλο ή target, απενεργοποιείται.
Available Shortcuts:
START_DAY, CUSTOMERS, REPORTS, XVAN, MESSAGES, SYNC, END_DAY, TNT_MASSPICKUP, TNT_DELIVERIES, TNT_RECEIPT, AGENDA, DASHBOARD, CUSTOMERDETAILS, LOGOUT, INTENT, DOCUMENTS_LIST_SALES
Για reportid:-1, ενεργοποιείται το default xml των shortcuts όπως παρακάτω.
<Androidlayout>
<ShortcutsGrid scrollAxis="Horizontal" inverted="true"> <!— scrollAxis optional attribute : Horizontal or Vertical --> <!— inverted optional attribute : true or false-->
<Item type="CUSTOMERS"/>
<Item type="REPORTS"/>
<Item type="XVAN"/>
<Item type="MESSAGES"/>
<Item type="SYNC"/>
<Item type="AGENDA"/>
</ShortcutsGrid>
</Androidlayout>
Επιλογή icon
Προστέθηκε η δυνατότητα επιλογής icon, με το optional attribute icon, π.χ. icon="faw_android"
Διαθέσιμα icons είναι της fontawesome (faw_*) που μπορείτε να δείτε εδώ:
https://play.google.com/store/apps/details?id=com.mikepenz.iconics.sample
Παράδειγμα:
<Androidlayout>
<ShortcutsGrid scrollAxis="Horizontal" inverted="true">
<Item type="CUSTOMERS" icon="faw_optin_monster"/>
<Item type="REPORTS"/>
<Item type="XVAN"/>
<Item type="MESSAGES"/>
<Item type="SYNC" icon="faw_exchange"/>
<Item type="CUSTOMERDETAILS" extras="cusid:1" icon="faw_android"/>
</ShortcutsGrid>
</Androidlayout>
Στο xml βάζουμε όσα shortcuts από τα παραπάνω και με όποια σειρά θέλουμε.
Προαιρετική παράμετρος είναι η scrollAxis με τιμές Horizontal / Vertical που καθορίζει το πώς θα scrollαρει το περιεχόμενο αν είναι μεγαλύτερο (επίσης αλλάζει και την τοποθέτηση πχ. Οριζόντια είναι μόνο μια σειρά εικονιδίων). (default: horizontal). Για shortcuts στο grid, καλύτερα να βάζετε vertical.
Προαιρετική παράμετρος είναι η inverted με τιμές true / false που καθορίζει τη σειρά τοποθέτησης των εικονιδίων και το scrolling (από τα δεξιά προς τα αριστερά για inverted και το αντίθετο). (default: true). Για shortcuts στο grid καλύτερα να βάζετε false ενώ στο header true.
Αντίστοιχα για τα δικά μας shortcuts πρέπει να φτιάξουμε μια εγγραφή στον tblReports με ReportType = ‘DASHBOARD’ και ReportGridLayout = ‘το δικό μας xml όπως παραπάνω’. Τα υπόλοιπα πεδία όπως γνωρίζουμε. To reportId αυτό το βάζουμε στο dashboardXml σαν src.
Customer Dashboard
Το Customer Dashboard είναι ακριβώς ίδιο με το Dashboard, ένας κλώνος με τις ίδιες ακριβώς λειτουργίες και τα ίδια ακριβώς reports.
Αντίστοιχα με το Dashboard του πωλητή, το Customer Dashboard θα προσπαθήσει να διαβάσει το XML script τύπου dashboard από τα εξής σημεία/καταχωρήσεις, που δίνονται εδώ με την σειρά που ισχύει και η προτεραιότητά τους:
Από την CUSTOMERLISTXML θα προσπαθήσει να δει αν υπάρχει εκεί κάποια καταχώρηση datamember με το όνομα dashboardId. Αφού διαβάσει την τιμή της (ουσιαστικά πρόκειται για το id number του πίνακα tblReports. ReportID), θα ψάξει κατευθείαν στον πίνακα tblReports για να βρει την αντίστοιχη καταχώρηση η οποία θα πρέπει να περιέχει το XML με το script του dashboard καθώς και την κολώνα ReportType = DASHBOARD και θα την φορτώσει.
Από την καταχώρηση customerDashboardXML, θα φορτώσει κατευθείαν το xml για το dashboard.
Αν δεν υπάρχουν καθόλου dashboard scripts, αλλά παρ'όλα αυτά υπάρχει datamember dashboardid, θα φορτωθεί από την εφαρμογή ένα default κενό dashboard.
Όταν υπάρχει λοιπόν μια από τις πιο πάνω περιπτώσεις, τότε στην οθόνη με τα Customer Details, στα ήδη υπάρχοντα tabs θα προστεθεί ακόμα ένα, το "MORE", το οποίο όταν επιλεγεί θα εμφανίσει το fragment του CustomerDashboard.
Όσον αφορά τα reports, είναι "κοινός" ο τρόπος λειτουργίας τους και λειτουργούν ακριβώς όπως και στο dashboard, με την μόνη διαφορά ότι πλέον λαμβάνεται υπ'όψιν στα queries που τρέχουν το token $CUSID$, το οποίο όποτε βρεθεί να υπάρχει στο κείμενο ενός query, θα αντικατασταθεί αυτόματα με το CustomerDetailsId, που μας έρχεται κατευθείαν από την επιλογή του χρήστη στην λίστα πελατών CustomerList. ΠΡΟΣΟΧΗ: Για να δούμε τις αλλαγές στο customer dashboard πρέπει να βγούμε από την εφαρμογή (δεν αρκεί ο συγχρονισμός).
Dashboard Web View Fragment
Προσθέτετε στο dashboardXml μια εγγραφή με ReportType 'web' με source to reportid που περιέχει την μορφοποίηση που θέλετε.
π.χ.
<Item position="1" type="web" widthSpan="4" heightSpan="4" src="reportid:31" target="" title=""/>
Υποχρεωτικό: Στον tblReports, το ReportType πρέπει να είναι WEB
Στο πεδίο ReportGridLayout βάζετε ένα xml της ακόλουθης μορφής:
<DashboardWebFragment>
<Options enableJS="true" enableBrowser="true" useFilters = "true" enableZoom="true"/>
<Filter equals="pb.gr" starts="pb.gr" ends="pb.gr"/>
<Data url = "www.pb.gr"
raw = "html 5 content here ... $token1$, $token2$ ]]"
tokensQuery="select data as token1 , data as token2"/>
</DashboardWebFragment>
Options Tag Προαιρετικό
enableJS : enables Javascript in webview. values = true, false (default = true)
enableBrowser : ενεργοποιεί την δυνατότητα να κάνετε full browsing μέσα από το view. Δηλαδή, τα links τρέχουν μέσα στο view όταν είναι ενεργοποιημένο, αλλιώς στέλνονται στο λειτουργικό να τα ανοίξει μέσα από το default πρόγραμμα (browser). values = true, false (default = false)
useFilters : ενεργοποιεί την χρήση φίλτρων που ορίζονται στο filters tag. Αυτά αφορούν τον έλεγχο των links που βρίσκονται στην ιστοσελίδα και δεν επιτρέπουν την περιήγηση σε links που αποτυγχάνουν τον έλεγχο των φίλτρων. values = true, false (default = false)
enableZoom : ενεργοποιεί την δυνατότητα να κάνετε zoom στο webview , είτε με double tap ή με gesture. values = true, false (default = true)
Filter Tag Προαιρετικό
Τα φίλτρα δουλεύουν εφόσον έχει επιλεγεί το enableBrowser = true και useFilters = true και έχουν σκοπό να επιτρέπουν να ανοίγουν μέσα στο PocketBiz links που θέλουμε και αφορούν τα συγκεκριμένα φίλτρα. Η προτεραιότητα των φίλτρων είναι ως εξής: equals->starts->ends for success (δηλ. ελέγχεται πρώτα το equals, αν αποτύχει το starts κ.ο.κ.)
equals : Φιλτράρει το link που πατάει ο χρήστης , ώστε το host του url να είναι ίδιο με το φίλτρο
starts : Φιλτράρει το link που πατάει ο χρήστης , ώστε το host του url να ξεκινάει με το φίλτρο
ends : Φιλτράρει το link που πατάει ο χρήστης , ώστε το host του url να τελειώνει με το φίλτρο
Data Tag Υποχρεωτικό
url : Βάζετε την διεύθυνση που θέλετε να δείξει το webview. Προσοχή: Να βάζετε την redirected διεύθυνση (τελική) γιατί αλλιώς αν δεν περάσει τα φίλτρα ή δεν έχετε ενεργοποιήσει το enableBrowser θα σας πετάει να το ανοίξει το λειτουργικό και δεν θα φαίνεται μέσα στο πρόγραμμα
Πχ. www.news247.gr -> redirect σε news247.gr
raw : Εδώ βάζετε καθαρό html 5 κώδικα που θέλετε να παίξει. Μέσα μπορείτε να βάλετε κάποια λεκτικά tokens ($token$ ) που θα αντικατασταθούν από τις τιμές που θα φέρει το select που θα ορίσετε στο tokensQuery. Προσοχή: μέσα στο xml πρέπει να βάλετε την html ώστε να μπορεί να παίξει, δηλ. να την μετατρέψετε με κάποιο tool ώστε τα tags να γίνουν escape.
Πχ.
<Data raw = "<!DOCTYPE html>
<html>
<body>
<video id="video" width="480" height="320" controls>
<source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
</body>
</html>"/>
Αυτό μπορεί να σας φανεί χρήσιμο για εντυπωσιακά views https://developer.chrome.com/multidevice/webview/pixelperfect
http://developer.android.com/guide/webapps/best-practices.html
tokensQuery : Εδώ βάζετε το query που θέλετε με columns τα tokens που έχετε ορίσει στην raw html .
Δηλ. Select column from table . Html content to be replaced = .......html ........ $column$ ............html........
enableJsonOutput : true/false (default false)
Προστέθηκε η δυνατότητα να αντικαθίσταται το αποτέλεσμα του select στο tokensQuery σε ένα token '$JSON$' στην raw html σε μορφή Json array.
Ενδεικτικά
[{"data":[{"customer3":"Athens","customer2":"4152","visit1":"Heineken Greece","customer1":"Heineken Greece","visit2":"4152"},{"customer3":"Athens","customer2":"4152","visit1":"Heineken Greece","customer1":"Heineken Greece","visit2":"4152"}],"success":true}]
ΠΑΡΑΤΗΡΗΣΕΙΣ
Μπορείτε να δείξετε και html5 videos μέσα στο view.
Αν βάλετε και τα 2 attributes raw και url τότε θα έχετε την εξής λειτουργικότητα: Όταν ξεκινάτε ή επιστρέφετε στην οθόνη του dashboard και δεν έχετε Internet τότε θα βλέπετε την raw html που έχετε ορίσει, ενώ αν έχετε internet θα φορτώνεται το url σας.
Προστέθηκε η δυνατότητα για να έχετε bootstrap και jquery στην raw html σας.
Ενδεικτικά <raw.html>
...
<link href="bootstrap.min.css" rel="stylesheet">
...
<script src="jquery_and_bootstrap.min.js"></script>
Παράδειγμα Web Fragment Report
Yammer Integration
Για να δημιουργήσουμε dashboard fragment για την προβολή feeds από το Yammer, στο dashboardXML, συμπληρώνουμε στα παρακάτω πεδία της εξής τιμές:
Πεδίο: item position -> την θέση μέσα στο dashboard
Πεδίο: type -> Τιμή: YAMMER (case insensitive)
Πεδίο: widthSpan -> το width που θα καταλαμβάνει το element
Πεδίο: heightSpan -> το height που θα καταλαμβάνει το element
Πεδίο: title -> Ο τίτλος του element
Πεδίο: src -> 0
Πεδίο: target -> 0
Πεδίο: group -> το id του group του χρήστη που θέλουμε να έχει σαν default η λίστα με τα feeds.
Πεδίο: network -> το id του network του χρήστη που θέλουμε να εμφανιστεί
Για παράδειγμα:
<Item position="9" type="YAMMER" widthSpan="4" heightSpan="2" title="Yammer" src="" target="" group="1113404" network="sieben.gr" />