示例#1
0
    def __init__(
        self,
        id=None,
        title=None,
        comment=None,
        quantity=None,
        quantity_format=None,
        quantity_b=None,
        quantity_b_format=None,
        tax=None,
        hour_rate=None,
        wage_add=None,
        wage_add_explain=None
    ):
        """Initialize the class."""
        # values of the BaseEntry class
        super(MultiplyEntry, self).__init__(
            id=id,
            title=title,
            comment=comment,
            quantity=quantity,
            quantity_format=quantity_format,
            quantity_b=quantity_b,
            quantity_b_format=quantity_b_format,
            tax=tax
        )

        # new values for this class
        self._hour_rate = QuantityTime(hour_rate)
        self._wage_add = QuantityTime(wage_add)
        self.wage_add_explain = '' if wage_add_explain is None else str(wage_add_explain)
示例#2
0
    def get_time(self, entry_list=None, *args, **kwargs):
        """
        Get time according to entry_list or zero.

        entry_list is the global list holding all entry-objects.
        This function calculates the time respecting the entries from the
        entry_list. The ConnectEntry class is an entry for multiplying entries
        times or only prices (depenging on self.is_time()) - e.g. licences
        can cost x-times multiplied the original working time of a task.
        This class can calculate it.
        """
        # if is_time() == False or entry_list not a list, return 0
        if not self.get_is_time() or type(entry_list) is not list:
            return QuantityTime('0:00')
        # is_time() == True, calculate time respecting other entires
        else:
            # otherwise iterate through entry_list and find
            # entries which ids exist in the self._connected list
            out = QuantityTime('0:00')
            for entry in entry_list:
                if entry.get_id() in self._connected:
                    # if its in the list, multiply its time and add it
                    out += (self.get_multiplicator() *
                            entry.get_time(entry_list=entry_list))
            # return the result
            return out * self._quantity * self._quantity_b
示例#3
0
def test_offer_data_structure():
    """Test the data structure for offer and appended entries."""
    myoffer = TestOffer().out

    # first check for title of second entry
    assert myoffer.get_entry_list()[1].title == 'Multiply title'

    # check time of third entry
    t = myoffer.get_entry_list()[2].get_time(myoffer.get_entry_list())
    assert t == QuantityTime(0)

    # connect connected entry to base entry (3rd entry to 1st)
    myoffer.get_entry_list()[2].connect_entry(
        entry_list=myoffer.get_entry_list(),
        entry_id=myoffer.get_entry_list()[0].get_id())

    # now time of third entry is 2 * 3 * 2.5 hours
    t = myoffer.get_entry_list()[2].get_time(myoffer.get_entry_list())
    multi = 2 * 3 * QuantityTime(2.5)
    assert t == multi
示例#4
0
    def get_time_total(self):
        """Get times of entries summerized."""
        # init output variable
        out = QuantityTime('0:00')

        # iterate through the entries and get its time
        for e in self._entry_list:
            out += e.get_time(entry_list=self._entry_list)

        # return it
        return out
示例#5
0
def update_entry(entry=None, quantity=None):
    """Try to return new entry with updated quantity etc."""
    is_entry = check_objects.is_entry(entry)
    quantity = str(quantity)

    if not is_entry:
        return entry

    # it's no MultiplyEntry
    if type(entry) is not MultiplyEntry:
        entry.quantity_format = quantity
        return entry

    # it's a multiply entry: try to convert given quantity to QuantityTime and string

    # first split the given quantity
    s = quantity.split(' ')

    # quantity string given as well
    if len(s) > 1:
        # set new quantity format
        entry.quantity_format = '{s} ' + ' '.join(s[1:])

    # only one thign entered
    else:
        # set new quantity format
        entry.quantity_format = '{s}'

    # get the quantity number
    quantity_number = QuantityTime(s[0])

    # first given thing is a number > 0
    if quantity_number > 0:

        # calculate the new hour rate
        hour_rate = entry.get_quantity() / quantity_number

        # set new hour rate
        entry.set_hour_rate(hour_rate)

        # set new quantity
        entry.set_quantity(quantity_number)

    # it's something else, set quantity_format from argument and leave quantity
    else:
        entry.quantity_format = quantity

    return entry
示例#6
0
    def __init__(
        self,
        id=None,
        title=None,
        comment=None,
        quantity=None,
        quantity_format=None,
        quantity_b=None,
        quantity_b_format=None,
        tax=None,
        time=None,
        price=None,
        connected=None
    ):
        """Init the class."""
        # gen ID if not set, otherwise get it from argument
        self._id = str(uuid.uuid1()) if id is None else str(id)

        # get other variables from arguments
        self.title = '' if title is None else str(title)
        self.comment = '' if comment is None else str(comment)
        self._quantity = QuantityTime(quantity)
        self.quantity_format = '' if quantity_format is None else str(quantity_format)
        if quantity_b is None:
            self._quantity_b = QuantityTime(1)
        else:
            self._quantity_b = QuantityTime(quantity_b)
        self.quantity_b_format = (
            '' if quantity_b_format is None else str(quantity_b_format)
        )
        self._tax = Decimal(0)                  # set default
        self.set_tax(tax)                       # try to set arguments value
        self._time = QuantityTime(time)
        self._price = Decimal(0)                # set default
        self.set_price(price)                   # try to set arguments value

        # get the connected list (for ConnectEntry only)
        if type(connected) is set:
            self._connected = connected
        else:
            self._connected = set()
示例#7
0
class Default(object):
    """Settings class."""

    def __init__(
        self,
        data_path=None,
        language=None,
        offer_title=None,
        offer_comment=None,
        offer_comment_b=None,
        offer_filename=None,
        offer_round_price=None,
        offer_templates=None,
        invoice_title=None,
        invoice_id=None,
        invoice_comment=None,
        invoice_comment_b=None,
        invoice_filename=None,
        invoice_round_price=None,
        invoice_templates=None,
        invoice_due_days=None,
        invoice_delivery=None,
        invoice_ledger_comment=None,
        date_fmt=None,
        commodity=None,
        client_id=None,
        client_company=None,
        client_company_b=None,
        client_attention=None,
        client_salutation=None,
        client_name=None,
        client_family_name=None,
        client_street=None,
        client_post_code=None,
        client_city=None,
        client_country=None,
        client_tax_id=None,
        client_language=None,
        project_title=None,
        project_hours_per_day=None,
        project_work_days=None,
        project_minimum_days=None,
        project_wage=None,
        baseentry_title=None,
        baseentry_comment=None,
        baseentry_quantity=None,
        baseentry_quantity_format=None,
        baseentry_quantity_b=None,
        baseentry_quantity_b_format=None,
        baseentry_time=None,
        baseentry_price=None,
        multiplyentry_title=None,
        multiplyentry_comment=None,
        multiplyentry_quantity=None,
        multiplyentry_quantity_format=None,
        multiplyentry_quantity_b=None,
        multiplyentry_quantity_b_format=None,
        multiplyentry_hour_rate=None,
        connectentry_title=None,
        connectentry_comment=None,
        connectentry_quantity=None,
        connectentry_quantity_format=None,
        connectentry_quantity_b=None,
        connectentry_quantity_b_format=None,
        connectentry_is_time=None,
        connectentry_multiplicator=None,
        ledger_time_def_quantity=None
    ):
        """Initialize the class and hard code defaults, if no file is given."""
        self.language = 'NEW' if language is None else language

        self.offer_title = '' if offer_title is None else offer_title
        self.offer_comment = '' if offer_comment is None else offer_comment
        self.offer_comment_b = '' if offer_comment_b is None else offer_comment_b
        self.offer_filename = '' if offer_filename is None else offer_filename
        self.set_offer_round_price(
            False if offer_round_price is None else offer_round_price
        )
        self._offer_templates = {}                      # set default
        self.set_offer_templates(offer_templates)       # try to set arguments value

        self.invoice_title = '' if invoice_title is None else invoice_title
        self.invoice_id = '' if invoice_id is None else invoice_id
        self.invoice_comment = '' if invoice_comment is None else invoice_comment
        self.invoice_comment_b = '' if invoice_comment_b is None else invoice_comment_b
        self.invoice_filename = '' if invoice_filename is None else invoice_filename
        self.set_invoice_round_price(
            False if invoice_round_price is None else invoice_round_price
        )
        self._invoice_templates = {}                        # set default
        self.set_invoice_templates(invoice_templates)       # try to set arguments value
        self._invoice_due_days = 14                         # set default
        self.set_invoice_due_days(invoice_due_days)         # try to set arguments value
        self.invoice_delivery = '' if invoice_delivery is None else invoice_delivery
        self.invoice_ledger_comment = (
            '' if invoice_ledger_comment is None else invoice_ledger_comment
        )

        self.date_fmt = '' if date_fmt is None else date_fmt
        self.commodity = '' if commodity is None else commodity

        # client default values
        self.client_id = '{CLIENT_COUNT}' if client_id is None else client_id
        self.client_company = '' if client_company is None else client_company
        self.client_company_b = '' if client_company_b is None else client_company_b
        self.client_attention = 'Attn.' if client_attention is None else client_attention
        self.client_salutation = '' if client_salutation is None else client_salutation
        self.client_name = '' if client_name is None else client_name
        self.client_family_name = '' if client_family_name is None else client_family_name
        self.client_street = '' if client_street is None else client_street

        self.client_post_code = '' if client_post_code is None else client_post_code
        self.client_city = '' if client_city is None else client_city
        self.client_country = '' if client_country is None else client_country
        self.client_tax_id = '' if client_tax_id is None else client_tax_id
        self.client_language = 'en' if client_language is None else client_language

        # project default values
        self.project_title = '{PROJECT_COUNT}' if project_title is None else project_title
        self._project_hours_per_day = 0
        self.set_project_hours_per_day(project_hours_per_day)
        self._project_work_days = [0, 1, 2, 3, 4]
        self.set_project_work_days(project_work_days)
        self._project_minimum_days = 2
        self.set_project_minimum_days(project_minimum_days)
        self._project_wage = Decimal(0)
        self.set_project_wage(project_wage)

        # baseentry default values
        self.baseentry_title = '' if baseentry_title is None else baseentry_title
        self.baseentry_comment = '' if baseentry_comment is None else baseentry_comment
        self._baseentry_quantity = QuantityTime(baseentry_quantity)
        self.baseentry_quantity_format = (
            '' if baseentry_quantity_format is None
            else baseentry_quantity_format
        )
        if baseentry_quantity_b is None:
            self._baseentry_quantity_b = QuantityTime(1)
        else:
            self._baseentry_quantity_b = QuantityTime(baseentry_quantity_b)
        self.baseentry_quantity_b_format = (
            '' if baseentry_quantity_b_format is None
            else baseentry_quantity_b_format
        )
        self._baseentry_time = QuantityTime(baseentry_time)
        self._baseentry_price = Decimal(0)
        self.set_baseentry_price(baseentry_price)

        # multiplyentry default values
        self.multiplyentry_title = (
            '' if multiplyentry_title is None
            else multiplyentry_title
        )
        self.multiplyentry_comment = (
            '' if multiplyentry_comment is None
            else multiplyentry_comment
        )
        self._multiplyentry_quantity = QuantityTime(multiplyentry_quantity)
        self.multiplyentry_quantity_format = (
            '' if multiplyentry_quantity_format is None
            else multiplyentry_quantity_format
        )
        if multiplyentry_quantity_b is None:
            self._multiplyentry_quantity_b = QuantityTime(1)
        else:
            self._multiplyentry_quantity_b = QuantityTime(multiplyentry_quantity_b)
        self.multiplyentry_quantity_b_format = (
            '' if multiplyentry_quantity_b_format is None
            else multiplyentry_quantity_b_format
        )
        self._multiplyentry_hour_rate = QuantityTime(multiplyentry_hour_rate)

        # connectentry default values
        self.connectentry_title = (
            '' if connectentry_title is None else connectentry_title
        )
        self.connectentry_comment = (
            '' if connectentry_comment is None else connectentry_comment
        )
        self._connectentry_quantity = QuantityTime(connectentry_quantity)
        self.connectentry_quantity_format = (
            '' if connectentry_quantity_format is None
            else connectentry_quantity_format
        )
        if connectentry_quantity_b is None:
            self._connectentry_quantity_b = QuantityTime(1)
        else:
            self._connectentry_quantity_b = QuantityTime(connectentry_quantity_b)
        self.connectentry_quantity_b_format = (
            '' if connectentry_quantity_b_format is None
            else connectentry_quantity_b_format
        )
        self.set_connectentry_is_time(
            True if connectentry_is_time is None else connectentry_is_time
        )
        self._connectentry_multiplicator = Decimal(0)
        self.set_connectentry_multiplicator(connectentry_multiplicator)

        # ledger time
        self.ledger_time_def_quantity = (
            '1' if ledger_time_def_quantity is None else ledger_time_def_quantity
        )

        # try to load default automatically
        if data_path is not None:
            self.load_settings_from_file(data_path)

    def set_offer_round_price(self, value):
        """Set offer_round_price."""
        self._offer_round_price = bool(value)

    def get_offer_round_price(self):
        """Get offer_round_price."""
        return self._offer_round_price

    def set_offer_templates(self, value):
        """Set offer_templates."""
        if type(value) is dict:
            self._offer_templates = value
        elif type(value) is list:
            self._offer_templates = {}
            for x in value:
                self.add_offer_template(x[0], x[1])

    def get_offer_templates_as_list(self):
        """Get offer_templates as list with tuples of key+value."""
        return [(key, self._offer_templates[key]) for key in self._offer_templates]

    def get_offer_templates(self):
        """Get offer_templates as dict."""
        return self._offer_templates

    def add_offer_template(self, key, value):
        """Add to offer_templates."""
        self._offer_templates[key] = value

    def del_offer_template(self, key):
        """Try to delete offer_templates entry."""
        if key in self._offer_templates:
            del self._offer_templates[key]

    def set_invoice_round_price(self, value):
        """Set invoice_round_price."""
        self._invoice_round_price = bool(value)

    def get_invoice_round_price(self):
        """Get invoice_round_price."""
        return self._invoice_round_price

    def set_invoice_templates(self, value):
        """Set invoice_templates."""
        if type(value) is dict:
            self._invoice_templates = value
        elif type(value) is list:
            self._invoice_templates = {}
            for x in value:
                self.add_invoice_template(x[0], x[1])

    def get_invoice_templates_as_list(self):
        """Get invoice_templates as list with tuples of key+value."""
        return [(key, self._invoice_templates[key]) for key in self._invoice_templates]

    def get_invoice_templates(self):
        """Get invoice_templates as dict."""
        return self._invoice_templates

    def add_invoice_template(self, key, value):
        """Add to invoice_templates."""
        self._invoice_templates[key] = value

    def del_invoice_template(self, key):
        """Try to delete invoice_templates entry."""
        if key in self._invoice_templates:
            del self._invoice_templates[key]

    def set_invoice_due_days(self, value):
        """Set invoice_due_days."""
        try:
            self._invoice_due_days = int(value)
        except Exception:
            pass

    def get_invoice_due_days(self):
        """Get invoice_due_days."""
        return self._invoice_due_days

    def set_project_hours_per_day(self, value):
        """Set project_hours_per_day."""
        try:
            self._project_hours_per_day = int(value)
        except Exception:
            pass

    def get_project_hours_per_day(self):
        """Get project_hours_per_day."""
        return self._project_hours_per_day

    def set_project_work_days(self, value):
        """Set project_work_days."""
        if type(value) is list:
            self._project_work_days = value

    def get_project_work_days(self):
        """Get project_work_days."""
        return self._project_work_days

    def set_project_minimum_days(self, value):
        """Set project_minimum_days."""
        try:
            self._project_minimum_days = int(value)
        except Exception:
            pass

    def get_project_minimum_days(self):
        """Get project_minimum_days."""
        return self._project_minimum_days

    def set_project_wage(self, value):
        """Set project_wage."""
        try:
            self._project_wage = Decimal(str(value))
        except Exception:
            pass

    def get_project_wage(self):
        """Get project_wage."""
        return self._project_wage

    def set_baseentry_quantity(self, value):
        """Set baseentry_quantity."""
        self._baseentry_quantity.set(value)

    def get_baseentry_quantity(self):
        """Get baseentry_quantity."""
        return self._baseentry_quantity

    def set_baseentry_quantity_b(self, value):
        """Set baseentry_quantity_b."""
        self._baseentry_quantity_b.set(value)

    def get_baseentry_quantity_b(self):
        """Get baseentry_quantity_b."""
        return self._baseentry_quantity_b

    def set_baseentry_time(self, value):
        """Set baseentry_time."""
        self._baseentry_time.set(value)

    def get_baseentry_time(self):
        """Get baseentry_time."""
        self._baseentry_time.type('time')
        return self._baseentry_time

    def set_baseentry_price(self, value):
        """Set baseentry_price."""
        try:
            self._baseentry_price = Decimal(str(value))
        except Exception:
            pass

    def get_baseentry_price(self):
        """Get baseentry_price."""
        return self._baseentry_price

    def set_multiplyentry_quantity(self, value):
        """Set multiplyentry_quantity."""
        self._multiplyentry_quantity.set(value)

    def get_multiplyentry_quantity(self):
        """Get multiplyentry_quantity."""
        return self._multiplyentry_quantity

    def set_multiplyentry_quantity_b(self, value):
        """Set multiplyentry_quantity_b."""
        self._multiplyentry_quantity_b.set(value)

    def get_multiplyentry_quantity_b(self):
        """Get multiplyentry_quantity_b."""
        return self._multiplyentry_quantity_b

    def set_multiplyentry_hour_rate(self, value):
        """Set multiplyentry_hour_rate."""
        self._multiplyentry_hour_rate.set(value)

    def get_multiplyentry_hour_rate(self):
        """Get multiplyentry_hour_rate."""
        self._multiplyentry_hour_rate.type('time')
        return self._multiplyentry_hour_rate

    def set_connectentry_quantity(self, value):
        """Set connectentry_quantity."""
        self._connectentry_quantity.set(value)

    def get_connectentry_quantity(self):
        """Get connectentry_quantity."""
        return self._connectentry_quantity

    def set_connectentry_quantity_b(self, value):
        """Set connectentry_quantity_b."""
        self._connectentry_quantity_b.set(value)

    def get_connectentry_quantity_b(self):
        """Get connectentry_quantity_b."""
        return self._connectentry_quantity_b

    def set_connectentry_is_time(self, value):
        """Set connectentry_is_time."""
        self._connectentry_is_time = bool(value)

    def get_connectentry_is_time(self):
        """Get connectentry_is_time."""
        return self._connectentry_is_time

    def set_connectentry_multiplicator(self, value):
        """Set connectentry_multiplicator."""
        try:
            self._connectentry_multiplicator = Decimal(str(value))
        except Exception:
            pass

    def get_connectentry_multiplicator(self):
        """Get connectentry_multiplicator."""
        return self._connectentry_multiplicator

    def to_json(self, indent=2):
        """Convert settings data to json format."""
        out = {}

        # fetch all setting variables
        out['language'] = self.language

        out['offer_title'] = self.offer_title
        out['offer_comment'] = self.offer_comment
        out['offer_comment_b'] = self.offer_comment_b
        out['offer_filename'] = self.offer_filename
        out['offer_round_price'] = self._offer_round_price
        out['offer_templates'] = self._offer_templates

        out['invoice_title'] = self.invoice_title
        out['invoice_id'] = self.invoice_id
        out['invoice_comment'] = self.invoice_comment
        out['invoice_comment_b'] = self.invoice_comment_b
        out['invoice_filename'] = self.invoice_filename
        out['invoice_round_price'] = self._invoice_round_price
        out['invoice_templates'] = self._invoice_templates
        out['invoice_due_days'] = self._invoice_due_days
        out['invoice_delivery'] = self.invoice_delivery
        out['invoice_ledger_comment'] = self.invoice_ledger_comment

        out['date_fmt'] = self.date_fmt
        out['commodity'] = self.commodity

        out['client_id'] = self.client_id
        out['client_company'] = self.client_company
        out['client_company_b'] = self.client_company_b
        out['client_attention'] = self.client_attention
        out['client_salutation'] = self.client_salutation
        out['client_name'] = self.client_name
        out['client_family_name'] = self.client_family_name
        out['client_street'] = self.client_street
        out['client_post_code'] = self.client_post_code
        out['client_city'] = self.client_city
        out['client_country'] = self.client_country
        out['client_tax_id'] = self.client_tax_id
        out['client_language'] = self.client_language

        out['project_title'] = self.project_title
        out['project_hours_per_day'] = self._project_hours_per_day
        out['project_work_days'] = self._project_work_days
        out['project_minimum_days'] = self._project_minimum_days
        out['project_wage'] = float(self._project_wage)

        out['baseentry_title'] = self.baseentry_title
        out['baseentry_comment'] = self.baseentry_comment
        out['baseentry_quantity'] = str(self._baseentry_quantity)
        out['baseentry_quantity_format'] = self.baseentry_quantity_format
        out['baseentry_quantity_b'] = str(self._baseentry_quantity_b)
        out['baseentry_quantity_b_format'] = self.baseentry_quantity_b_format
        out['baseentry_time'] = str(self._baseentry_time)
        out['baseentry_price'] = float(self._baseentry_price)

        out['multiplyentry_title'] = self.multiplyentry_title
        out['multiplyentry_comment'] = self.multiplyentry_comment
        out['multiplyentry_quantity'] = str(self._multiplyentry_quantity)
        out['multiplyentry_quantity_format'] = self.multiplyentry_quantity_format
        out['multiplyentry_quantity_b'] = str(self._multiplyentry_quantity_b)
        out['multiplyentry_quantity_b_format'] = self.multiplyentry_quantity_b_format
        out['multiplyentry_hour_rate'] = str(self._multiplyentry_hour_rate)

        out['connectentry_title'] = self.connectentry_title
        out['connectentry_comment'] = self.connectentry_comment
        out['connectentry_quantity'] = str(self._connectentry_quantity)
        out['connectentry_quantity_format'] = self.connectentry_quantity_format
        out['connectentry_quantity_b'] = str(self._connectentry_quantity_b)
        out['connectentry_quantity_b_format'] = self.connectentry_quantity_b_format
        out['connectentry_is_time'] = self._connectentry_is_time
        out['connectentry_multiplicator'] = float(self._connectentry_multiplicator)

        out['ledger_time_def_quantity'] = self.ledger_time_def_quantity

        # return the json
        return json.dumps(out, indent=indent, sort_keys=True)

    def feed_json(self, js=None):
        """Feed settings variables from json string."""
        if js is None:
            return

        # get js as dict
        try:
            js = json.loads(js)
        except Exception:
            # do not load it
            return

        # feed settings variables
        if 'language' in js.keys():
            self.language = js['language']

        if 'offer_title' in js.keys():
            self.offer_title = js['offer_title']

        if 'offer_comment' in js.keys():
            self.offer_comment = js['offer_comment']

        if 'offer_comment_b' in js.keys():
            self.offer_comment_b = js['offer_comment_b']

        if 'offer_filename' in js.keys():
            self.offer_filename = js['offer_filename']

        if 'offer_round_price' in js.keys():
            self.set_offer_round_price(js['offer_round_price'])

        if 'offer_templates' in js.keys():
            self._offer_templates = js['offer_templates']

        if 'invoice_title' in js.keys():
            self.invoice_title = js['invoice_title']

        if 'invoice_id' in js.keys():
            self.invoice_id = js['invoice_id']

        if 'invoice_comment' in js.keys():
            self.invoice_comment = js['invoice_comment']

        if 'invoice_comment_b' in js.keys():
            self.invoice_comment_b = js['invoice_comment_b']

        if 'invoice_filename' in js.keys():
            self.invoice_filename = js['invoice_filename']

        if 'invoice_round_price' in js.keys():
            self.set_invoice_round_price(js['invoice_round_price'])

        if 'invoice_templates' in js.keys():
            self._invoice_templates = js['invoice_templates']

        if 'invoice_due_days' in js.keys():
            self.set_invoice_due_days(js['invoice_due_days'])

        if 'invoice_delivery' in js.keys():
            self.invoice_delivery = js['invoice_delivery']

        if 'invoice_ledger_comment' in js.keys():
            self.invoice_ledger_comment = js['invoice_ledger_comment']

        if 'date_fmt' in js.keys():
            self.date_fmt = js['date_fmt']

        if 'commodity' in js.keys():
            self.commodity = js['commodity']

        if 'client_id' in js.keys():
            self.client_id = js['client_id']

        if 'client_company' in js.keys():
            self.client_company = js['client_company']

        if 'client_company_b' in js.keys():
            self.client_company_b = js['client_company_b']

        if 'client_attention' in js.keys():
            self.client_attention = js['client_attention']

        if 'client_salutation' in js.keys():
            self.client_salutation = js['client_salutation']

        if 'client_name' in js.keys():
            self.client_name = js['client_name']

        if 'client_family_name' in js.keys():
            self.client_family_name = js['client_family_name']

        if 'client_street' in js.keys():
            self.client_street = js['client_street']

        if 'client_post_code' in js.keys():
            self.client_post_code = js['client_post_code']

        if 'client_city' in js.keys():
            self.client_city = js['client_city']

        if 'client_country' in js.keys():
            self.client_country = js['client_country']

        if 'client_tax_id' in js.keys():
            self.client_tax_id = js['client_tax_id']

        if 'client_language' in js.keys():
            self.client_language = js['client_language']

        if 'project_title' in js.keys():
            self.project_title = js['project_title']

        if 'project_hours_per_day' in js.keys():
            self.set_project_hours_per_day(js['project_hours_per_day'])

        if 'project_work_days' in js.keys():
            self.set_project_work_days(js['project_work_days'])

        if 'project_minimum_days' in js.keys():
            self.set_project_minimum_days(js['project_minimum_days'])

        if 'project_wage' in js.keys():
            self.set_project_wage(js['project_wage'])

        if 'baseentry_title' in js.keys():
            self.baseentry_title = js['baseentry_title']

        if 'baseentry_comment' in js.keys():
            self.baseentry_comment = js['baseentry_comment']

        if 'baseentry_quantity' in js.keys():
            self.set_baseentry_quantity(js['baseentry_quantity'])

        if 'baseentry_quantity_format' in js.keys():
            self.baseentry_quantity_format = js['baseentry_quantity_format']

        if 'baseentry_quantity_b' in js.keys():
            self.set_baseentry_quantity_b(js['baseentry_quantity_b'])

        if 'baseentry_quantity_b_format' in js.keys():
            self.baseentry_quantity_b_format = js['baseentry_quantity_b_format']

        if 'baseentry_time' in js.keys():
            self.set_baseentry_time(js['baseentry_time'])

        if 'baseentry_price' in js.keys():
            self.set_baseentry_price(js['baseentry_price'])

        if 'multiplyentry_title' in js.keys():
            self.multiplyentry_title = js['multiplyentry_title']

        if 'multiplyentry_comment' in js.keys():
            self.multiplyentry_comment = js['multiplyentry_comment']

        if 'multiplyentry_quantity' in js.keys():
            self.set_multiplyentry_quantity(js['multiplyentry_quantity'])

        if 'multiplyentry_quantity_format' in js.keys():
            self.multiplyentry_quantity_format = js['multiplyentry_quantity_format']

        if 'multiplyentry_quantity_b' in js.keys():
            self.set_multiplyentry_quantity_b(js['multiplyentry_quantity_b'])

        if 'multiplyentry_quantity_b_format' in js.keys():
            self.multiplyentry_quantity_b_format = js['multiplyentry_quantity_b_format']

        if 'multiplyentry_hour_rate' in js.keys():
            self.set_multiplyentry_hour_rate(js['multiplyentry_hour_rate'])

        if 'connectentry_title' in js.keys():
            self.connectentry_title = js['connectentry_title']

        if 'connectentry_comment' in js.keys():
            self.connectentry_comment = js['connectentry_comment']

        if 'connectentry_quantity' in js.keys():
            self.set_connectentry_quantity(js['connectentry_quantity'])

        if 'connectentry_quantity_format' in js.keys():
            self.connectentry_quantity_format = js['connectentry_quantity_format']

        if 'connectentry_quantity_b' in js.keys():
            self.set_connectentry_quantity_b(js['connectentry_quantity_b'])

        if 'connectentry_quantity_b_format' in js.keys():
            self.connectentry_quantity_b_format = js['connectentry_quantity_b_format']

        if 'connectentry_is_time' in js.keys():
            self.set_connectentry_is_time(js['connectentry_is_time'])

        if 'connectentry_multiplicator' in js.keys():
            self.set_connectentry_multiplicator(js['connectentry_multiplicator'])

        if 'ledger_time_def_quantity' in js.keys():
            self.ledger_time_def_quantity = js['ledger_time_def_quantity']

    def gen_abs_path_to_default_file(self, data_path, lang=None):
        """Generate the absolut path to the settings file."""
        lang_set = type(lang) is str
        if not lang_set:
            return data_path + '/defaults_' + self.language + '.settings'
        else:
            return data_path + '/defaults_' + lang + '.settings'

    def delete_default_file(self, data_path, lang=None):
        """Delete the default file in data_path."""
        if os.path.isfile(self.gen_abs_path_to_default_file(data_path, lang)):
            os.remove(self.gen_abs_path_to_default_file(data_path, lang))

    def save_defaults_to_file(self, data_path):
        """Save the default to file in data_path."""
        f = open(self.gen_abs_path_to_default_file(data_path), 'w')
        f.write(self.to_json())
        f.close()

    def load_settings_from_file(self, data_path):
        """Load the settings from file in data_path."""
        # check if the file exists
        if os.path.isfile(self.gen_abs_path_to_default_file(data_path)):
            # load content from file
            f = open(self.gen_abs_path_to_default_file(data_path), 'r')
            loaded = f.read().strip()
            f.close()

            # and feed own variables with it
            self.feed_json(loaded)

    def copy(self):
        """Return copy of own object."""
        return Default(
            language=self.language,
            offer_title=self.offer_title,
            offer_comment=self.offer_comment,
            offer_comment_b=self.offer_comment_b,
            offer_filename=self.offer_filename,
            offer_round_price=self._offer_round_price,
            offer_templates=self._offer_templates,
            invoice_title=self.invoice_title,
            invoice_id=self.invoice_id,
            invoice_comment=self.invoice_comment,
            invoice_comment_b=self.invoice_comment_b,
            invoice_filename=self.invoice_filename,
            invoice_round_price=self._invoice_round_price,
            invoice_templates=self._invoice_templates,
            invoice_due_days=self._invoice_due_days,
            invoice_delivery=self.invoice_delivery,
            invoice_ledger_comment=self.invoice_ledger_comment,
            date_fmt=self.date_fmt,
            commodity=self.commodity,
            client_id=self.client_id,
            client_company=self.client_company,
            client_company_b=self.client_company_b,
            client_attention=self.client_attention,
            client_salutation=self.client_salutation,
            client_name=self.client_name,
            client_family_name=self.client_family_name,
            client_street=self.client_street,
            client_post_code=self.client_post_code,
            client_city=self.client_city,
            client_country=self.client_country,
            client_tax_id=self.client_tax_id,
            client_language=self.client_language,
            project_title=self.project_title,
            project_hours_per_day=self._project_hours_per_day,
            project_work_days=self._project_work_days,
            project_minimum_days=self._project_minimum_days,
            project_wage=self._project_wage,
            baseentry_title=self.baseentry_title,
            baseentry_comment=self.baseentry_comment,
            baseentry_quantity=self._baseentry_quantity,
            baseentry_quantity_format=self.baseentry_quantity_format,
            baseentry_quantity_b=self._baseentry_quantity_b,
            baseentry_quantity_b_format=self.baseentry_quantity_b_format,
            baseentry_time=self._baseentry_time,
            baseentry_price=self._baseentry_price,
            multiplyentry_title=self.multiplyentry_title,
            multiplyentry_comment=self.multiplyentry_comment,
            multiplyentry_quantity=self._multiplyentry_quantity,
            multiplyentry_quantity_format=self.multiplyentry_quantity_format,
            multiplyentry_quantity_b=self._multiplyentry_quantity_b,
            multiplyentry_quantity_b_format=self.multiplyentry_quantity_b_format,
            multiplyentry_hour_rate=self._multiplyentry_hour_rate,
            connectentry_title=self.connectentry_title,
            connectentry_comment=self.connectentry_comment,
            connectentry_quantity=self._connectentry_quantity,
            connectentry_quantity_format=self.connectentry_quantity_format,
            connectentry_quantity_b=self._connectentry_quantity_b,
            connectentry_quantity_b_format=self.connectentry_quantity_b_format,
            connectentry_is_time=self._connectentry_is_time,
            connectentry_multiplicator=self._connectentry_multiplicator,
            ledger_time_def_quantity=self.ledger_time_def_quantity
        )
示例#8
0
    def __init__(
        self,
        data_path=None,
        language=None,
        offer_title=None,
        offer_comment=None,
        offer_comment_b=None,
        offer_filename=None,
        offer_round_price=None,
        offer_templates=None,
        invoice_title=None,
        invoice_id=None,
        invoice_comment=None,
        invoice_comment_b=None,
        invoice_filename=None,
        invoice_round_price=None,
        invoice_templates=None,
        invoice_due_days=None,
        invoice_delivery=None,
        invoice_ledger_comment=None,
        date_fmt=None,
        commodity=None,
        client_id=None,
        client_company=None,
        client_company_b=None,
        client_attention=None,
        client_salutation=None,
        client_name=None,
        client_family_name=None,
        client_street=None,
        client_post_code=None,
        client_city=None,
        client_country=None,
        client_tax_id=None,
        client_language=None,
        project_title=None,
        project_hours_per_day=None,
        project_work_days=None,
        project_minimum_days=None,
        project_wage=None,
        baseentry_title=None,
        baseentry_comment=None,
        baseentry_quantity=None,
        baseentry_quantity_format=None,
        baseentry_quantity_b=None,
        baseentry_quantity_b_format=None,
        baseentry_time=None,
        baseentry_price=None,
        multiplyentry_title=None,
        multiplyentry_comment=None,
        multiplyentry_quantity=None,
        multiplyentry_quantity_format=None,
        multiplyentry_quantity_b=None,
        multiplyentry_quantity_b_format=None,
        multiplyentry_hour_rate=None,
        connectentry_title=None,
        connectentry_comment=None,
        connectentry_quantity=None,
        connectentry_quantity_format=None,
        connectentry_quantity_b=None,
        connectentry_quantity_b_format=None,
        connectentry_is_time=None,
        connectentry_multiplicator=None,
        ledger_time_def_quantity=None
    ):
        """Initialize the class and hard code defaults, if no file is given."""
        self.language = 'NEW' if language is None else language

        self.offer_title = '' if offer_title is None else offer_title
        self.offer_comment = '' if offer_comment is None else offer_comment
        self.offer_comment_b = '' if offer_comment_b is None else offer_comment_b
        self.offer_filename = '' if offer_filename is None else offer_filename
        self.set_offer_round_price(
            False if offer_round_price is None else offer_round_price
        )
        self._offer_templates = {}                      # set default
        self.set_offer_templates(offer_templates)       # try to set arguments value

        self.invoice_title = '' if invoice_title is None else invoice_title
        self.invoice_id = '' if invoice_id is None else invoice_id
        self.invoice_comment = '' if invoice_comment is None else invoice_comment
        self.invoice_comment_b = '' if invoice_comment_b is None else invoice_comment_b
        self.invoice_filename = '' if invoice_filename is None else invoice_filename
        self.set_invoice_round_price(
            False if invoice_round_price is None else invoice_round_price
        )
        self._invoice_templates = {}                        # set default
        self.set_invoice_templates(invoice_templates)       # try to set arguments value
        self._invoice_due_days = 14                         # set default
        self.set_invoice_due_days(invoice_due_days)         # try to set arguments value
        self.invoice_delivery = '' if invoice_delivery is None else invoice_delivery
        self.invoice_ledger_comment = (
            '' if invoice_ledger_comment is None else invoice_ledger_comment
        )

        self.date_fmt = '' if date_fmt is None else date_fmt
        self.commodity = '' if commodity is None else commodity

        # client default values
        self.client_id = '{CLIENT_COUNT}' if client_id is None else client_id
        self.client_company = '' if client_company is None else client_company
        self.client_company_b = '' if client_company_b is None else client_company_b
        self.client_attention = 'Attn.' if client_attention is None else client_attention
        self.client_salutation = '' if client_salutation is None else client_salutation
        self.client_name = '' if client_name is None else client_name
        self.client_family_name = '' if client_family_name is None else client_family_name
        self.client_street = '' if client_street is None else client_street

        self.client_post_code = '' if client_post_code is None else client_post_code
        self.client_city = '' if client_city is None else client_city
        self.client_country = '' if client_country is None else client_country
        self.client_tax_id = '' if client_tax_id is None else client_tax_id
        self.client_language = 'en' if client_language is None else client_language

        # project default values
        self.project_title = '{PROJECT_COUNT}' if project_title is None else project_title
        self._project_hours_per_day = 0
        self.set_project_hours_per_day(project_hours_per_day)
        self._project_work_days = [0, 1, 2, 3, 4]
        self.set_project_work_days(project_work_days)
        self._project_minimum_days = 2
        self.set_project_minimum_days(project_minimum_days)
        self._project_wage = Decimal(0)
        self.set_project_wage(project_wage)

        # baseentry default values
        self.baseentry_title = '' if baseentry_title is None else baseentry_title
        self.baseentry_comment = '' if baseentry_comment is None else baseentry_comment
        self._baseentry_quantity = QuantityTime(baseentry_quantity)
        self.baseentry_quantity_format = (
            '' if baseentry_quantity_format is None
            else baseentry_quantity_format
        )
        if baseentry_quantity_b is None:
            self._baseentry_quantity_b = QuantityTime(1)
        else:
            self._baseentry_quantity_b = QuantityTime(baseentry_quantity_b)
        self.baseentry_quantity_b_format = (
            '' if baseentry_quantity_b_format is None
            else baseentry_quantity_b_format
        )
        self._baseentry_time = QuantityTime(baseentry_time)
        self._baseentry_price = Decimal(0)
        self.set_baseentry_price(baseentry_price)

        # multiplyentry default values
        self.multiplyentry_title = (
            '' if multiplyentry_title is None
            else multiplyentry_title
        )
        self.multiplyentry_comment = (
            '' if multiplyentry_comment is None
            else multiplyentry_comment
        )
        self._multiplyentry_quantity = QuantityTime(multiplyentry_quantity)
        self.multiplyentry_quantity_format = (
            '' if multiplyentry_quantity_format is None
            else multiplyentry_quantity_format
        )
        if multiplyentry_quantity_b is None:
            self._multiplyentry_quantity_b = QuantityTime(1)
        else:
            self._multiplyentry_quantity_b = QuantityTime(multiplyentry_quantity_b)
        self.multiplyentry_quantity_b_format = (
            '' if multiplyentry_quantity_b_format is None
            else multiplyentry_quantity_b_format
        )
        self._multiplyentry_hour_rate = QuantityTime(multiplyentry_hour_rate)

        # connectentry default values
        self.connectentry_title = (
            '' if connectentry_title is None else connectentry_title
        )
        self.connectentry_comment = (
            '' if connectentry_comment is None else connectentry_comment
        )
        self._connectentry_quantity = QuantityTime(connectentry_quantity)
        self.connectentry_quantity_format = (
            '' if connectentry_quantity_format is None
            else connectentry_quantity_format
        )
        if connectentry_quantity_b is None:
            self._connectentry_quantity_b = QuantityTime(1)
        else:
            self._connectentry_quantity_b = QuantityTime(connectentry_quantity_b)
        self.connectentry_quantity_b_format = (
            '' if connectentry_quantity_b_format is None
            else connectentry_quantity_b_format
        )
        self.set_connectentry_is_time(
            True if connectentry_is_time is None else connectentry_is_time
        )
        self._connectentry_multiplicator = Decimal(0)
        self.set_connectentry_multiplicator(connectentry_multiplicator)

        # ledger time
        self.ledger_time_def_quantity = (
            '1' if ledger_time_def_quantity is None else ledger_time_def_quantity
        )

        # try to load default automatically
        if data_path is not None:
            self.load_settings_from_file(data_path)
示例#9
0
class MultiplyEntry(BaseEntry):
    """
    A multiplying entry.

    This entry type is similar to the BaseEntry, except that
    it calculates the time according to a given hour_rate value.
    The class has a new value "hour_rate" which will be multiplicated
    by the quantity and thus calculates the time.
    """

    def __init__(
        self,
        id=None,
        title=None,
        comment=None,
        quantity=None,
        quantity_format=None,
        quantity_b=None,
        quantity_b_format=None,
        tax=None,
        hour_rate=None,
        wage_add=None,
        wage_add_explain=None
    ):
        """Initialize the class."""
        # values of the BaseEntry class
        super(MultiplyEntry, self).__init__(
            id=id,
            title=title,
            comment=comment,
            quantity=quantity,
            quantity_format=quantity_format,
            quantity_b=quantity_b,
            quantity_b_format=quantity_b_format,
            tax=tax
        )

        # new values for this class
        self._hour_rate = QuantityTime(hour_rate)
        self._wage_add = QuantityTime(wage_add)
        self.wage_add_explain = '' if wage_add_explain is None else str(wage_add_explain)

    def set_time(self, value):
        """Disable the function."""
        pass

    def get_time(self, *args, **kwargs):
        """Get own quantity * own hour as time."""
        out = self._quantity * self._quantity_b * self._hour_rate
        out.type('time')
        return out

    def set_price(self, value):
        """Disable function."""
        pass

    def get_price(self, wage=Decimal('0.00'), round_price=False, *args, **kwargs):
        """Get own time * wage as price."""
        if round_price:
            rounder = 0
        else:
            rounder = 2
        return round(
            self.get_time(*args, **kwargs).get() * (wage + self._wage_add.get()),
            rounder
        )

    def set_hour_rate(self, value):
        """Set hour_rate."""
        self._hour_rate.set(value)

    def get_hour_rate(self):
        """Get hour_rate."""
        return self._hour_rate

    def set_wage_add(self, value):
        """Set wage_add."""
        self._wage_add.set(value)

    def get_wage_add(self):
        """Get wage_add."""
        return self._wage_add

    def to_dict(self):
        """Convert object to dict."""
        out = {}

        # fetch all important data for this entry type
        out['type'] = self.__class__.__name__
        out['id'] = self.get_id()
        out['title'] = self.title
        out['comment'] = self.comment
        out['quantity'] = str(self._quantity)
        out['quantity_format'] = self.quantity_format
        out['quantity_b'] = str(self._quantity_b)
        out['quantity_b_format'] = self.quantity_b_format
        out['tax'] = float(self._tax)
        out['hour_rate'] = str(self._hour_rate)
        out['wage_add'] = str(self._wage_add)
        out['wage_add_explain'] = self.wage_add_explain

        return out

    def to_json(self, indent=2, ensure_ascii=False):
        """Convert all data to json format."""
        return json.dumps(
            self.to_dict(),
            indent=indent,
            ensure_ascii=ensure_ascii,
            sort_keys=True
        )

    @classmethod
    def from_json(cls, js=None, keep_id=True):
        """Convert all data from json format."""
        if js is None:
            return cls()

        # get js as dict
        if type(js) is not dict:
            try:
                js = json.loads(js)
            except Exception:
                # return default object
                return cls()

        # create new entry object from json

        # get ID if it's no preset_loading
        if not keep_id:
            id = None
        elif keep_id is True:
            if 'id' in js.keys():
                id = js['id']
            else:
                id = None
        else:
            id = str(keep_id)

        # get other values
        if 'title' in js.keys():
            title = js['title']
        else:
            title = None

        if 'comment' in js.keys():
            comment = js['comment']
        else:
            comment = None

        if 'quantity' in js.keys():
            quantity = js['quantity']
        else:
            quantity = None

        if 'quantity_format' in js.keys():
            quantity_format = js['quantity_format']
        else:
            quantity_format = None

        if 'quantity_b' in js.keys():
            quantity_b = js['quantity_b']
        else:
            quantity_b = None

        if 'quantity_b_format' in js.keys():
            quantity_b_format = js['quantity_b_format']
        else:
            quantity_b_format = None

        if 'tax' in js.keys():
            tax = js['tax']
        else:
            tax = None

        if 'hour_rate' in js.keys():
            hour_rate = js['hour_rate']
        else:
            hour_rate = None

        if 'wage_add' in js.keys():
            wage_add = js['wage_add']
        else:
            wage_add = None

        if 'wage_add_explain' in js.keys():
            wage_add_explain = js['wage_add_explain']
        else:
            wage_add_explain = None

        return cls(
            id=id,
            title=title,
            comment=comment,
            quantity=quantity,
            quantity_format=quantity_format,
            quantity_b=quantity_b,
            quantity_b_format=quantity_b_format,
            tax=tax,
            hour_rate=hour_rate,
            wage_add=wage_add,
            wage_add_explain=wage_add_explain
        )

    def copy(self, keep_id=True):
        """Return a copy of this object."""
        return MultiplyEntry().from_json(js=self.to_json(), keep_id=keep_id)
示例#10
0
 def get_time_zero(self, *args, **kwargs):
     """Get time as '-' if time is 0, else str of time."""
     if self.get_time(*args, **kwargs) == QuantityTime(0):
         return '-'
     else:
         return str(self.get_time(*args, **kwargs))
示例#11
0
class BaseEntry(object):
    """A very simple entry with basic options and FIXED values."""

    def __init__(
        self,
        id=None,
        title=None,
        comment=None,
        quantity=None,
        quantity_format=None,
        quantity_b=None,
        quantity_b_format=None,
        tax=None,
        time=None,
        price=None,
        connected=None
    ):
        """Init the class."""
        # gen ID if not set, otherwise get it from argument
        self._id = str(uuid.uuid1()) if id is None else str(id)

        # get other variables from arguments
        self.title = '' if title is None else str(title)
        self.comment = '' if comment is None else str(comment)
        self._quantity = QuantityTime(quantity)
        self.quantity_format = '' if quantity_format is None else str(quantity_format)
        if quantity_b is None:
            self._quantity_b = QuantityTime(1)
        else:
            self._quantity_b = QuantityTime(quantity_b)
        self.quantity_b_format = (
            '' if quantity_b_format is None else str(quantity_b_format)
        )
        self._tax = Decimal(0)                  # set default
        self.set_tax(tax)                       # try to set arguments value
        self._time = QuantityTime(time)
        self._price = Decimal(0)                # set default
        self.set_price(price)                   # try to set arguments value

        # get the connected list (for ConnectEntry only)
        if type(connected) is set:
            self._connected = connected
        else:
            self._connected = set()

    def get_id(self):
        """Get id."""
        return self._id

    def set_quantity(self, value):
        """Set quantity."""
        self._quantity.set(value)

    def get_quantity(self):
        """Get quantity."""
        return self._quantity

    def get_quantity_str(self, fmt=None):
        """Get self._quantity as string."""
        return self.get_quantity_universal_str(
            fmt=fmt,
            quantity=self._quantity,
            quantity_fmt=self.quantity_format
        )

    def set_quantity_b(self, value):
        """Set quantity_b."""
        self._quantity_b.set(value)

    def get_quantity_b(self):
        """Get quantity_b."""
        return self._quantity_b

    def get_quantity_b_str(self, fmt=None):
        """Get self._quantity_b as string."""
        return self.get_quantity_universal_str(
            fmt=fmt,
            quantity=self._quantity_b,
            quantity_fmt=self.quantity_b_format
        )

    def get_quantity_universal_str(self, fmt=None, quantity=None, quantity_fmt=None):
        """
        Get quantity as string with possible formatting.

        In case the offer is for music production for example, it would
        be good if the quantity of the offer posting would not be listed
        as a decimal rather than a readable time format. So instead of
        "1.5 min" -> "1:30 min" or similar. With the following format
        options you can achieve this - also with leading zeros:

        {s}: standard automatic quantity
        {d}: quantity in decimal
        {F}: quantity converted to time, show full
        {R}: quantity converted to time, show remaining

        Means that 1.5 with fmt == "{F}:{R}" would output 0:01, while
        fmt == "{F}:{R}" would output 1:30. 61.75 with
        """
        if type(quantity) is not QuantityTime:
            return str(fmt)

        # get self.quantity_format if no argument is given
        if fmt is None:
            fmt = quantity_fmt

        # is this also is empty, get '{s}' as default output
        # (so that it shows the default at least)
        if fmt == '':
            fmt = '{s}'

        # init formating output variable
        format_me = {}

        # get format_me
        format_me['s'] = quantity
        format_me['d'] = quantity.get()
        format_me['F'] = quantity.full()
        format_me['R'] = quantity.remain()

        # {F} exists
        if '{F}' in fmt:
            # correct leading zeros
            fmt = fmt.replace('{R}', '{R:02}')

        # output the stuff
        try:
            return fmt.format(**format_me)
        except Exception:
            # if any wrong {...} are given
            return fmt

    def set_tax(self, value):
        """Set tax."""
        # check if value is decimal
        try:
            is_percent = True if float(value) > 1.0 else False
        except Exception:
            is_percent = False

        # try to set a new tax
        try:
            # only works, if input is integer, float or string
            if is_percent:
                self._tax = Decimal(str(value)) / 100
            else:
                self._tax = Decimal(str(value))
        except Exception:
            # otherwise don't do anything
            pass

    def get_tax(self, *args, **kwargs):
        """Get tax."""
        return self._tax

    def get_tax_percent(self, *args, **kwargs):
        """Get tax."""
        return self._tax * 100

    def set_time(self, value):
        """Set time."""
        self._time.set(value)

    def get_time(self, *args, **kwargs):
        """Get time."""
        self._time.type('time')
        return self._time * self._quantity * self._quantity_b

    def get_time_raw(self, *args, **kwargs):
        """Get raw time value."""
        self._time.type('time')
        return self._time

    def get_time_zero(self, *args, **kwargs):
        """Get time as '-' if time is 0, else str of time."""
        if self.get_time(*args, **kwargs) == QuantityTime(0):
            return '-'
        else:
            return str(self.get_time(*args, **kwargs))

    def set_price(self, value):
        """Set price."""
        # try to set a new price
        try:
            # only works, if input is integer, float or string
            self._price = round(Decimal(str(value)), 2)
        except Exception:
            # otherwise don't do anything
            pass

    def get_price(self, round_price=False, *args, **kwargs):
        """Get price."""
        if round_price:
            rounder = 0
        else:
            rounder = 2
        return round(self._price * self._quantity.get() * self._quantity_b.get(), rounder)

    def get_unit_price(self, round_price=False, *args, **kwargs):
        """Get price / quantity."""
        quantities = self._quantity.get()

        # decomment next line for getting unit price divided by quantity b as well!
        # quantities = self._quantity.get() * self._quantity_b.get()

        # divide with quantity, if its > 0
        if quantities > 0:
            return round(
                self.get_price(
                    round_price=round_price,
                    *args,
                    **kwargs
                ) / quantities,
                2
            )

        # fallback output: simple get_price
        else:
            return round(
                self.get_price(
                    round_price=round_price,
                    *args,
                    **kwargs
                ),
                2
            )

    def get_price_raw(self):
        """Get raw price value."""
        return self._price

    def get_price_tax(self, *args, **kwargs):
        """Get tax of the price."""
        return round(
            self._tax * self.get_price(
                *args,
                **kwargs
            ),
            2
        )

    def get_unit_price_tax(self, *args, **kwargs):
        """Get price_tax / quantity."""
        quantities = self._quantity.get()

        # decomment next line for getting unit price divided by quantity b as well!
        # quantities = self._quantity.get() * self._quantity_b.get()

        # divide with quantity, if its > 0
        if quantities > 0:
            return round(
                self.get_price_tax(
                    *args,
                    **kwargs
                ) / quantities,
                2
            )

        # fallback output: simple get_price_tax
        else:
            return round(
                self.get_price_tax(
                    *args,
                    **kwargs
                ),
                2
            )

    def get_connected(self):
        """Get connected set."""
        return self._connected

    def to_dict(self):
        """Convert all data to a dict."""
        out = {}

        # fetch all important data for this entry type
        out['type'] = self.__class__.__name__
        out['id'] = self.get_id()
        out['title'] = self.title
        out['comment'] = self.comment
        out['quantity'] = str(self._quantity)
        out['quantity_format'] = self.quantity_format
        out['quantity_b'] = str(self._quantity_b)
        out['quantity_b_format'] = self.quantity_b_format
        out['tax'] = float(self._tax)
        out['time'] = str(self._time)
        out['price'] = float(self._price)

        return out

    def to_json(self, indent=2, ensure_ascii=False):
        """Convert all data to json format."""
        return json.dumps(
            self.to_dict(),
            indent=indent,
            ensure_ascii=ensure_ascii,
            sort_keys=True
        )

    @classmethod
    def from_json(cls, js=None, keep_id=True):
        """Convert all data from json format."""
        if js is None:
            return cls()

        # get js as dict
        if type(js) is not dict:
            try:
                js = json.loads(js)
            except Exception:
                # return default object
                return cls()

        # create new entry object from json

        # get ID if it's no preset_loading
        if not keep_id:
            id = None
        elif keep_id is True:
            if 'id' in js.keys():
                id = js['id']
            else:
                id = None
        else:
            id = str(keep_id)

        # get other values
        if 'title' in js.keys():
            title = js['title']
        else:
            title = None

        if 'comment' in js.keys():
            comment = js['comment']
        else:
            comment = None

        if 'quantity' in js.keys():
            quantity = js['quantity']
        else:
            quantity = None

        if 'quantity_format' in js.keys():
            quantity_format = js['quantity_format']
        else:
            quantity_format = None

        if 'quantity_b' in js.keys():
            quantity_b = js['quantity_b']
        else:
            quantity_b = None

        if 'quantity_b_format' in js.keys():
            quantity_b_format = js['quantity_b_format']
        else:
            quantity_b_format = None

        if 'tax' in js.keys():
            tax = js['tax']
        else:
            tax = None

        if 'time' in js.keys():
            time = js['time']
        else:
            time = None

        if 'price' in js.keys():
            price = js['price']
        else:
            price = None

        return cls(
            id=id,
            title=title,
            comment=comment,
            quantity=quantity,
            quantity_format=quantity_format,
            quantity_b=quantity_b,
            quantity_b_format=quantity_b_format,
            tax=tax,
            time=time,
            price=price
        )

    def copy(self, keep_id=True):
        """Return a copy of this object."""
        return BaseEntry().from_json(js=self.to_json(), keep_id=keep_id)

    def is_project(self, project=None):
        """
        Check if given argument is project object.

        This is some kind of workaround, since I canot import the Project class
        into Offer module due to circular dependencies. Do I really still have
        a that bad programm manufacture? )=
        """
        try:
            return project.i_am_project()
        except Exception:
            return False

    def return_changed_type(
        self,
        into='BaseEntry',
        entry_list=None,
        wage=None,
        project=None,
        round_price=None
    ):
        """Return the own entry object into other entry object."""
        # return changed into MultiplyEntry
        if into == 'MultiplyEntry':
            new_entry = MultiplyEntry(
                id=self.get_id(),
                title=self.title,
                comment=self.comment,
                quantity=self.get_quantity(),
                quantity_format=self.quantity_format,
                quantity_b=self.get_quantity_b(),
                quantity_b_format=self.quantity_b_format,
                tax=self.get_tax()
            )

            return new_entry

        # return changed into ConnectEntry
        elif into == 'ConnectEntry':
            new_entry = ConnectEntry(
                id=self.get_id(),
                title=self.title,
                comment=self.comment,
                quantity=self.get_quantity(),
                quantity_format=self.quantity_format,
                quantity_b=self.get_quantity_b(),
                quantity_b_format=self.quantity_b_format,
                tax=self.get_tax()
            )

            return new_entry

        # return changed into BaseEntry (also as fallback if into argument is invalid)
        else:
            new_entry = BaseEntry(
                id=self.get_id(),
                title=self.title,
                comment=self.comment,
                quantity=self.get_quantity(),
                quantity_format=self.quantity_format,
                quantity_b=self.get_quantity_b(),
                quantity_b_format=self.quantity_b_format,
                tax=self.get_tax(),
                price=self.get_price(
                    entry_list=entry_list,
                    wage=wage,
                    round_price=round_price
                ),
                time=self.get_time(
                    entry_list=entry_list
                )
            )

            return new_entry
示例#12
0
def test_integrety_entry():
    """Test if BaseEntry, ConnectEntry and MultiplyEntry work as they should."""
    a = BaseEntry(title='Title A',
                  comment='Comment A',
                  quantity=1.0,
                  time=1.0,
                  price=50.00)

    b = MultiplyEntry(title='Title B',
                      comment='Comment B',
                      quantity=2.0,
                      hour_rate=0.5)

    c = ConnectEntry(title='Title C',
                     comment='Comment C',
                     quantity=2.5,
                     is_time=False,
                     multiplicator=0.5)

    d = ConnectEntry(title='Title D',
                     comment='Comment D',
                     quantity=3.0,
                     is_time=True,
                     multiplicator=0.75)

    # init entries in list
    entries = []
    entries.append(a)
    entries.append(b)
    entries.append(c)
    entries.append(d)

    # connect first two entries two the first ConnectEntry
    entries[2].connect_entry(entry_list=entries, entry_id=entries[0].get_id())
    entries[2].connect_entry(entry_list=entries, entry_id=entries[1].get_id())

    # connect first ConnectEntry to the second ConnectEntry
    entries[3].connect_entry(entry_list=entries, entry_id=entries[2].get_id())

    # connect second ConnectEntry to the first ConnectEntry
    # and it should not work anymore
    entries[2].connect_entry(entry_list=entries, entry_id=entries[3].get_id())
    assert entries[3].get_id() not in entries[2].get_connected()

    # connect MultiplyEntry to the second ConnectEntry
    entries[3].connect_entry(entry_list=entries, entry_id=entries[1].get_id())

    # set wage to work with
    wage = Decimal('50.00')

    # check values for BaseEntry
    assert entries[0].title == 'Title A'
    assert entries[0].comment == 'Comment A'
    assert entries[0].get_quantity() == Decimal('1.0')
    assert entries[0].get_time() == QuantityTime(1.0)
    assert entries[0].get_price() == Decimal('50.00')

    # check values for MultiplyEntry
    assert entries[1].title == 'Title B'
    assert entries[1].comment == 'Comment B'
    assert entries[1].get_quantity() == Decimal('2.0')
    assert entries[1].get_hour_rate() == QuantityTime(0.5)
    assert entries[1].get_time() == QuantityTime(1.0)
    assert entries[1].get_price(wage=wage) == Decimal('50.00')

    # check values for first ConnectEntry
    assert entries[2].title == 'Title C'
    assert entries[2].comment == 'Comment C'
    assert entries[2].get_quantity() == Decimal('2.5')
    assert entries[2].get_is_time() is False
    assert entries[2].get_time(entry_list=entries) == QuantityTime(0)
    assert entries[2].get_price(entry_list=entries,
                                wage=wage) == Decimal('125.00')

    # check values for second ConnectEntry
    assert entries[3].title == 'Title D'
    assert entries[3].comment == 'Comment D'
    assert entries[3].get_quantity() == Decimal('3.0')
    assert entries[3].get_is_time() is True
    assert entries[3].get_time(entry_list=entries) == QuantityTime('2:15:00')
    assert entries[3].get_price(entry_list=entries,
                                wage=wage) == Decimal('112.50')