Last active
August 29, 2015 14:06
-
-
Save vsanjuan/ae162a2c91213651109b to your computer and use it in GitHub Desktop.
Product cost on ZODB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from persistent import Persistent | |
import transaction | |
import ZODB | |
import ZODB.FileStorage | |
class Product(Persistent): | |
"""Models a product composition by listing the materials and activities | |
needed to produce it. | |
Attributes: | |
Code: A key that uniquely identifies the product. | |
Name: Name of the product. | |
Materials: List of materials, and amounts needed to make the product. | |
Activities: List of activities and its consumption needed to make the product. | |
""" | |
def __init__(self, code, name, description, base_unit): | |
"""Creates a new product""" | |
self.code = code | |
self.name = name | |
self.description = description | |
self.billofmaterials = {} | |
self.billofactivities = {} | |
def addMaterial(self, material_code, consumption, consumption_unit, | |
production_ratio, production_unit, waste, cost_per_unit= 0 ): | |
''' Adds a new material to the product list and the information related | |
to the consumption to the F.P. production the parameters are the following: | |
material_code : Code of the material to be consumed. | |
consumption: Amount of material consumed. | |
consumption_unit: Unit in which the consumption amount is expressed. | |
production_ratio: Units of F.P. to which the consumption is referred. | |
production_unit : Unit of production to which the production ratio is related. | |
waste: % of the material thrown to the waste. | |
''' | |
self.billofmaterials[material_code] = {'material_code': material_code, | |
'consumption': consumption, | |
'consumption_unit' : consumption_unit, | |
'production_unit': production_unit, | |
'production_ratio': production_ratio, | |
'waste' : waste, | |
'cost_per_unit': cost_per_unit} | |
# self.billofmaterials._p_changed = True | |
self._p_changed = True | |
def addActivity(self, activity_code, consumption, activity_unit, | |
production_ratio, production_unit, cost_per_unit = 0): | |
"""Adds a new activity in the product list needed to make the product and | |
the information related with the consumption for each unit on F.P. | |
Parameters: | |
consumption: Amount of activity consumed. | |
activiy_unit: Unit in which the consumption amount is expressed. | |
production_ratio: Units of F.P. to which the consumption is referred. | |
production_unit : Unit of production to which the production ratio is related. | |
""" | |
self.activities[activity_code] = { 'activity_code': activity_code, | |
'consumption': consumption, | |
'activity_unit': activity_unit, | |
'production_ratio': production_ratio, | |
'production_unit': production_unit, | |
'cost_per_unit' : cost_per_unit } | |
self.billofactivities._p_changed = True | |
self._p_changed = True | |
def CalculateCost(self, productcode): | |
"""Calculates the direct product cost based on materials and activities consumption. | |
This function doesn't check yet: | |
A. Consumption units and price units for the activities are homogeneous. | |
B. production ratios per unit of output are homogeneous among the activities. | |
Parameters: | |
Product code | |
Returns two values: | |
1. Total material cost. | |
2. Total activity cost. | |
""" | |
# Recovers the information about activities and materials needed to calculate the cost | |
# Maybe it would be better to filter the activities and materials in the bill of materials | |
# and bill of activities. I will implement this later if too many materials or activities | |
# are loaded in memory. | |
activitytrax = ActivityTrax().activities | |
materialtrax = MaterialTrax().materials | |
material_cost = 0 | |
activity_cost = 0 | |
for materialcode, material_usage in self.billofmaterials: | |
material_cost += materialtrax[material_code].cost_per_product(material_usage.consumption) | |
return material_cost, activity_cost | |
def __str__(self): | |
pass | |
class Activity(Persistent): | |
def __init__(self, code, name, description, cost_per_unit, activity_unit): | |
self.code = code | |
self.name = name | |
self.description = description | |
self.cost_per_unit = cost_per_unit | |
self.activity_unit = activity_unit | |
def cost_per_product(self, product, consumption): | |
return consumption * self.cost_per_unit | |
def __str__(self): | |
return ("Activity Code: %s, Name: %s,\n Description: %s,\n Cost per unit: %s\n Base unit: %s" | |
% (self.code, self.name, self.description, self.cost_per_unit, self.activity_unit)) | |
class Material(Persistent): | |
def __init__(self, code, name, description, cost_per_unit, base_unit): | |
self.code = code | |
self.name = name | |
self.description = description | |
self.cost_per_unit = cost_per_unit | |
self.base_unit = base_unit | |
def cost_per_product(self, consumption): | |
return consumption * self.cost_per_unit | |
def __str__(self): | |
return ("Material Code: %s, Name: %s,\n Description: %s,\n Cost per unit: %s\n Base unit: %s" | |
% (self.code, self.name, self.description, self.cost_per_unit, self.base_unit)) | |
class Trax(object): | |
db = ZODB.DB(ZODB.FileStorage.FileStorage("products.fs")) | |
connection = db.open() | |
root = connection.root() | |
def __init__(self, intro = "Product trax product tracking helper", | |
db_path="products.fs"): | |
self.intro = intro | |
class ProductTrax(Trax): | |
def __init__(self, intro = "Product trax tracking helper", | |
db_path="products.fs"): | |
Trax.__init__(self) | |
if 'products' in self.root: | |
self.products = self.root['products'] | |
else: | |
self.products = self.root['products'] = {} | |
def addProduct(self, code, name, description, base_unit): | |
product = Product( code, name, description, base_unit) | |
self.products[code] = product | |
transaction.commit() | |
def addActivity(self, product_code, activity_code, consumption, activity_unit, | |
production_ratio, production_unit, cost_per_unit = 0): | |
self.products[product_code].addActivity( activity_code, consumption, activity_unit, | |
production_ratio, production_unit, cost_per_unit = 0) | |
def addMaterial(self, product_code, material_code, consumption, consumption_unit, | |
production_ratio, production_unit, waste, cost_per_unit= 0 ): | |
print "From ProductTrax addMaterial product name: exit" | |
print self.products[product_code].name | |
self.products[product_code].addMaterial( material_code, consumption, consumption_unit, | |
production_ratio, production_unit, waste, cost_per_unit= 0 ) | |
def list_products(self): | |
print "Product Title" | |
print "======= =====" | |
for name, product in self.products.items(): | |
print "%-20s%s" % (name, product.description) | |
def list_materials(self, productcode): | |
print "Product: %s" % productcode | |
print " Material" | |
print "=========" | |
for productcode, product in self.products[productcode].materials.items(): | |
print product.name | |
class MaterialTrax(Trax): | |
def __init__(self, intro = "Material trax tracking helper", | |
db_path="products.fs"): | |
Trax.__init__(self) | |
if 'materials' in self.root: | |
self.materials = self.root['materials'] | |
else: | |
self.materials = self.root['materials'] = {} | |
def addMaterial(self, code, name, description, base_unit): | |
material = Material( code, name, description, base_unit) | |
print self.materials.items() | |
self.materials[code] = material | |
transaction.commit() | |
class ActivitiyTrax(Trax): | |
def __init__(self, intro = "Material trax tracking helper", | |
db_path="products.fs"): | |
Trax.__init__(self) | |
if 'activities' in self.root: | |
self.activities = self.root['activities'] | |
else: | |
self.activities = self.root['activities'] = {} | |
def addActivity(self, code, name, description, cost_per_unit, activity_unit): | |
activity = Activity( code, name, description, cost_per_unit, activity_unit) | |
self.activities[code] = activity | |
transaction.commit() | |
if __name__ == '__main__': | |
# materials = MaterialTrax() | |
# materials.addMaterial(1, "PPC 5mm 1000 gm2", "Polipropileno celular 5 mm 1000 grs / m2", "box") | |
# materials.addMaterial(2, "PPC 5mm 1200 gm2", "Polipropileno celular 5 mm 1200 grs / m2", "box") | |
# print materials.materials[1] | |
# products = ProductTrax() | |
# activities = ActivitiyTrax() | |
# activities.addActivity(1, "Coser", "Coser", 100, "ML") | |
# activities.addActivity(2, "Cortar", "Cortar", 50, "Cortes") | |
# print activities.activities[1] | |
# print activities.activities[2] | |
# products.addProduct(1, "Caja A", "Caja PPC", "caja") | |
# print products.products[1].name | |
products = ProductTrax() | |
print products | |
# print products.products[1].__dict__ | |
# print products.products[1].__methods__ | |
print products.products[1].code | |
print products.products[1].name | |
print '*' * 80 | |
#products.addMaterial(1,1, 10,"Kg.", 1, "Unit", 5) | |
# products.products[2].addMaterial(1, 10,"Kg.", 1, "Unit", 5) | |
# print products.products[1].billofmaterials | |
print '*' * 80 | |
productA = Product(1, "Caja A", "Caja PPC", "caja") | |
productB = Product(1, "Caja A", "Caja PPC", "caja") | |
productB.addMaterial(1, 10,"Kg.", 1, "Unit", 5) | |
productB.addMaterial(2, 20,"Kg.", 1, "Unit", 10) | |
print "Bill of materials \n", productB.billofmaterials | |
print productB.CalculateCost() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment