Week 8 • Module 15

Practical Example: CSV Export

Map/Reduce script that generates CSV files and emails them

🎯 Project Overview

Build a Map/Reduce script that:

📋 Stage 1: getInputData

function getInputData(context) {
    const runtime = require('N/runtime');
    
    // Load saved search from script parameter
    const searchId = runtime.getCurrentScript().getParameter({
        name: 'custscript_customer_search'
    });
    
    return search.load({ id: searchId });
}

💡 Script Parameters

Using a script parameter for the saved search ID makes the script flexible—administrators can change which customers are processed without modifying code.

🔄 Stage 2: map

function map(context) {
    const query = require('N/query');
    const customerId = context.value;
    
    // Query transactions for this customer
    const results = query.runSuiteQL({
        query: `
            SELECT tranid, trandate, total
            FROM transaction
            WHERE entity = ?
            AND type = 'SalesOrd'
        `,
        params: [customerId]
    }).asMappedResults();
    
    // Format as CSV line and write to reduce
    results.forEach(txn => {
        const csvLine = [customerId, txn.tranid, txn.trandate, txn.total].join(',');
        context.write({
            key: 'csv',
            value: csvLine
        });
    });
}

📊 Stage 3: reduce

function reduce(context) {
    const file = require('N/file');
    const email = require('N/email');
    
    // Collect all CSV lines
    const header = 'Customer ID,Order Number,Date,Total';
    const lines = context.values;
    const csvContent = header + '\n' + lines.join('\n');
    
    // Create CSV file
    const csvFile = file.create({
        name: 'customer_transactions.csv',
        fileType: file.Type.CSV,
        contents: csvContent,
        folder: 12345  // File Cabinet folder ID
    });
    csvFile.save();
    
    // Email with attachment
    email.send({
        author: 207,
        recipients: 'admin@company.com',
        subject: 'Daily Transaction Report',
        body: 'Please find the attached report.',
        attachments: [csvFile]
    });
}

📝 Stage 4: summarize

function summarize(context) {
    // Log any errors
    context.mapSummary.errors.iterator().each((key, error) => {
        log.error('Map Error', error);
        return true;
    });
    
    log.audit('Complete', 'CSV export finished');
}

📖 Finding This in the Docs

This capstone combines multiple modules. Key references:

  1. Map/Reduce Script Type → getInputData, map, reduce, summarize stages
  2. N/query Module → runSuiteQL() for transaction queries
  3. N/file Module → file.create() for CSV generation
  4. N/email Module → email.send() with attachments

Key pages to bookmark:

🎯 Key Takeaways