דוחות
שני כלים, ומנוע אחד: כל הדוחות והשאילתות השמורות במוצר חיים במחלקה _DynamicQueries.
שאילתה מול דוח
Section titled “שאילתה מול דוח”אותו מנגנון בדיוק, בשני מקומות בממשק:
| הצורה | איפה מופיעה | מה מבדיל |
|---|---|---|
| דוח | דף הדוחות — apps/mybusiness/Reports |
PageName: "apps/mybusiness/reports" |
| שאילתה שמורה | הרשימה הנפתחת “שאילתות” בדף רשימה של ישות | PageId + PageName הם אותו דף; FormName הוא הטופס שלו (בסגנון dynamic-table-formP113); Default: true הופך אותה לתצוגה הפותחת. חובה ShowFields — שאילתת ברירת מחדל בלי ShowFields מסתירה את כל עמודות הטבלה |
לכן אותו כלי בונה גם “דוח מכירות לפי אחראי” בדף הדוחות, וגם את התצוגה שנפתחת כברירת מחדל בדף המכירות.
Get-Reports
Section titled “Get-Reports”| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
objectId |
String | דוח בודד לפי מזהה | |
pageId |
String | כל הדוחות של דף מסוים |
בלי אף פרמטר מוחזרים הדוחות של הדף apps/mybusiness/reports (סינון לפי PageName), כ‑{ "results": [ … ] }. objectId שלא קיים מחזיר { "results": [] }.
Create-or-Update-Report
Section titled “Create-or-Update-Report”| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
report |
Object | ✔ | אובייקט הדוח |
reportId |
String | מזהה דוח קיים. קיים ⇒ עדכון; נעדר ⇒ יצירה |
שדות ה‑report
Section titled “שדות ה‑report”| הקבוצה | השדה | המשמעות |
|---|---|---|
| זהות | Name |
שם הדוח בעברית. חובה ביצירה (Error: Name is required). הימנעו מגרשיים וסוגריים — ראו המגבלה על קידוד |
ClassName |
הטבלה שעליה שואלים. חובה ביצירה, תמיד — גם בשאילתת ישות (Error: ClassName is required) |
|
| מיקום | PageName / PageId / FormName / Default |
לאיזה דף הדוח נקשר. שלחו גם PageId וגם PageName |
| עמודות | ShowFields |
מערך מסלולי תצוגה — בלי שם המחלקה: "AccountId.Name", "OwnerId.name" |
OptionalFields |
הגדרת כל עמודה: { field ✔, summary ✔, text, type, aggrField, aggrFunc, dateFormat } |
|
| סינון | QueryElems |
פקדי הסינון שהמשתמש רואה — מבנה תנאי B |
| צורה | IsAggr |
false = רשימה שטוחה של רשומות · true = מקובץ ומסוכם |
PivotInfo |
{ row, col, value } — טבלה צולבת. דורש IsAggr: true |
|
CalculatedFields |
עמודות מחושבות | |
| תצוגה | Sort |
שדה מיון. מקף לסדר יורד: -createdAt. (זו גם הדרך היחידה למיון ברירת מחדל בדף רשימה — דרך שאילתה עם Default: true) |
ShowSum |
כותרת שורת הסיכום — הערך הוא הכותרת, והוא מה שמפעיל את השורה. בלי גרשיים (ראו המגבלה על קידוד) | |
GridDivider |
רוחב פקד סינון בגריד. ברירת מחדל 4 |
|
AllowCsv |
כפתור ייצוא CSV | |
Url2Link |
הצגת URL כקישור | |
| תזמון | ScheduleSendAt |
{ interval ✔, hour ✔, occurrence } |
ScheduleSendTo |
כתובות מייל, מופרדות בפסיקים | |
| הרשאות | permissions |
מי רשאי לראות ולהשתמש. הכלי לא אוכף את הנוכחות שלו — בלי permissions הדוח נוצר עם ACL של הבעלים בלבד, ואף אחד אחר לא רואה אותו |
editPermissions |
objectId של המשתמש שרשאי לערוך. חובה ביצירה עם Master Key (Error: Edit Permissions is required when creating a report with master key) |
המבנה שגורם לרוב הכשלים
Section titled “המבנה שגורם לרוב הכשלים”בדוח מקובץ (IsAggr: true), כל עמודה ב‑OptionalFields היא אחד משניים — וההבדל היחיד ביניהן הוא נוכחות aggrFunc:
שדה בלי
aggrFunc(או עם"") הוא הקיבוץ. שדה עםaggrFuncהוא הערך.
זה הכול. אין דגל groupBy ואין דגל measure — הנוכחות של הפונקציה היא ההצהרה.
aggrFunc |
המשמעות |
|---|---|
"" או מושמט |
קבץ לפי השדה הזה |
dow · q · q/yy · mm · mm/yy · yy · dd/mm/yy · mm/dd/yy |
קבץ שדה תאריך לפי חלון הזמן הזה. mm/yy הוא סוס העבודה |
count · sum · avg · min · max |
מדוד — זו עמודת הערך |
{ "report": { "Name": "מכירות לפי אחראי וחודש", "ClassName": "Sales", "PageName": "apps/mybusiness/reports", "IsAggr": true, "AllowCsv": true, "PageId": "<ה-_id של דף Reports מ-Get-Site-Pages>", "ShowFields": ["OwnerId.name", "createdAt", "Total"], "OptionalFields": [ { "field": "OwnerId.name", "aggrField": "OwnerId._User.name", "text": "אחראי", "summary": "" }, { "field": "createdAt", "aggrField": "createdAt", "text": "חודש", "aggrFunc": "mm/yy", "summary": "" }, { "field": "Total", "aggrField": "Total", "text": "סכום", "aggrFunc": "sum", "summary": "sum" } ], "QueryElems": [ { "F": "SaleStatusId", "C": "exists", "T": "Pointer", "P": { "targetClass": "SaleStatuses" }, "FText": "שלב קיים" } ], "Sort": "-Total", "ShowSum": "סיכום", "GridDivider": 4, "permissions": ["role:Admin", "role:Sales"], "editPermissions": "2b0QVKoigE"} }summary הוא פונקציית שורת הסיכום של העמודה: sum/avg/min/max רק על עמודה מספרית. summary: "sum" על עמודת count של שדה מחרוזת (או על כל שדה שאינו Number) מפיל את שורת הסיכום ב‑400 — the type of the group aggregate field (Name) must be "Number"; השתמשו שם ב‑"" או count.
שלושת השדות שחייבים להתיישר
Section titled “שלושת השדות שחייבים להתיישר”לכל עמודה בדוח מקובץ, שלושה ערכים חייבים להסכים:
| המאפיין | הפורמט | הדוגמה |
|---|---|---|
ShowFields[i] |
מסלול נקודה, בלי שם מחלקה | "SaleStatusId.Name" |
OptionalFields[i].field |
זהה ל‑ShowFields[i] |
"SaleStatusId.Name" |
OptionalFields[i].aggrField |
מסלול מלא, עם שם המחלקה באמצע | "SaleStatusId.SaleStatuses.Name" |
דוח שטוח
Section titled “דוח שטוח”IsAggr: false — רשימת רשומות כמו שהן. OptionalFields מצטמצם ל‑{ field, summary, text }, בלי aggrFunc ובלי aggrField, ו‑summary משמש רק לשורת הסיכום התחתונה.
{ "report": { "Name": "דוח מכירות מפורט", "ClassName": "Sales", "PageName": "apps/mybusiness/reports", "IsAggr": false, "AllowCsv": true, "PageId": "<ה-_id של דף Reports>", "ShowFields": ["AccountId.Name", "Name", "SaleStatusId.Name", "OwnerId.name", "Total", "ClosingDate"], "OptionalFields": [ { "field": "AccountId.Name", "summary": "", "text": "לקוח" }, { "field": "Name", "summary": "", "text": "שם מכירה" }, { "field": "SaleStatusId.Name", "summary": "", "text": "סטטוס" }, { "field": "OwnerId.name", "summary": "", "text": "אחראי" }, { "field": "Total", "summary": "sum", "text": "סכום" }, { "field": "ClosingDate", "summary": "", "text": "תאריך סגירה", "dateFormat": "Date" } ], "Sort": "-createdAt", "ShowSum": "סיכום", "GridDivider": 4, "permissions": ["role:Admin", "role:Sales"], "editPermissions": "2b0QVKoigE"} }ערכי summary: "" · count (לכל טיפוס) · sum · avg · min · max (ל‑Number; min/max גם ל‑Date).
ערכי dateFormat להצגה: DateTime · Date · Time · Year · Q/YY · MM/YY · Month · Quarter.
טבלה צולבת — PivotInfo
Section titled “טבלה צולבת — PivotInfo”"PivotInfo": { "row": "OwnerId.name", "col": "createdAt", "value": "Total" }row— שדה קיבוץ (בליaggrFunc).col— בדרך כלל תאריך עםaggrFuncשל זמן.value— מדד עםsumאוcount.- כל שלושתם חייבים להופיע גם ב‑
ShowFieldsוגם ב‑OptionalFields, ודורשIsAggr: true. - תא שסכומו 0 מוצג כ‑
NaN— פגם תצוגה בלבד.
QueryElems — פקדי הסינון
Section titled “QueryElems — פקדי הסינון”מבנה תנאי B, בדיוק כמו בטבלאות תצוגה ובטריגרים:
"QueryElems": [ { "F": "Name", "C": "contains", "T": "String", "V": "", "FText": "חיפוש שם" }, { "F": "SaleStatusId", "C": "containedIn", "T": "Pointer", "V": [], "P": { "targetClass": "SaleStatuses", "multiple": true }, "FText": "סטטוס" }, { "F": "OwnerId", "C": "equalTo", "T": "Pointer", "V": "currentUser", "P": { "targetClass": "_User" }, "FText": "אחראי" }, { "F": "createdAt", "C": "greaterThanOrEqualTo", "T": "Date", "FText": "מתאריך" }, { "F": "createdAt", "C": "lessThanOrEqualTo", "T": "Date", "FText": "עד תאריך" }, { "F": "IsAccount", "C": "equalTo", "T": "Boolean", "V": false, "FText": "לידים בלבד" }]containedIn+P.multiple: true= בחירה מרובה.equalToבליmultiple= בחירה יחידה."currentUser"= “הרשומות שלי”.- סינון לפי שדה בטבלה מקושרת נכתב עם שם המחלקה:
"AccountId.Accounts.Name"— שימו לב שזה הפוך מ‑ShowFields, שם המחלקה לא מופיעה.
פריסת הפילטרים
Section titled “פריסת הפילטרים”הממשק מסדר את הפקדים מימין לשמאל, מלמעלה למטה, לפי הסדר במערך.
GridDivider:3(ארבעה פקדים בשורה — האידיאלי) או4(שלושה בשורה) כשיש מספיק פקדים למלא שורה.6ו‑12מותחים פקד על חצי מסך או על כולו, וזה נראה שבור, אלא אם באמת יש רק פקד או שניים. זה בדיוק מה שסכימת הכלי ממליצה: “for one field the number should be 12. for 2 fields the value is 6”.- סדר המערך: חיפושי טקסט ← בחירות מרובות של Pointer ← זוגות טווח תאריכים ← תיבות סימון אחרונות. תיבת סימון בסוף המערך נוחתת בפינה השמאלית‑תחתונה, שזה המקום הטבעי שלה ב‑RTL.
CalculatedFields — עמודות מחושבות
Section titled “CalculatedFields — עמודות מחושבות”"CalculatedFields": [ { "name": "מחיר לפני הנחה", "fieldA": "PricePerUnit", "fieldB": "Quantity", "action": "Times" }, { "name": "שיעור הנחה", "fieldA": "מחיר לפני הנחה", "fieldB": "Total", "action": "Divide (%)" }]action |
הפעולה |
|---|---|
Plus |
fieldA + fieldB |
Minus |
fieldA - fieldB |
Times |
fieldA * fieldB |
Divide |
fieldA / fieldB |
Divide (%) |
(fieldA / fieldB) * 100 |
אפשר לשרשר: ה‑name של שדה מחושב קודם משמש כ‑fieldA או fieldB בשדה הבא — כמו בדוגמה.
משלוח מתוזמן
Section titled “משלוח מתוזמן”"ScheduleSendAt": { "interval": "daily", "hour": 8, "occurrence": [] },"ScheduleSendTo": "manager@company.com,team@company.com"interval |
occurrence |
|---|---|
daily |
[] |
weekly |
ימי השבוע, 0 = ראשון — למשל [0, 3] |
monthly |
ימים בחודש — למשל [1, 15] |
occurrence נחוץ ל‑weekly ול‑monthly — אבל הכלי לא אוכף אותו (שבועי בלי occurrence נשמר כמות שהוא). ספקו אותו תמיד.
הרשאות
Section titled “הרשאות”"permissions": ["role:Admin", "role:Sales", "2b0QVKoigE"],"editPermissions": "2b0QVKoigE"permissions— מי רואה ומשתמש. תפקיד נכתב בקידומתrole:ואחריה שם התפקיד המדויק (רגיש לרישיות ולרווחים:role:Report Admin). את שמות התפקידים מוציאים ב‑Get-Roles.editPermissions—objectIdשל משתמש אחד. חובה כשיוצרים עם Master Key, כי אז אין משתמש מחובר שיירש את הבעלות.
ה‑permissions נכתבים כמות שהם כמפתחות קריאה ב‑ACL של הרשומה, ו‑editPermissions מקבל קריאה+כתיבה. לכן משתמש נכתב כ‑objectId חשוף (כפי שהסכימה אומרת); הצורה "userId:<id>" יוצרת מפתח ACL חסר משמעות ואינה מעניקה דבר. ובכל מקרה: העדיפו תפקידים על משתמשים בודדים.
סדר העבודה
Section titled “סדר העבודה”1. Get-Schema(class) מאמתים שמות שדות2. Get-Optional-Fields(class) ← מכאן מעתיקים field / aggrField / type / text3. Get-Roles → שמות התפקידים ל-permissions Get-all-Users → objectId ל-editPermissions4. שאילתת ישות? Get-Reports(pageId) → מעתיקים FormName משאילתה קיימת5. Create-or-Update-Report6. Get-Reports(objectId) קריאה חוזרת לאימות7. דוח מתוזמן? יוצרים בלי תזמון, ומוסרים למשתמש את צעד ההוספה/השמירה מהממשקמגבלות
Section titled “מגבלות”- אין מחיקת דוח. אין כלי. מחיקה נעשית בממשק או ב‑REST על
_DynamicQueriesעם Master Key. - דוח מורכב אינו נתמך בכלי. דוח שמאגד כמה דוחות (
SubqueriesInfo) — הכלי מתעלם מהשדה ויוצר דוח רגיל. זהו פער ידוע בכלי; אל תעקפו אותו בכתיבה ישירה מסביבת סוכן. - פלט
Get-Reportsכבד — סננו לפיobjectIdאוpageId. Aggregate-Dataהוא הדוד של המשפחה, לא בן שלה. הוא אגרגציה חד‑פעמית שלא נשמרת בשום מקום, והדקדוק שלו קרוב אבל לא זהה — הפרמטרgroupbyשלו הוא מחרוזת. ראו כלי נתונים.GridDividerברירת מחדל4— ואם לא תעברו עליו במודע תקבלו לפעמים פריסה שנראית שבורה.
- טבלאות תצוגה ודפי רשימה —
Get-Optional-Fieldsואותה דוקטרינתaggrField - אלמנטי דשבורד — כשהמספר הבודד עדיף על טבלה
- כלי נתונים — אגרגציה חד‑פעמית בלי לשמור דוח
- תפקידים, הרשאות טבלה וחבילות — מאיפה מגיעים
role:ו‑editPermissions - אינדקס הכלים המלא