App Logo The Malt Miller to Brewfather Sync

Extract ingredients from Malt Miller invoices and sync with your Brewfather inventory

⚠️ IMPORTANT: A premium Brewfather account is required for this app to work.

Upload PDF
Parse Invoice
Match & Sync
Error! {{ error }}
Success! {{ success }}

Upload Malt Miller Invoice

Drag and drop your Malt Miller PDF invoice here, or click to browse

Processing invoice...

Invoice Analysis

Invoice Number

{{ invoiceData?.invoice?.invoiceNumber || 'N/A' }}

Total Items

{{ invoiceData?.summary?.totalItems || 0 }}

Invoice Total

£{{ invoiceData?.summary?.totalCost?.toFixed(2) || '0.00' }}

Items total: £{{ invoiceData?.summary?.calculatedTotal?.toFixed(2) || '0.00' }}
Difference may include VAT, shipping, or non-brewing items

Categories

{{ Object.keys(invoiceData?.summary?.byType || {}).length }}

Ingredients by Category

{{ type }}s

{{ data.count }} items

£{{ data.totalCost.toFixed(2) }}

Cost Breakdown

Items Total: £{{ invoiceData.summary.calculatedTotal?.toFixed(2) || '0.00' }}
VAT: £{{ invoiceData.summary.vat?.toFixed(2) }}
Shipping: £{{ invoiceData.summary.shipping?.toFixed(2) }}
Other/Discounts: £{{ invoiceData.summary.breakdown.other?.toFixed(2) }}

Invoice Total: £{{ JSON.stringify(invoiceData) }}
Note: £{{ invoiceData.summary.costDiscrepancy?.toFixed(2) }} difference may be due to rounding, discounts, or non-brewing items not captured.

Brewfather Integration

Brewfather API Credentials

Credentials loaded from storage
Credentials saved locally in your browser
Security: Credentials are stored locally in your browser only and never sent to external servers except Brewfather API.

Ingredient Matching Analysis

Analyzing which ingredients match your existing Brewfather inventory...

Matching Results

Exact Matches

{{ matchSummary.exactMatches }}

Ready to sync

Partial Matches

{{ matchSummary.partialMatches }}

Verify before sync

No Matches

{{ matchSummary.noMatches }}

Add manually first

{{ ingredient.name }}

{{ ingredient.type }} • {{ ingredient.amount }} {{ ingredient.type === 'misc' ? 'item' : ingredient.unit }} • £{{ ingredient.cost?.toFixed(2) || '0.00' }}/{{ ingredient.type === 'misc' ? 'item' : ingredient.unit }}

Exact Match Partial Match No Match Synced
Brewfather: {{ ingredient.brewfatherMatch.name }} (Current: {{ JSON.stringify(ingredient.brewfatherMatch.inventory)}}) → New: {{ ingredient.newInventoryAmount }} {{ ingredient.brewfatherMatch.inventory?.unit || ingredient.unit }}
Partial Match: Please verify this ingredient matches correctly before syncing.

Brewfather Sync Results

Summary

{{ getSyncSummary().success }}
Updated
{{ getSyncSummary().notFound }}
Not Found
{{ getSyncSummary().errors }}
Errors

{{ type }}s ({{ Array.isArray(results) ? results.length : 0 }})

{{ result.name }}
{{ result.currentAmount }} → {{ result.newAmount }} {{ result.unit || '' }} (+{{ result.adjustedBy || 0 }}) +{{ result.adjustedBy }} {{ result.unit || '' }} added Updated
{{ result.name }}
Not in Brewfather
{{ result.name }}
{{ result.error || 'Error' }}

Next Steps

Items marked as "Not in Brewfather" need to be added to your Brewfather inventory first. You can add them manually through the Brewfather web app, then run the sync again to update quantities.