כלי הצעות מחיר
הצעת מחיר במערכת היא מסמך HTML עם placeholders, ששמור כשורה בטבלה PDFTemplate. ההפקה ממזגת רשומת Sales — יחד עם שורות המכירה שלה ועם הלקוח שאליו היא מצביעה — לתוך התבנית, מרנדרת אותה, ומייצרת PDF לשליחה ולחתימה.
שלושה כלים: אחד מוצא תבניות, אחד כותב תבנית, אחד מפיק מסמך.
Get-Price-Quote-Templates
Section titled “Get-Price-Quote-Templates”בלי פרמטרים. מחזיר objectId ו‑Name לכל תבנית — ולא את ה‑HTML.
[ { "objectId": "pdft012345", "Name": "הצעת מחיר כולל מע\"מ" }, { "objectId": "pdft067890", "Name": "תבנית קלאסית-מקצועית" } ]כדי לקרוא את התוכן עצמו — Get-Data על טבלת PDFTemplate:
{ "table": "PDFTemplate", "objectId": "pdft012345" }יש גם משאב MCP בשם price-quote-example (URI: price-quote-example://main, מתגלה ב‑resources/list ונקרא ב‑resources/read) שמחזיר תבנית לדוגמה עם כל ה‑placeholders — כ‑4KB של HTML עם windowDiv, בלוק חתימה, data-repeat על <tr> ובלי שום <script>. זו הדרך המהירה ללמוד את הפורמט לפני שכותבים אחת חדשה. על משאבי MCP והדרך לקרוא אותם — כלי קבצים.
Create-Update-Price-Quote-Template
Section titled “Create-Update-Price-Quote-Template”יוצר תבנית חדשה, או מעדכן קיימת כשמעבירים objectId.
| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
templateName |
String | ✔ | שם התבנית כפי שיופיע ברשימה |
templateContent |
String | ✔ | ה‑HTML המלא |
objectId |
String | מזהה תבנית קיימת ⇒ עדכון. בלעדיו — נוצרת תבנית חדשה |
התשובה ביצירה: { "objectId": "CdbeHAOSBL", "createdAt": "…" }; בעדכון: { "objectId": "…", "updatedAt": "…" }. objectId שאינו קיים ⇒ Error: Object not found.. תבנית שנוצרת דרך הכלי מקבלת אוטומטית TypeId של “הצעות מחיר”, ולכן מופיעה מיד ב‑Get-Price-Quote-Templates.
חוזה ה‑HTML — ארבעה כללים מחייבים
Section titled “חוזה ה‑HTML — ארבעה כללים מחייבים”1 · שורש windowDiv
Section titled “1 · שורש windowDiv”האלמנט החיצוני חייב להיות div עם id="windowDiv":
<div id="windowDiv" class="rtl" style="height: auto; padding: 20px 50px; direction: rtl; -webkit-print-color-adjust: exact; font-family: 'Noto Sans Hebrew', sans-serif;"> <!-- כל תוכן המסמך --></div>2 · בלוק החתימה מנוהל על ידי המערכת
Section titled “2 · בלוק החתימה מנוהל על ידי המערכת”<div id="sigDiv" style="text-align: center; margin-top: 30px;"> <div id="Signature">חתימה</div> <div id="SignatureName">שם חתום</div> <div id="SignatureDate">תאריך חתימה</div></div>שלושת המזהים הפנימיים מחויבים בסכימה. העטיפה sigDiv היא מה שהמערכת מסתירה לפני החתימה וחושפת אחריה (בעמוד PriceQuoteSign: לפני החתימה sigDiv מקבל display: none; את שדות החתימה עצמם — תאריך, שם חותם, אימייל, קנבס חתימה — העמוד מוסיף בעצמו).
לכן: אל תסתירו את הבלוק ב‑CSS — display:none שובר את הזרימה — ואל תשנו את שמות המזהים, כי אז הבלוק מוצג ללקוח לפני שחתם.
אחרי חתימה מוצלחת רשומת ה‑PriceQuotes מתעדכנת: StatusId עובר ל‑“אושרה”, ונכתבים SignedAt, SignedByName, SignedByEmail ו‑SignedPdf (שדה PrivateFile, חוזר ב‑Get-Data כ‑resource_link עם URI מסוג file-storage:///…/PriceQuotes/<id>/SignedPdf — ראו המשאב get-file).
3 · שורות חוזרות — data-repeat
Section titled “3 · שורות חוזרות — data-repeat”התכונה יושבת על ה‑<tr>. לא על ה‑<table> ולא על ה‑<td>:
<table style="width:100%; border-collapse:collapse;"> <tr class="brand-thead"> <td>מוצר</td><td>תיאור</td><td>כמות</td><td>מחיר ליחידה</td><td>סה"כ</td> </tr> <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></table>מופיע רק מוצר אחד? כמעט תמיד ה‑data-repeat הודבק על האלמנט הלא נכון. שתי שורות SaleRows ⇒ שני <tr data-repeat="SaleRows"> בפלט, כל אחד עם הערכים של השורה שלו (הסדר אינו בהכרח סדר היצירה). מכירה בלי שורות ⇒ הטבלה נשארת עם כותרת בלבד, בלי שגיאה.
4 · אין <script> בתבנית
Section titled “4 · אין <script> בתבנית”ה‑placeholders
Section titled “ה‑placeholders”סוגריים כפולים. זה מנוע שונה לגמרי מזה של הטריגרים וההודעות, שמשתמש בסוגריים משולשים.
| הרמה | Placeholders | מה חוזר בפועל |
|---|---|---|
| ההצעה עצמה | {{number}} · {{date}} · {{Vat}} · {{totalIncludingVat}} |
10017 (מספר רץ) · 23-08-2026 (DD‑MM‑YYYY) · 180.00 — סכום המע“מ, לא אחוז · 1180.00 |
| המכירה | {{Sales.Total}} · {{Sales.TotalBeforeDiscount}} · {{Sales.DiscountValue}} |
הערכים כפי שהם ברשומה, בלי עיצוב (1000, 1100, 100) |
| הלקוח (דרך Pointer) | {{Sales.AccountId.Name}} · {{Sales.AccountId.Address}} · {{Sales.AccountId.PhoneNumber}} · {{Sales.AccountId.Email}} |
כל שדה של Accounts לפי שמו בסכימה. Phone שבתיאור הכלי אינו שדה במערכת vanilla — השדה הוא PhoneNumber, ו‑{{Sales.AccountId.Phone}} מודפס ריק |
| שורת מוצר | {{SaleRows.ProductId.Name}} · {{SaleRows.Description}} · {{SaleRows.Quantity}} · {{SaleRows.PricePerUnit}} · {{SaleRows.Total}} |
שורה לכל רשומת SaleRows של המכירה |
הכלל: כל placeholder הוא שם שדה בסכימה (או מסלול דרך Pointer), וכל מה שלא קיים מודפס ריק — לכן Get-Schema על Sales ועל Accounts לפני שכותבים תבנית. {{Sales.Probability}}, {{Sales.ReasonForLost}}, {{Sales.NextStepDate}} קיימים ויעבדו; IsWon / IsLost אינם שדות של Sales במערכת vanilla (הסטטוס הוא SaleStatusId).
שדות קלט שכותבים בחזרה
Section titled “שדות קלט שכותבים בחזרה”<input> ששמו מתחיל ב‑Accounts. או ב‑Sales. נשמר בחזרה לרשומה כשהלקוח שולח את המסמך החתום:
<input name="Accounts.Address" type="text" /><input name="Sales.Comment" type="text" />Accounts.Address ו‑Accounts.City נכתבים ל‑Accounts, Sales.Comment נכתב ל‑Sales, ו‑input בשם אחר (למשל FreeText) לא נשמר בשום מקום. הכתיבה מתבצעת רק כחלק מהחתימה — לא בצפייה במסמך.
שני פרטים: value="{{…}}" על ה‑input לא מונע את השמירה — הערך החדש נשמר — אלא רק מציג את הערך הנוכחי כברירת מחדל; ושם השדה אחרי הקידומת חייב להיות שם שדה אמיתי בסכימה של Accounts / Sales — קחו אותו מ‑Get-Schema.
צבעים ב‑PDF
Section titled “צבעים ב‑PDF”| הנושא | הכלל |
|---|---|
| מיקום ב‑RTL | ה‑<td> הראשון בשורה מרונדר מימין — הלוגו בתא הראשון |
| גודל | width: 240px; height: auto. לא max-width / max-height — הם מרנדרים לוגו זעיר כשל‑PNG יש שוליים שקופים |
| הקובץ | חתכו את השוליים השקופים לפני העלאה |
| העלאה | Upload-Public-File, ומשם ה‑URL לתוך ה‑HTML |
Create-Price-Quote
Section titled “Create-Price-Quote”מפיק מסמך ממכירה קיימת.
| הפרמטר | טיפוס | חובה | המשמעות |
|---|---|---|---|
saleId |
String | ✔ | מזהה רשומת ה‑Sales. המכירה חייבת להתקיים |
templateId |
String | ✔ | מזהה התבנית מ‑Get-Price-Quote-Templates |
status |
Enum | ✔ | אחד מארבעה, ראו למטה |
includeVAT |
Boolean | ברירת מחדל true. עם false: vat: 0 ו‑{{Vat}} מודפס 0.00 |
|
siteId |
String | מזהה האתר (siteId מ‑Get-Sites). ראו למטה |
{ "saleId": "V0sVNyS45K", "templateId": "pdft012345", "status": "טיוטה", "includeVAT": true }התשובה:
{ "objectId": "91ksfWWkpM", "link": "https://<sub>.mbapps.co.il/apps/mybusiness/PriceQuoteSign?oid=91ksfWWkpM", "total": 1000, "totalWithVat": 1180, "vat": 180 }objectId הוא רשומה חדשה ב‑PriceQuotes (עם Number רץ, Content — ה‑HTML הממוזג, ו‑Pointers ל‑SaleId, AccountId, TemplateId, StatusId). saleId או templateId שאינם קיימים ⇒ Error: Object not found.. הכלי אינו בודק שהתבנית היא מסוג “הצעות מחיר” — תבנית Invoice של MyBooks מתקבלת ומופקת כהצעה.
ה‑enum של הסטטוסים — ארבע מחרוזות עבריות מדויקות
Section titled “ה‑enum של הסטטוסים — ארבע מחרוזות עבריות מדויקות”| הערך | המשמעות |
|---|---|
טיוטה |
טיוטה |
נשלחה - בהמתנה לאישור |
נשלחה, ממתינה לאישור הלקוח. הסטטוס היחיד שבו קישור החתימה נפתח ללא התחברות |
בוטלהמושהית |
בוטלה / מושהית |
אושרה |
אושרה |
siteId — פרמטר אופציונלי
Section titled “siteId — פרמטר אופציונלי”הפרמטר מופיע בסכימה החיה של הכלי ואינו חובה. הערך הוא ה‑siteId שמחזיר Get-Sites (מחרוזת hex של 24 תווים); עם הערך התקין ההצעה מופקת בדיוק כמו בלעדיו — במערכת עם אתר אחד אין לו השפעה נראית.
תקלות נפוצות — טבלת אבחון
Section titled “תקלות נפוצות — טבלת אבחון”| התסמין | הבדיקה הראשונה |
|---|---|
| המסמך “עובד במסך” אבל ה‑PDF שונה | חפשו <script ב‑HTML של התבנית והסירו הכול — JS רץ רק בדפדפן |
| בלוק החתימה מוצג לפני שחתמו | id="sigDiv" ושלושת המזהים הפנימיים — בדיוק כך |
| ה‑PDF יוצא בלי צבעים, המסך תקין | חסר בלוק @media print עם !important |
| אין צבע גם במסך | חסר style inline (צריך גם מחלקה וגם inline) |
| מוצג רק מוצר אחד | data-repeat="SaleRows" לא על ה‑<tr> |
| טבלת המוצרים ריקה | למכירה אין רשומות SaleRows |
| ערך חסר במסמך (תווית בלי ערך) | שגיאת כתיב במסלול · שדה שאינו בסכימה (למשל Phone במקום PhoneNumber) · השדה ריק ברשומה |
מודפס {ערך} עם סוגריים |
סוגריים משולשים במקום כפולים |
Error: Object not found. |
saleId / templateId / objectId שאינו קיים |
Cannot read properties of undefined (reading 'includes') |
siteId שגוי — השמיטו אותו |
| הלוגו זעיר או הכותרת ענקית | PNG עם שוליים שקופים · max-width במקום width |
Get-Data על PDFTemplate חוזר בלי HTML |
הוסיפו HTML ל‑keys, או הורידו את הפרמטר |
| הלקוח רואה “המסמך לא נמצא” | ההצעה אינה בסטטוס נשלחה - בהמתנה לאישור — רק בו הקישור נפתח ללא התחברות (בגרסאות שרת ישנות נדרש login בכל סטטוס) |
- כלי קבצים — העלאת הלוגו וקריאת ה‑PDF שנוצר
- כלי נתונים — קריאה וכתיבה של
PDFTemplateושלSales - אינדקס הכלים המלא
- שרת ה‑MCP — ההבדל בין סוגריים כפולים למשולשים