📊 กราฟแสดงสัดส่วนแหล่งที่มารายได้ (Income Share)
📊 กราฟแสดงสัดส่วนรายจ่ายตามหมวดหมู่ (Expense Share)
📅 สรุปผลการดำเนินงานรายเดือน (บาท) ปี: ทั้งหมด
รายได้รวม
รายจ่ายรวม
กำไรสุทธิ
เดือน รายได้รวม (บาท) รายจ่ายรวม (บาท) กำไรสุทธิ (บาท) อัตรากำไร (%)
🛡️ การเฝ้าระวังเกณฑ์ภาษี VAT (1.8 ล้านบาท) & ค่าเฉลี่ย
สถานะภาษี VAT: ✅ ปกติ ไม่เข้าเกณฑ์ VAT
ยอดรายได้สะสม: 0.00 บาท เพดาน VAT: 1,800,000.00 บาท (0.00%)
คงเหลืออีก 1,800,000.00 บาท ก่อนถึงเกณฑ์จด VAT ภาษีหัก ณ ที่จ่าย (WHT 3%) สะสม: 0.00 บาท
🎯 เป้ารายได้ต่อเดือน: 100,000.00 ฿
เฉลี่ยเดือนละ 0.00 ฿ 0.00%
📣 ความคุ้มค่างบยิงแอด (ROAS) 🛒 หมวดขายดี: -
ไม่มีรายจ่ายค่าแอด
งบโฆษณารวม: 0.00 ฿ (0.00% ของรายได้)
รายได้เฉลี่ยต่อเดือน
0.00 ฿
ค่าใช้จ่ายคอนเทนต์เฉลี่ย/เดือน
0.00 ฿
กำไรสุทธิเฉลี่ยต่อเดือน
0.00 ฿
ความคุ้มค่าต้นทุนคอนเทนต์ (ROI)
0.00 เท่า

📌 ตารางสัดส่วนแหล่งที่มารายได้ & แยกตามเพจ/ช่องทาง

แหล่งที่มา / เพจ / ช่องทาง จำนวนเงิน (บาท) สัดส่วน (%)
📊 ตารางเปรียบเทียบรายปี (Yearly Comparison)
ปี (ค.ศ.) รายได้สุทธิรวม (บาท) รายจ่ายสุทธิรวม (บาท) กำไรสุทธิ (บาท) อัตรากำไร (%)
🧾 ตารางสรุปรายจ่ายแยกตามหมวดหมู่ (Expense Breakdown)
หมวดหมู่รายจ่าย จำนวนเงิน (บาท) สัดส่วน (%)
➕ ฟอร์มกรอกรายการใหม่ (หรือคลิกกรอก/เลือกดรอปดาวน์ในตารางด้านล่างได้โดยตรง)
📋 ตารางกรอกรายรับ-รายจ่าย (ทุกช่องเชื่อมโยงกับแดชบอร์ดทั้ง 6 บล็อก, ภาษี VAT และตารางสรุปแบบ Real-time)
☑️ เลือกอยู่ 0 รายการ
# วันที่ เดือน ปี รายการ ชื่อเพจ / ช่องทาง หมวดหมู่ บัญชี รายได้ FB รายได้ Affiliate รายได้รวม รายจ่าย กำไรสุทธิ เอกสาร / ใบเสร็จ ตรวจสลิป หมายเหตุ หมวด Affiliate WHT 3% จัดการ
แสดง 0 จาก 0 รายการ
หน้า 1 / 1
⚙️ จัดการลิสต์หัวข้อดรอปดาวน์ทั้งหมด & สำรองข้อมูล (เพิ่ม / แก้ไข / ลบได้ทุกจุด ไม่ฟิกค่า)
📦 สถานะความจุพื้นที่จัดเก็บข้อมูลบนเว็บ (LocalStorage + IndexedDB Backup) กำลังคำนวณ...
📘 ชื่อเพจ / ช่องทาง
    💰 หมวดหมู่รายรับ
      🧾 หมวดหมู่รายจ่าย
        🛒 หมวดหมู่สินค้า Affiliate
          🏦 ช่องทางเงิน / บัญชี
            📄 สถานะเอกสาร / ใบเสร็จ
              ☁️ เชื่อมต่อ Google Apps Script เพื่อซิงก์ข้อมูลเข้า Google Sheets อัตโนมัติ ยังไม่มีประวัติการซิงก์
              📄 เปิดไฟล์ Google Sheets ต้นฉบับ

              🛠️ โค้ด Google Apps Script (Code.gs) สำหรับนำไปวางใน Google Sheets

              /**
               * Google Apps Script สำหรับเชื่อมต่อกับเว็บแอป index.html (FB & Affiliate Tracker)
               */
              const SHEET_ID = '1HODr9FK8qSeicKon313Hf8tJRoqNReDhI74j0F0xAdI';
              
              function getTargetSpreadsheet() {
                try {
                  return SpreadsheetApp.getActiveSpreadsheet() || SpreadsheetApp.openById(SHEET_ID);
                } catch (e) {
                  return SpreadsheetApp.openById(SHEET_ID);
                }
              }
              
              function doGet(e) {
                const ss = getTargetSpreadsheet();
                const dataSheet = ss.getSheetByName('Data');
                const transactions = [];
              
                if (dataSheet && dataSheet.getLastRow() >= 2) {
                  const values = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 18).getValues();
                  for (let i = 0; i < values.length; i++) {
                    const r = values[i];
                    if (!r[0] || String(r[0]).toLowerCase() === 'total') continue;
                    let dateStr = '';
                    if (r[1] instanceof Date) {
                      dateStr = Utilities.formatDate(r[1], Session.getScriptTimeZone(), 'yyyy-MM-dd');
                    } else if (r[1]) {
                      dateStr = String(r[1]).slice(0, 10);
                    }
                    transactions.push({
                      id: Number(r[0]) || (transactions.length + 1),
                      date: dateStr,
                      month: String(r[2] || ''),
                      year: Number(r[3]) || new Date().getFullYear(),
                      title: String(r[4] || ''),
                      page: String(r[5] || ''),
                      category: String(r[6] || ''),
                      account: String(r[7] || ''),
                      fbIncome: Number(r[8]) || 0,
                      affIncome: Number(r[9]) || 0,
                      expense: Number(r[11]) || 0,
                      docStatus: String(r[13] || ''),
                      verified: Boolean(r[14] === true || String(r[14]).toUpperCase() === 'TRUE'),
                      note: String(r[15] || ''),
                      affCategory: String(r[16] || ''),
                      wht: Number(r[17]) || 0
                    });
                  }
                }
              
                return ContentService.createTextOutput(JSON.stringify({
                  status: 'ok',
                  transactions: transactions,
                  syncedAt: new Date().toISOString()
                })).setMimeType(ContentService.MimeType.JSON);
              }
              
              function doPost(e) {
                try {
                  const payload = JSON.parse(e.postData.contents);
                  const ss = getTargetSpreadsheet();
                  let dataSheet = ss.getSheetByName('Data');
                  if (!dataSheet) dataSheet = ss.insertSheet('Data');
              
                  const headers = [
                    'ลำดับ', 'วันที่', 'เดือน', 'ปี', 'รายการ', 'ชื่อเพจ / ช่องทาง', 'หมวดหมู่',
                    'ช่องทางเงิน / บัญชี', 'รายได้สุทธิ\nเนื้อหา FB', 'รายได้สุทธิ\nAffiliate',
                    'รายได้สุทธิ\nรวม', 'รายจ่าย', 'กำไรสุทธิ', 'เอกสาร /\nใบเสร็จ',
                    'ตรวจสลิปแล้ว', 'หมายเหตุ', 'หมวดสินค้า Affiliate', 'ภาษีหัก ณ ที่จ่าย (WHT 3%)'
                  ];
              
                  dataSheet.getRange(1, 1, 1, headers.length).setValues([headers]);
                  if (dataSheet.getLastRow() > 1) {
                    dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 18).clearContent();
                  }
              
                  const txList = payload.transactions || [];
                  if (txList.length > 0) {
                    const rows = txList.map((t, idx) => {
                      const rowNum = idx + 2;
                      return [
                        t.id || (idx + 1),
                        t.date || '',
                        t.month || '',
                        t.year || '',
                        t.title || '',
                        t.page || '',
                        t.category || '',
                        t.account || '',
                        Number(t.fbIncome) || 0,
                        Number(t.affIncome) || 0,
                        `=I${rowNum}+J${rowNum}`,
                        Number(t.expense) || 0,
                        `=K${rowNum}-L${rowNum}`,
                        t.docStatus || '',
                        Boolean(t.verified),
                        t.note || '',
                        t.affCategory || '',
                        Number(t.wht) > 0 ? Number(t.wht) : ''
                      ];
                    });
              
                    dataSheet.getRange(2, 1, rows.length, 18).setValues(rows);
              
                    const lastRow = rows.length + 1;
                    const totalRowNum = rows.length + 2;
                    const totalRow = [
                      'Total', '', '', '', '', '', '', '',
                      `=SUM(I2:I${lastRow})`, `=SUM(J2:J${lastRow})`, `=SUM(K2:K${lastRow})`,
                      `=SUM(L2:L${lastRow})`, `=SUM(M2:M${lastRow})`, '', '', '', '', ''
                    ];
                    dataSheet.getRange(totalRowNum, 1, 1, 18).setValues([totalRow]);
                  }
              
                  return ContentService.createTextOutput(JSON.stringify({
                    status: 'ok',
                    count: txList.length,
                    syncedAt: new Date().toISOString()
                  })).setMimeType(ContentService.MimeType.JSON);
                } catch (err) {
                  return ContentService.createTextOutput(JSON.stringify({
                    status: 'error',
                    message: err.toString()
                  })).setMimeType(ContentService.MimeType.JSON);
                }
              }