distil/artifice/billing/csv_invoice.py

112 lines
3.7 KiB
Python

import os
from csv import writer
from artifice import invoice
# from artifice import clerk_mixins
import yaml
from decimal import *
class Csv(invoice.RatesFileMixin, invoice.Invoice):
def __init__(self, tenant, start, end, config):
self.config = config
self.tenant = tenant
self.lines = {}
self.closed = False
self.start = start
self.end = end
self.total = Decimal(0.0)
def bill(self):
# Usage is one of VMs, Storage, or Volumes.
for element in self.tenant.resources.values():
print " * " + element.metadata['type']
print " - resource id: " + str(element.id)
self.add_line(element.metadata['type'], [element.id])
appendee = []
appendee2 = []
for key, value in element.metadata.iteritems():
print " - " + key + ": " + str(value)
appendee.append(key + str(":"))
appendee2.append(value)
self.add_line(element.metadata['type'], appendee)
self.add_line(element.metadata['type'], appendee2)
total_cost = Decimal(0.0)
appendee = ["service:", "usage:", "rate:", "cost:"]
self.add_line(element.metadata['type'], appendee)
for strategy in element.usage_strategies.values():
appendee = []
cost = Decimal(0.0)
usage = Decimal(strategy.volume)
# GET REGION FROM CONFIG:
region = 'wellington'
rate = self.rate(strategy.service, region)
cost = usage * rate
total_cost += cost
appendee.append(strategy.service)
appendee.append(usage)
appendee.append(rate)
appendee.append(round(cost, 2))
print " - " + strategy.service + ": " + str(usage)
print " - rate: " + str(rate)
print " - cost: " + str(round(cost))
self.add_line(element.metadata['type'], appendee)
appendee = ["total cost:", round(total_cost, 2)]
self.add_line(element.metadata['type'], appendee)
print " - total cost: " + str(round(total_cost))
self.add_line(element.metadata['type'], [])
self.total += total_cost
def add_line(self, el_type, line):
if not self.closed:
try:
self.lines[el_type].append(line)
except KeyError:
self.lines[el_type] = [line]
return
raise AttributeError("Can't add to a closed invoice")
@property
def filename(self):
fn_dict = dict(tenant=self.tenant.name, start=self.start,
end=self.end)
fn = os.path.join(
self.config["output_path"],
self.config["output_file"] % fn_dict
)
return fn
def close(self):
try:
open(self.filename)
raise RuntimeError("Can't write to an existing file!")
except IOError:
pass
fh = open(self.filename, "w")
csvwriter = writer(fh, dialect='excel', delimiter=',')
csvwriter.writerow(["", "from", "until"])
csvwriter.writerow(["usage range: ", str(self.start), str(self.end)])
csvwriter.writerow([])
for key in self.lines:
for line in self.lines[key]:
csvwriter.writerow(line)
csvwriter.writerow([])
# write a blank line
csvwriter.writerow([])
# write total
csvwriter.writerow(["invoice total cost: ", round(self.total, 2)])
fh.close()
self.closed = True