סקילים — ניהול, מינוח ומכירות
ארבעה סקילים שנוגעים בצד התפעולי — מי נכנס, איך המערכת מדברת, ואיך היא מוציאה מסמכים. שניים מהם נוגעים בדברים שקשה או בלתי אפשרי להחזיר לאחור: הרשאות, ומספרי מסמכים.
| הסקיל | מה הוא משנה במערכת חיה | מה מחייב אישור לפני ביצוע |
|---|---|---|
myb-p-users-roles-permissions |
גישה של אנשים לנתונים | כל Set-Table-Permissions — הוא דורס |
myb-p-rename-terms |
טקסט ב‑HTML של עשרות דפים | הרשימה המלאה של הדפים והמונחים |
myb-p-mybooks-setup |
מסמכים חשבונאיים ורצפי מספור | כל דבר — כולל כל הפקת מסמך |
myb-p-price-quote-template |
מסמך שהלקוח של הלקוח רואה | תוכן ועיצוב, לפני שליחה ראשונה |
myb-p-users-roles-permissions
Section titled “myb-p-users-roles-permissions”שלושה עמודי תווך של בקרת גישה, ושלוש החלטות עצמאיות לכל עובד:
┌──────────────┐ שייך ל ┌─────────────┐ │ משתמש │ ─────────────► │ חבילה │ מושב / רישיון │ (_User) │ │ Business │ │ │ חבר ב │ Enterprise │ │ │ ─────────────► └─────────────┘ │ │ ┌─────────────┐ │ │ │ תפקיד │ קבוצת הרשאות │ │ │ Admin │ └──────────────┘ │ Sales … │ └──────┬──────┘ │ מוזכר ב ▼ ┌─────────────┐ │ הרשאות │ find / get / create │ טבלה (CLP) │ update / delete / addField └─────────────┘מי הוא? ← איזה מושב הוא תופס? ← מה מותר לו לעשות? שלוש שאלות נפרדות. למשתמש אין תפקיד אוטומטי, ולתפקיד אין הרשאה אוטומטית.
קליטת עובד — שלושה צעדים, אף אחד לא אופציונלי
Section titled “קליטת עובד — שלושה צעדים, אף אחד לא אופציונלי”// 1. יצירהCreate-or-Update-User({ "name": "דוד כהן", "username": "david.cohen@acme.co.il", "password": "<Passw0rd-לדוגמה>", "job": "מנהל מכירות", "phone": "0501111001", "active": true})// → { objectId: "6uWdJUouOg", ... }
// 2. מושבGet-Packages() // מאתרים resellerPackageIdSet-Package-for-User({ "userId": "6uWdJUouOg", "resellerPackageId": "<businessPackageId>", "action": "add" })
// 3. תפקידGet-Roles() // מאתרים roleIdAdd-Users-to-Role({ "roleId": "slOOdR6Dyh", "userIds": ["6uWdJUouOg"] })שדות המשתמש
Section titled “שדות המשתמש”| השדה | הערה |
|---|---|
name |
שם תצוגה (עברית בסדר) |
username |
מזהה ההתחברות — חייב להיות כתובת מייל (הכלי דוחה ערך אחר: Email address format is invalid.) |
password |
לפחות 8 תווים, עם אות קטנה + אות גדולה + ספרה (נאכף: Password must be at least 8 characters long / must contain at least one uppercase letter, one lowercase letter, and one number) |
job |
תפקיד (שדה מותאם) |
phone / extension |
טלפון ושלוחה |
active |
true = יכול להתחבר · false = נעול (לא נמחק) |
isPortalUser |
true למשתמשי פורטל חיצוניים — הנחיית יצירה, לא שדה שנשמר: קובע אם ליצור את המשתמש גם במערכת הראשית. משתמש פורטל אינו נוצר שם. הוא אינו נספר לחיוב ואינו מתחבר במסלול הראשי (by-design, mcp-a-03) |
emailVerified |
ברירת מחדל true |
objectId |
קיים ⇒ עדכון של השדות שהעברתם בלבד; נעדר ⇒ יצירה |
אין כלי למחיקת משתמש. הניב הוא active: false — הוא שומר את ההיסטוריה (createdBy, בעלות על רשומות, צירי זמן) וחוסם התחברות. ה‑CRM מלא בהפניות Pointer למשתמשים שיישברו במחיקה קשה.
חבילות — ההבחנה שבולעת זמן
Section titled “חבילות — ההבחנה שבולעת זמן”Get-Packages מחזיר שני דברים:
{ "packages": [ { "resellerPackageId": "5ae59690…", "numberOfUsers": 7, "resellerPackageIdData": { "name": "Business" } } ], "users": [ { "parseId": "2b0QVKoigE", "email": "…", "relatedPackages": ["5ae5986c…"] } ]}numberOfUsers הוא תקרת המושבים. לפני קליטה מרובה, ספרו: users.filter(u => u.relatedPackages.includes(pkgId)).length מול numberOfUsers. (האכיפה לא נבדקה בסבב האימות — סביבת הבדיקות היא ללא חבילה, packages: []; ב‑API הרישום אינו חוסם התחברות — core-api-13.)
העברת משתמש בין חבילות: קודם remove מהישנה, אחר כך add לחדשה — אחרת הוא תופס שני מושבים לרגע.
תפקידים
Section titled “תפקידים”| התפקיד | הצבע | לרוב |
|---|---|---|
| Admin | red | מנהל בסיס נתונים מלא |
| CRM | purple | משתמש CRM כללי — קריאה/כתיבה ברוב הטבלאות |
| Sales | azure | צוות מכירות |
| Support | green | צוות תמיכה |
| Lead Admin | red | ניהול לידים |
| Report Admin | orange | דוחות ואנליטיקה |
| MyBooks Admin | orange | הנהלת חשבונות |
| Campaign Manager | green | קמפיינים |
| MyChatAdmin / MyChatUser | red / azure | מודול הצ’אט |
Create-Role מקבל name (חובה), description וצבע מתוך green · red · yellow · orange · azure · purple.
תפקיד חדש נולד ריק — בלי משתמשים ובלי הרשאות טבלה. חברות בתפקיד לבדה לא עושה כלום עד שמוסיפים אותו ל‑CLP של טבלה כלשהי.
Add-Users-to-Role ו‑Remove-Users-from-Role מקבלים מערכים — אוגדו. הרשאות אפקטיביות של משתמש הן האיחוד של כל התפקידים שלו; אם למישהו יש גישה רחבה באופן מפתיע, בדקו את כל התפקידים שלו, לא רק את הברור.
תפקידי מערכת לא ניתנים לשינוי שם דרך MCP — השמות (Admin, Sales…) הם המפתחות הקנוניים שכל CLP מפנה אליהם. שינוי שם היה שובר כל טבלה שכתוב בה role:Admin.
CLP — הרשאות ברמת הטבלה
Section titled “CLP — הרשאות ברמת הטבלה”שש פעולות, וכל אחת ממפה מי ← true:
{ "find": { "role:Admin": true, "role:CRM": true, "role:Sales": true }, "get": { "role:Admin": true, "role:CRM": true, "role:Sales": true }, "create": { "role:Admin": true, "role:CRM": true, "role:Sales": true }, "update": { "role:Admin": true, "role:CRM": true, "role:Sales": true, "EkeJaH4t4W": true }, "delete": { "role:Admin": true }, "addField": {}}| תבנית המפתח | מעניקה ל |
|---|---|
role:<RoleName> |
כל חברי התפקיד — שם מדויק, תלוי רישיות (רווחים מותרים: role:Report Admin) |
<userObjectId> |
משתמש בודד — מנגנון חריגים, לשמור נדיר |
requiresAuthentication |
כל משתמש מחובר |
* |
ציבורי/אנונימי — רק לטבלאות שנחשפות לאינטרנט במכוון |
הערכים תמיד true — אין false, והיעדר = אין הענקה. {} על פעולה = אף אחד דרך ה‑API הרגיל (רק Master Key / MCP). ערך false נדחה בוולידציה (expected true).
find מול get: find הוא שאילתת רשימה (הרשת), get הוא שליפת רשומה בודדת לפי objectId (פתיחת כרטיס). שמרו אותם זהים כמעט תמיד — תפקיד שיכול לפתוח כרטיסים אבל לא לראות רשימה יוצר חוויה שבורה.
עשר תבניות CLP מוכנות
Section titled “עשר תבניות CLP מוכנות”| # | התבנית | הצורה |
|---|---|---|
| 1 | טבלת CRM דיפולטיבית | CRM+Admin+Sales+Support על כל 5 הפעולות, addField: {} — ברירת המחדל לטבלה מותאמת חדשה |
| 2 | טבלת מכירות בלבד | להוריד role:Support מכל מקום |
| 3 | טבלת תמיכה בלבד | להוריד role:Sales |
| 4 | צופה לקריאה בלבד | התפקיד ב‑find+get בלבד |
| 5 | שותף בלי מחיקה | find/get/create/update, לא delete — מכריח “בוטל” במקום מחיקה קשה |
| 6 | חריג למשתמש בודד | "update": { "role:Support": true, "EkeJaH4t4W": true } |
| 7 | נעילה למנהלים | רק role:Admin על הכול (טבלאות קונפיגורציה/ביקורת) |
| 8 | טבלה נעולה (מונעת‑טריגר) | קריאות לתפקידים; create/update/delete כולם {} — רק master key כותב |
| 9 | כל מי שמחובר | find/get: requiresAuthentication; כתיבה למנהלים |
| 10 | קריאה ציבורית | "*" ב‑find/get — רק לקטלוגים של דפי נחיתה, באישור הלקוח |
עזיבה ושינוי תפקיד
Section titled “עזיבה ושינוי תפקיד”עזיבה:1. Create-or-Update-User({ objectId, active: false }) ← חסימת התחברות2. Remove-Users-from-Role לכל תפקיד שהיה בו ← מסודר3. Set-Package-for-User(action: "remove") ← שחרור המושב
קידום:Remove-Users-from-Role(oldRoleId) → Add-Users-to-Role(newRoleId)אימות ב-Get-Role-Users על שני התפקידיםאחרי כל שינוי — הוכיחו שהוא עבד. משתמש נוצר? Get-all-Users כולל אותו. חבילה הוצבה? Get-Packages ← users מציג relatedPackages חדש. CLP השתנה? Get-Table-Permissions מציג את הצורה החדשה. אל תסמכו על “OK” של קריאת הכתיבה כשההרשאות רגישות.
myb-p-rename-terms
Section titled “myb-p-rename-terms”מתאים את שפת המוצר לשפת הלקוח — “מכירה” ← “פרויקט”, “לקוח” ← “משתתף”, “פנייה” ← “קריאה” — בכל הממשק, בעזרת כלים ילידיים שמשנים את ה‑HTML ואת מילוני המערכת ישירות.
| הכלי | מה הוא משנה |
|---|---|
Set-Terminology-Dictionary |
מיפוי מונחים כלל‑מערכתי שקובצי ה‑JS של המוצר קוראים |
Replace-Terms |
החלפת טקסט ישירות ב‑HTML של דף — קבוע |
Edit-Page + change-existing-field-label |
תוויות שדה בטופס |
Set-Menu-Items |
כותרות פריטי תפריט |
Add-Edit-Text-Element |
אלמנט טקסט/כותרת ספציפי לפי elemId |
מיפוי ברירת המחדל
Section titled “מיפוי ברירת המחדל”| הישות | המחלקה | יחיד | רבים |
|---|---|---|---|
| Sale | Sales |
מכירה | מכירות |
| Account | Accounts |
לקוח | לקוחות |
| Case | Cases |
פנייה | פניות |
| Task | Tasks |
משימה | משימות |
| Activity | Activities |
פעילות | פעילויות |
| Contact | Contacts |
איש קשר | אנשי קשר |
שמונת השלבים
Section titled “שמונת השלבים”1. גילוי כל הדפים המושפעים — בשתי אסטרטגיות משלימות:
לפי שם: Get-Site-Pages ואז סינון לפי שם המחלקה. עבור Sale: Sale, Sales, SaleRows, Pipeline, DashboardSales, DashboardSalesManager, DashboardSalesRep, System-Tables-Sale-Statuses, Mobile-Sale, Mobile-Sales.
לפי סכימה: Get-Schema ← טבלאות עם שדות Pointer שמצביעים למחלקה. אם יש להן דפים, הן עלולות להציג את המונח בתוויות או בכותרות סקשן.
2. עדכון מילון המונחים — Get-Terminology-Dictionary תחילה, ואז Set-Terminology-Dictionary שמעדכן את המונחים שמשתנים ומשמר את כל השאר:
Set-Terminology-Dictionary({ "terminology": { "מכירה": "פרויקט", "מכירות": "פרויקטים", "פנייה": "פנייה", "פניות": "פניות", "משימה": "משימה", "משימות": "משימות", "לקוח": "לקוח", "לקוחות": "לקוחות"}})3. Replace-Terms על CRMmaster — הצעד החשוב ביותר. שם יושב המילון הראשי שמשמש את כל הדפים.
4. Replace-Terms על Timeline — בנפרד. הוא מכיל שמות ישויות קשיחים בתבניות האירועים.
5. Replace-Terms על כל הדפים שהתגלו — אפשר במקביל. זה מטפל בכותרות, טקסט כפתורים (“מכירה חדשה” ← “פרויקט חדש”), כותרות גרפים ומונים, כותרות מודאל, תוויות צ’קבוקס, כותרות עמודות, ותיאורי כרטיסי הגדרות. דף שלא הכיל את המונח מחזיר Error: No changes found (לא changes: []) — זו לא תקלה; דף שהכיל מחזיר changes: [{term, count}].
6. תוויות שדה — לדפים שבהם הישות מופיעה כתווית של שדה Pointer (“משויך למכירה”):
Edit-Page({ "pageId": "<PriceQuote>", "actions": [ { "actionType": "change-existing-field-label", "fieldName": "SaleId", "label": "משויך לפרויקט" }]})7. פריטי תפריט — Get-Menus ← Get-Menu-Items לכל תפריט רלוונטי ← Set-Menu-Items. כל פריט חייב לכלול את כל השדות (_id, title, type, page, order, icon) — מעתיקים מהתשובה של Get-Menu-Items.
8. אימות — המשתמש מרענן (Ctrl+F5) ובודק: תפריט הצד · דף הרשימה (כותרת, כפתור, עמודות) · דף הטופס · Pipeline · דף הלקוח (לשוניות, סקשנים) · ציר הזמן · לשוניות “הוספה חדשה” · דשבורדים · דף ההגדרות ותת‑הדפים.
כשהמגדר משתנה (מכירה = נקבה ← פרויקט = זכר), פעלי ציר הזמן צריכים התאמה:
Replace-Terms({ "pageId": "<Timeline>", "terms": { "מכירה": "פרויקט", "מכירות": "פרויקטים", "עודכנה": "עודכן", "נוצרה": "נוצר"}})רק על Timeline. בדפים אחרים המילים האלה עשויות להופיע בהקשרים שונים לגמרי.
כללי ברזל
Section titled “כללי ברזל”- אין דריסות JS בלי אישור מפורש.
CRMmaster+Timelineהם חובה.- לעולם לא לגעת בסכימה — שמות טבלאות, שמות שדות ומחלקות CSS הם מזהים פנימיים.
- קריאה לפני כתיבה —
Get-Page-Contentלקבלת מזהי הדפים. - אידמפוטנטי — הרצה שנייה עם אותם מונחים מחזירה
No changes found; המונח הישן כבר איננו. - להיזהר ממונחים ששוברים HTML — הסכימה מזהירה מזה במפורש. מונח שמופיע גם בשם מחלקת CSS או בתכונת
data-*יהרוס את הדף.
חזרה לאחור
Section titled “חזרה לאחור”Set-Terminology-Dictionary— שחזור המונחים המקורייםReplace-Termsעל כל הדפים עם המיפוי ההפוך ({"פרויקט": "מכירה"})Set-Menu-Items— שחזור הכותרותEdit-Page— שחזור תוויות השדות
myb-p-mybooks-setup
Section titled “myb-p-mybooks-setup”MyBooks הוא אפליקציית החיוב והמסמכים (apps/mybooks/) — היא חולקת את הטבלאות Accounts ו‑Products עם ליבת ה‑CRM, ומפיקה מסמכים ממוספרים, בעלי משמעות משפטית, ובלתי ניתנים לשינוי.
MCP מול ממשק — למה זה סקיל של הדרכה
Section titled “MCP מול ממשק — למה זה סקיל של הדרכה”| מה | הסטטוס |
|---|---|
קריאות MCP (Get-Data, Count-Data, Get-Schema, Get-Site-Pages) |
משטח האימות המתועד. אחרי כל צעד בממשק |
כתיבות MCP לטבלאות הקונפיגורציה (AccountingSettings, AccountingDocsType, Retainers, PaymentBtns) |
אינן מנגנון נתמך — אל תכתבו. חיווט השרת (מספור, טוקנים, מנוע החיוב) עלול להיעקף בכתיבת שורה גולמית. לא נבדק בסבב האימות בכוונה (אין דרך בטוחה לבדוק זאת בלי לסכן רצפי מספור). ברירת המחדל: הדרכה בממשק + קריאה חוזרת |
Products |
חריג — טבלת נתונים משותפת רגילה. Create-Data בסדר, ואז אימות שהמוצר מופיע בדף ההגדרות |
“הדרכה בממשק” פירושה: לומר למשתמש בדיוק איפה (נתיב הדף) ומה להזין — ואז הסוכן מאמת בקריאה חוזרת. שום צעד לא מסתיים ב“תעשה את זה בממשק” בלי אימות.
שלב 0 — ביקורת בסיס (קריאה בלבד, תמיד ראשונה)
Section titled “שלב 0 — ביקורת בסיס (קריאה בלבד, תמיד ראשונה)”Get-Site-Pages ← יש apps/mybooks/*? אם לא — המודול לא מותקןGet-Data("AccountingSettings", keys: [...], limit: 1)Get-Data("AccountingDocsType", limit: 10) ← סוגי המסמכים + NumLast לכל אחדGet-Data("CreditClearingTerminal", limit: 10)Count-Data("AccountingHeaders") ← כבר הופקו מסמכים? זה משנה את חשבון ההסבהCount-Data("AccountingHeadersDraft")Count-Data("Retainers")Get-Data("RetainerPlans", limit: 20)Get-Data("PaymentBtns", limit: 20)אם Count-Data("AccountingHeaders") > 0 — כבר הופקו מסמכים, והמספור לא ניתן להורדה מתחת למספרים האלה. אומרים את זה לפני הריאיון, לא אחריו.
תשע שאלות הריאיון
Section titled “תשע שאלות הריאיון”- סוגי מסמכים — מה העסק מפיק בפועל? (חשבונית מס · קבלה · חשבונית מס קבלה · חשבונית מס זיכוי · חשבונית עסקה · הזמנת עבודה · תעודת משלוח)
- המשך רצף ממערכת קודמת — מה המספר האחרון שהופק בכל סוג? החלטה חשבונאית‑משפטית: המספור ניתן להעלאה בלבד וטעות אינה הפיכה. בקשו אישור בכתב למספרים, ואשרור מול רואה החשבון.
- פרטי עסק — שם משפטי (עברית + אנגלית אם מפיקים באנגלית), ח.פ/עוסק, כתובת, לוגו, אחוז מע“מ, מטבע.
- סליקה — כן/לא, איזה ספק (Upay / Pelecard), ומי מחזיק בפרטי ההתחברות (הלקוח, תמיד).
- ריטיינרים / הוראות קבע — תדירות, תאריך חיוב ראשון, סכומים או תוכניות, סוג המסמך בכל חיוב, כמה לקוחות.
- דפי/כפתורי תשלום — אילו מוצרים במחיר קבוע, טווח כמויות, איפה הכפתור יוטמע.
- שליחת מסמכים במייל — מכתובת המערכת או מכתובת ממותגת (SMTP)?
- חשבונית ישראל — צפויות חשבוניות מעל סף מספרי ההקצאה? (הסף משתנה לפי שנה — לוודא מול רואה החשבון.)
- מלאי — האם מסמכים צריכים להזיז מלאי? מחוץ לליבת הסקיל; להוסיף להיקף במפורש.
עשרת השלבים
Section titled “עשרת השלבים”| # | השלב | הדף בממשק | הקריאה החוזרת |
|---|---|---|---|
| 3 | זהות עסקית | apps/mybooks/SettingCompany |
Get-Data("AccountingSettings", keys: [...]) |
| 4 | סוגי מסמכים ומספור | הגדרות מסמכים | Get-Data("AccountingDocsType", limit: 20) — NumLast מול האישור בכתב |
| 5 | תבניות ומוצרים | SettingsTemplates · SettingProducts |
Get-Data("Products") + בדיקה חזותית |
| 6 | סליקה | SettingPelecard |
Get-Data("CreditClearingTerminal") — שורה עם Default: true |
| 7 | ריטיינרים | RetainerPlans · Retainers |
Get-Data("Retainers", keys: [...]) + RetainerRows |
| 8 | דפי תשלום | PaymentsBtns |
Get-Data("PaymentBtns") + פתיחת ה‑Link הציבורי |
| 9 | שליחה במייל | בלוק SMTP ב‑AccountingSettings |
Get-Data(keys: ["SmtpServer","SmptPort",…]) + שליחה חוזרת של מסמך קיים |
| 10 | תאימות ישראלית | הגדרות ← חשבונית ישראל · ExportUniformFiles |
אימות טבעי בחשבונית הראשונה מעל הסף |
מעבר האימות — טיוטה, ורק אז ייצור
Section titled “מעבר האימות — טיוטה, ורק אז ייצור”זרימת טיוטה מקצה לקצה, חובה: הלקוח יוצר מסמך חדש מהסוג העיקרי ב‑apps/mybooks/Documents ← בוחר לקוח ← מוסיף שורת מוצר ← שמור טיוטא (לא הפק מסמך). הסוכן מאמת Get-Data("AccountingHeadersDraft") ואת שורות ה‑AccountingInvoiceLinesDraft/AccountingReceiptLinesDraft, ואז הטיוטה נמחקת מלשונית הטיוטות — והמחיקה מאומתת בקריאה חוזרת.
ההפקה האמיתית הראשונה — רק באישור מפורש, ורצוי על עסקה אמיתית ראשונה: מאשרים עם המשתמש את ה‑DocumentNumber הצפוי (= NumLast + 1) לפני הלחיצה, מזהירים שה‑PDF נפתח בחלון קופץ, וקוראים חזרה Get-Data("AccountingHeaders") למספר ולקובץ, ו‑AccountingInvoiceBalance לסוגי חשבונית.
מה הסקיל אינו
Section titled “מה הסקיל אינו”| הבקשה | לאן |
|---|---|
| תבניות הצעת מחיר / עיצוב PDF ממותג | myb-p-price-quote-template |
| אוטומציות חיוב (מיילים על אירועי מסמך, תזכורות) | myb-p-trigger-setup |
| דוחות מעבר לדוחות המובנים | myb-p-create-update-reports |
| ייבוא חשבוניות ישנות כמסמכים שהופקו | לא יכולת מתועדת. מנגנון ההסבה המתועד הוא המשך רצף, עם הארכיון הישן נשמר במערכת הקודמת. כל בקשה כזו מסווגת כ‑Gap |
| ייעוץ חשבונאי או מיסויי | רואה החשבון של הלקוח |
myb-p-price-quote-template
Section titled “myb-p-price-quote-template”תבניות הצעת מחיר הן HTML מלא עם placeholders דינמיים שמוחלפים בנתוני המכירה בזמן יצירת ה‑PDF. התבנית רצה בתוך Webview בתוך דף ה‑CRM — ומכאן המגבלות.
אחסון: טבלת PDFTemplate, נגישה דרך Get-Data / Update-Data / Create-Update-Price-Quote-Template.
שלושת הכללים הקריטיים
Section titled “שלושת הכללים הקריטיים”מבנה החובה
Section titled “מבנה החובה”<div id="windowDiv" class="rtl" style="height: auto; padding: 20px 50px; -webkit-print-color-adjust: exact; direction: rtl;">
<!-- כל התוכן -->
<div id="sigDiv"> <div id="Signature">חתימה</div> <div id="SignatureName">שם חתום</div> <div id="SignatureDate">תאריך חתימה</div> </div></div>ה‑placeholders
Section titled “ה‑placeholders”{{number}} מספר הצעת המחיר{{date}} תאריך היצירה{{totalIncludingVat}} סה"כ כולל מע"מ{{Vat}} אחוז המע"מ
{{Sales.AccountId.Name}} שם הלקוח{{Sales.AccountId.PhoneNumber}} טלפון{{Sales.AccountId.Email}} מייל{{Sales.AccountId.Address}} כתובת{{Sales.TotalBeforeDiscount}} לפני הנחה{{Sales.DiscountValue}} סכום ההנחה{{Sales.Total}} אחרי הנחה, לפני מע"משורות מוצרים — data-repeat יושב על ה‑<tr>, לא על ה‑<table> ולא על ה‑<td>:
<tr data-repeat="SaleRows"> <td>{{SaleRows.ProductId.Name}}</td> <td>{{SaleRows.Description}}</td> <td>{{SaleRows.Quantity}}</td> <td>{{SaleRows.PricePerUnit}} ₪</td> <td>{{SaleRows.Total}} ₪</td></tr>מה אסור להכניס להצעת מחיר
Section titled “מה אסור להכניס להצעת מחיר”הצעת מחיר היא מסמך חיצוני שהלקוח רואה. שדות ניהול פנימיים לא נכנסים:
| שדה אסור | למה |
|---|---|
{{Sales.Probability}} |
הסתברות סגירה — למנהל המכירות |
{{Sales.ReasonForLost}} |
סיבת כישלון |
{{Sales.NextStepDate}} |
תאריך התקשרות הבא |
{{Sales.IsWon}} / {{Sales.IsLost}} |
סטטוס פנימי |
RTL בטבלאות
Section titled “RTL בטבלאות”בכיוון RTL, ה‑<td> הראשון בשורה מוצג בצד ימין. רוצים לוגו בימין — הוא ה‑<td> הראשון; פרטי חברה בשמאל — ה‑<td> השני.
הלוגו — הבעיה שנראית כמו בעיית עיצוב
Section titled “הלוגו — הבעיה שנראית כמו בעיית עיצוב”קובצי PNG של לוגואים מגיעים לרוב עם שטח שקוף עצום מסביב: קובץ 3000×3000 שהלוגו בו תופס 2100×500 במרכז. הצגה עם max-width: 300px תיתן לוגו זעיר — כי הוא רק 70% מגובה התמונה.
הפתרון הוא חיתוך לפי ערוץ Alpha לפני ההעלאה. אחרי חיתוך נכון, width קבוע עם height: auto מספיק:
<img src="URL" style="width: 240px; height: auto; display: block; margin-right: 0; margin-left: auto;" />אל תשתמשו ב‑max-height — זה מה שגורם ללוגו להיראות קטן.
העלאה: Upload-Public-File עם base64, או שהלקוח מעלה דרך ממשק המדיה של ה‑CRM ומוסר את ה‑URL.
// יצירה — מחזיר objectId, לשמור לעדכוניםCreate-Update-Price-Quote-Template({ "templateName": "הצעת מחיר — מותג א'", "templateContent": "<div id=\"windowDiv\" class=\"rtl\" …>…</div>"})
// עדכון — עם objectIdCreate-Update-Price-Quote-Template({ "templateName": "הצעת מחיר — מותג א'", "objectId": "xxxxxxxxxx", "templateContent": "<div id=\"windowDiv\" …>…</div>"})
// רשימת התבניות הקיימותGet-Price-Quote-Templates()
// קריאת תבנית — מחזיר את שדה ה-HTMLGet-Data({ "table": "PDFTemplate", "objectId": "xxxxxxxxxx" })שכפול תבנית למותג אחר: קוראים את ה‑HTML של המקורית עם Get-Data, מזינים אותה ל‑Create-Update-Price-Quote-Template עם שם חדש ובלי objectId.
שדות קלט בתבנית
Section titled “שדות קלט בתבנית”- כלי משתמשים ב‑MCP · כלי הצעות מחיר
- סוכן במצב קריאה בלבד — רשימת ההיתר שמייצרת סוכן שלא יכול לשנות כלום
- עבודה בטוחה עם סוכן על מערכת חיה