Index: treasury/finance_core/models.py
===================================================================
--- treasury/finance_core/models.py	(revision 169d7b5505d576fd5ca93dab4f665456a0caf731)
+++ treasury/finance_core/models.py	(revision 52c3467bd648ca1c97ed2de96a9dc11df2b2c16e)
@@ -85,4 +85,80 @@
 
 
+class Transaction(models.Model):
+    name = models.CharField(max_length=40)
+    desc = models.TextField(blank=True)
+
+    def __unicode__(self,):
+        return self.name
+
+def make_transfer(name, amount,
+    layer, budget_term, from_area, to_area, desc, ):
+    tx = Transaction(
+        name=name,
+        desc=desc,
+    )
+    tx.save()
+
+    from_li = LineItem(
+        label='Send: %s' % (name, ),
+        amount=-amount,
+        budget_area=from_area,
+        budget_term=budget_term,
+        layer=layer,
+        tx=tx,
+    )
+    from_li.save()
+
+    to_li = LineItem(
+        label='Receive: %s' % (name, ),
+        amount=amount,
+        budget_area=to_area,
+        budget_term=budget_term,
+        layer=layer,
+        tx=tx,
+    )
+    to_li.save()
+
+    return tx
+
+
+class LineItem(models.Model):
+    tx = models.ForeignKey(Transaction)
+    amount = models.DecimalField(max_digits=7, decimal_places=2, help_text='Do not include "$"')
+    label = models.CharField(max_length=40)
+    budget_area = models.ForeignKey(BudgetArea)
+    budget_term = models.ForeignKey(BudgetTerm)
+    layer = models.IntegerField() # this might actually be a Transaction property...
+
+    def layer_string(self,):
+        layer = self.layer
+        return layer_name(get_layer_by_num(layer))
+
+    def __unicode__(self, ):
+        return "%s: %s: $%s (%s) in %s during %s" % (
+            self.tx, self.label, self.amount, self.layer,
+            self.budget_area, self.budget_term, )
+
+
+layers=(
+    (10, 'budget'),
+    (20, 'allocation'),
+    (30, 'expenditure'),
+    (40, 'closeout'),
+)
+def get_layer_by_name(name):
+    for layer in layers:
+        if name == layer[1]:
+            return layer
+    raise KeyError, "layer %s not found" % (name, )
+def get_layer_by_num(num):
+    for layer in layers:
+        if num == layer[0]:
+            return layer
+    raise KeyError, "layer %d not found" % (num, )
+def layer_name(layer): return layer[1]
+def layer_num(layer):  return layer[0]
+
+
 def coerce_full_email(email):
     if '@' in email: return email
Index: treasury/vouchers/import_budget.py
===================================================================
--- treasury/vouchers/import_budget.py	(revision 7874f6a11f045157180ef05fa8b95e02b84c61ac)
+++ treasury/vouchers/import_budget.py	(revision 52c3467bd648ca1c97ed2de96a9dc11df2b2c16e)
@@ -4,6 +4,10 @@
 import subprocess
 import vouchers.models
-from vouchers.models import BudgetArea
-from vouchers.models import coerce_full_email
+import finance_core.models
+from finance_core.models import BudgetArea
+from finance_core.models import coerce_full_email
+from finance_core.models import Transaction
+from finance_core.models import get_layer_by_name, layer_num
+from decimal import *
 
 columns = ['comm_name','priority','expense_type','start_date','end_date','project','item_name','desc','people','count','costitem','subtotal','per_person','email_list']
@@ -14,8 +18,8 @@
     reader = csv.reader(infile)
     for comm in reader:
-        email_list,chair_list,name,prefer_chair,area = comm
+        email_list,chair_list,name,prefer_chair,area,account = comm
         if prefer_chair=='yes': prefer_chair = True
         else: prefer_chair = False
-        committees[email_list] = { 'email_list': email_list, 'chair_list': chair_list, 'name': name, 'prefer_chair':prefer_chair, 'area':area}
+        committees[email_list] = { 'email_list': email_list, 'chair_list': chair_list, 'name': name, 'prefer_chair':prefer_chair, 'area':area, 'account':account}
     return committees
 
@@ -60,13 +64,17 @@
     for comm in committees.values():
         parent = parents[comm['area']]
-        parent.add_child(
-            name=comm['name'],
-            owner=coerce_full_email(comm['chair_list']),
-            interested=coerce_full_email(comm['email_list']),
-            use_owner=comm['prefer_chair'],
-            always=True,
-        )
+        if len(parent.get_children().filter(name=comm['name'])) > 0:
+            pass
+        else:
+            parent.add_child(
+                name=comm['name'],
+                owner=coerce_full_email(comm['chair_list']),
+                interested=coerce_full_email(comm['email_list']),
+                use_owner=comm['prefer_chair'],
+                always=True,
+            )
     return (depth+1, )
 
+budget_layer = layer_num(get_layer_by_name('budget'))
 def do_process_rows(committees, budget, term, depth):
     reader = csv.reader(budget)
@@ -105,4 +113,9 @@
             else: line_item_obj = line_items[0]
             line_item_obj.mark_used(term)
+            amount = Decimal(subtotal.replace('$', '').replace(',', ''))
+            finance_core.models.make_transfer(
+                item_name, amount, budget_layer,
+                term, budget_source, line_item_obj, desc=desc)
+
 
 def main(committees_file, budget_file, term_name, ):
