Skip to content

Instantly share code, notes, and snippets.

@vsanjuan
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save vsanjuan/f668a3fbac4858f2f5d3 to your computer and use it in GitHub Desktop.

Select an option

Save vsanjuan/f668a3fbac4858f2f5d3 to your computer and use it in GitHub Desktop.

Revisions

  1. vsanjuan revised this gist Sep 6, 2014. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion resources
    Original file line number Diff line number Diff line change
    @@ -243,7 +243,9 @@ class EquipmentCatalogue(ResourceCatalogue):
    print "Please check and try again"
    return new_resource # The object is returned to the user to modify it.


    def list_resources(self, typeofobject = Equipment):

    CatalogueResource.list_resources(typeofobject)



  2. vsanjuan created this gist Sep 6, 2014.
    371 changes: 371 additions & 0 deletions resources
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,371 @@
    # Persistent class is imported so the Class can
    # be saved later in ZODB
    from persistent import Persistent
    from ZODB import FileStorage, DB
    import transaction
    from copy import deepcopy

    storage = FileStorage.FileStorage('activity_costing.fs')
    db = DB(storage)



    class Resource(Persistent):
    """Represents the resources used by the different activities.

    Attributes:
    name: Resource name.
    resource_code: A unique alphanumeric that identifies the resource.
    measure_unit : Unity of measure in which the resource usage and cost
    is measured.
    cost: Cost in Euros of the resource per measure_unit. This value is
    calculated for its child from its properties.

    """

    def __init__(self, name, resource_code, measure_unit, cost):

    self.name = name
    self.resource_code = resource_code
    self.measure_unit = measure_unit
    self.cost = cost

    def calculate_cost():
    """Calculates the cost per unit of measure for each resource depending
    of the properties of each child resource.

    Args:
    Defined in the child class

    Returns:
    A cost in Euros per measure_unit

    """

    pass


    class ResourceCatalogue(Persistent):
    """ Represents a catalogue of the resources available and the
    methods used to manage the catalogue. This class has no attributes """


    def __init__(self):

    connection, root = self.connect_ZODB()

    try:
    self.resource_catalogue = deepcopy(root.resource_catalogue)
    except:
    self.resource_catalogue = {}


    connection.close()

    def connect_ZODB(self):
    """Opens a connection to the ZODB"""

    connection = db.open()
    root = connection.root()

    return connection, root

    def save_ZODB(self, resource):
    """Saves de catalogue to the ZODB"""

    connection, root = self.connect_ZODB()

    self.resource_catalogue[resource.resource_code] = resource

    root.resource_catalogue = self.resource_catalogue

    transaction.commit()
    connection.close()


    def add_resource(self) :
    """ Method to be implemented by the child class to add a new
    resource"""
    pass


    def search_resource(self, resource_code = "", resource_name = ""):
    """Method to search and retrieve a resource by code or name.
    If the resource is found returns a ResourceCategory object. If
    not returns None."""

    if resource_code in self.resource_catalogue:
    return self.resource_catalogue[resource_code]
    else:
    return None

    for resource in self.resource_catalogue.values():
    if ( resource.name == resource_name) :
    return resource

    return None


    def list_resources(self, typeofresource = None):
    """List all items included in the catalogue.
    Each child from this class has its own __str__ method"""

    catalogue = self.resource_catalogue.values()

    print "*" * 80
    print "*" * 30 + "Lista de recursos" + "*" * 33
    print "*" * 80

    for resource in catalogue:
    if typeofresource == None:
    print resource
    print "*" * 80
    else:
    if typeofresource == type(resource):
    print resource
    print "*" * 80


    def delete_resource(self, resource_code):

    pass



    class JobCatalogue(ResourceCatalogue):
    """Represent a catalogue of the different job categories from where
    they can be managed and puts it in persistent ZODB storage
    """

    def __init__(self):
    """Adds a new Job Category list to the root ZODB if it hasn't
    been created yet. Otherwise it loads the information from the database.
    """

    ResourceCatalogue.__init__(self)


    def add_resource(self, job_category, resource_code, gross_salary, benefits, annual_hours, effective_working_rate):
    """Adds a new job category to the job catalogue and returns the JobCategory object
    """

    new_category = JobCategory(job_category, resource_code, gross_salary, benefits, annual_hours, effective_working_rate)


    # checks if the resource code is in the database. If so warns the user before committing the changes
    if resource_code not in self.resource_catalogue:

    #Save the new_category object
    self.save_ZODB(new_category)

    return new_category
    else:
    print "Resource {} code already exists. ".format(resource_code)
    resource = self.search_resource(resource_code)
    print resource
    print "Please check and try again"
    return new_category # The object is returned to the user to modify it.





    class JobCategory(Resource):
    """Represents the different job categories employed in each activity
    according to its qualifications

    Attributes:
    job_category: job performed.
    gross_salary: annual income before taxes
    benefits: annual monetary cost of extra costs as social security, health
    insurance, etc..
    annual_hours: yearly hours worked according to law and labour agreements.
    effective_working_rate: estimated percentage of effective working hours.
    Default value is 80%. The value is stored as a percentage.
    """

    def __init__(self, job_category, resource_code, gross_salary, benefits, annual_hours, effective_working_rate):
    """Inits JobCategory."""
    Resource.__init__(self, job_category, resource_code, "hours", 0)
    self.gross_salary = gross_salary
    self.benefits = benefits
    self.annual_hours = annual_hours
    self.effective_working_rate = effective_working_rate / 100.0

    self.cost = self.calculate_cost()


    def __str__(self):

    return ("Resource Code: " + str(self.resource_code) +
    " \nJob category: " + str(self.name) +
    " \nGross salary: {:,}".format(self.gross_salary) +
    " \nBenefits {:,} ".format(self.benefits) +
    " \nAnnual working hours: {:,}".format(self.annual_hours) +
    " \nEffective working rate {:.2%} ".format(self.effective_working_rate) +
    " \nHourly cost: {:.2f} ".format(self.cost))


    def calculate_cost(self):
    """Calculates the cost per effective working hour based on the object
    properties"""

    hourly_cost = ( self.gross_salary + self.benefits) / (self.annual_hours * self.effective_working_rate)

    return hourly_cost

    class EquipmentCatalogue(ResourceCatalogue):
    """Represents a catalogue of the company equipment information
    from where it be managed and stored in a persistent ZODB storage
    """

    def __init__(self):
    """Loads to memory the Resource Catalogue"""
    ResourceCatalogue.__init__(self)


    def add_resource(self, resource_code, equipment_name, measure_unit, acquisition_cost, useful_life, useful_life_time_unit="hours"):
    """Adds a new equipment to the company catalogue"""

    new_resource = Equipment(resource_code, equipment_name, measure_unit, acquisition_cost, useful_life, useful_life_time_unit="hours")

    # checks if the resource code is in the database. If so warns the user before committing the changes
    if resource_code not in self.resource_catalogue:

    #Save the new_category object
    self.save_ZODB(new_resource)

    return new_resource
    else:
    print "Resource {} code already exists. ".format(resource_code)
    resource = self.search_resource(resource_code)
    print resource
    print "Please check and try again"
    return new_resource # The object is returned to the user to modify it.





    class Equipment(Resource):
    """Represents the equipment used in the company to peform different activities.

    Attributes:

    Resouce_code : A unique code that identifies the equipment
    Equipment_name: Name of the equipment
    Measure_unit: Unit of measure in which the equipment is kept in inventory.
    Acquisition_cost : Cost of the equipment installed and working in the company including transport
    and installation expenses.
    Useful_life : Time in which the equipment will be productive.
    Useful_life_time_unit = It can be hours or years depending on the type of equipment.

    """

    def __init__(self, resource_code, equipment_name, measure_unit, acquisition_cost, useful_life, useful_life_time_unit="hours"):

    Resource.__init__(self, equipment_name, resource_code, measure_unit, 0)

    self.acquisition_cost = acquisition_cost # acquisition in Euros.
    self.useful_life = useful_life # useful life in hours
    self.useful_life_time_unit = useful_life_time_unit # it has to be a time object that allows conversions

    self.cost = self.calculate_cost()


    def calculate_cost(self):
    """ Calculates the cost of the equipment per unit of time"""

    return self.acquisition_cost / self.useful_life

    def __str__(self):

    return ("Equipment code: {} ".format(self.resource_code) +
    "\nEquipment name: {} ".format(self.name) +
    "\nMeasure unit: {} ".format(self.measure_unit) +
    "\nAcquisition cost: {:,} ".format(self.acquisition_cost) +
    "\nUseful life: {:,}".format(self.useful_life) +
    "\nUseful life time unit: {}".format(self.useful_life_time_unit) +
    "\nCost per time unit: {:.2f}".format(self.cost))

    class Space(Resource):

    """Represents the space available for the activities performed in the company.

    Attributes:

    Monthly_rental: Rent paid each month by the company without V.A.T.
    Rental_space: Space rented in square meters.
    % UsefulSpace: % of the total space that can be employed in company
    activities.

    """

    def __init__(self, space_code, space_name, monthly_rental, rental_space, useful_space):

    Resource.__init__(self, space_name, space_code, "square meters", 0)
    self.monthly_rental = monthly_rental
    self.rental_space = rental_space
    self.useful_sapce = useful_space / 100.0

    def CalculateCost(self):
    """Calculates the rental monthly cost per sqm."""

    return self.monthly_rental / self.rental_space

    def __str__(self):

    return ("Space code: {} ".format(self.resource_code) +
    "\nSpace name: {}".format(self.name) +
    "\nMonthly rental: {:,}".format(self.monthly_rental) +
    "\nRental space: {:,}".format(self.rental_space) +
    "\nUseful space: {:.2%}".format(self.useful_space) +
    "\nRenta cost per sqm: {:,.2f}".format(self.cost))


    if __name__ == "__main__":

    equipos = EquipmentCatalogue()
    equipos.add_resource(22, "Cortadora", "Maquina", 30000, 5000)
    equipos.add_resource(21, "Prensa", "Maquina", 20000, 10000)
    alquiler_oficina = Space(24, "Oficina centro", 3000, 200, 80)

    equipos.list_resources()

    # resource = ResourceCatalogue()

    # resource.list_resources()

    catalogue = ResourceCatalogue()

    catalogue.list_resources(JobCategory)
    catalogue.list_resources(Equipment)


    job_catalogue = JobCatalogue()

    # paleta = job_catalogue.add_resource("Paleta", 16, 15000, 5000, 1800, 50 )

    # print "*" * 80

    # designer = job_catalogue.add_resource("Designer", 15, 30000, 10000, 1800, 80 )

    # print "*" * 80

    # resource = job_catalogue.search_resource(15)
    # print "El recurso quince es: ", resource

    # resource = job_catalogue.search_resource(22)


    # print "El recurso 22 es: ", resource

    # job_catalogue.list_resources(JobCategory)


    # print "*" * 80
    # print "Lista todos los recursos"
    job_catalogue.list_resources()
    # print job
    # print paleta
    # print job.gross_salary