def test_offer_wage_zero(): """ Normally you can get project as argument to get its wage, if own is 0. The fallback however should return 0 as wage, when offer wage is zero. """ # test offer wage getter on its own offer_wage_test = Offer(wage=0) assert offer_wage_test.get_wage() == Decimal(0) # now test it with a project linked to it proj = Project(wage=10) assert offer_wage_test.get_wage(project=proj) == Decimal(10)
class TestOfferB(object): """Simple test offer.""" # generate some example entries b = BaseEntry( title='Base title', comment='Base comment', quantity=1, time=2.5, price=125 ) m = MultiplyEntry( title='Multiply title', comment='Multiply comment', quantity=0.5, hour_rate=4 ) c = MultiplyEntry( title='Multiply title 2', comment='Multiply comment 2', quantity=4, hour_rate=3.15 ) d = ConnectEntry( title='Connect title 2', comment='Connect comment 2', quantity=9, is_time=False, multiplicator=0.25 ) # init the offer out = Offer( title='Testing offer B' ) # add entries to its list out.append(b) out.append(m) out.append(c) out.append(d) # connect 2nd entry to 4th entry out.get_entry_list()[3].connect_entry( entry_list=out.get_entry_list(), entry_id=out.get_entry_list()[1].get_id() ) # 4th entry get_price() should now return 0.5 * 4 * 9 * 0.25 * 50.00 = 225.00 wage = Decimal('50.00') p = round(Decimal(0.5 * 4 * 9 * 0.25) * wage, 2) assert out.get_entry_list()[3].get_price( entry_list=out.get_entry_list(), wage=wage ) == p assert len(out.get_entry_list()) == 4
class TestOffer(object): """Simple test offer.""" # generate some example entries b = BaseEntry(title='Base title', comment='Base comment', quantity=1, time=2.5, price=125) m = MultiplyEntry(title='Multiply title', comment='Multiply comment', quantity=0.5, hour_rate=4) c = ConnectEntry(title='Connect title', comment='Connect comment', quantity=3, is_time=True, multiplicator=2) # init the offer out = Offer(title='Testing offer') # add entries to its list out.append(b) out.append(m) out.append(c) assert len(out.get_entry_list()) == 3
def PresetOffer( offer_preset=None, settings=None, global_list=None, client=None, project=None, replace=False ): """Return new Offer based on given offer, but with string replacements.""" if type(offer_preset) is not Offer: return NewOffer( settings=settings, global_list=global_list, client=client, project=project ) # get replaces replace_dict = replacer( settings=settings, global_list=global_list, client=client, project=project, offerinvoice=offer_preset ) title = offer_preset.title.format_map(replace_dict) comment = offer_preset.comment.format_map(replace_dict) comment_b = offer_preset.comment_b.format_map(replace_dict) # dates off_date = offer_preset.get_date() if not replace and off_date is not None: off_date = date.today() elif replace and off_date is None: off_date = date.today() # get other values date_fmt = offer_preset.date_fmt wage = offer_preset.get_wage() commodity = offer_preset.commodity round_price = offer_preset.get_round_price() entry_list = offer_preset.get_entry_list() # return new Offer object return Offer( title=title, comment=comment, comment_b=comment_b, date_fmt=date_fmt, date=off_date, wage=wage, commodity=commodity, round_price=round_price, entry_list=entry_list )
def test_offer_date(): """Set offer date.""" da = Offer(date=date(1987, 10, 15)) assert da.get_date() == date(1987, 10, 15) da.set_date('1992-08-02') assert da.get_date() == date(1992, 8, 2)
def load_offer_list_from_js(self, lis=None): """Convert list to offer object list.""" offer_list = [] # cycle through the list of dicts for offer in lis: # it should have a type key if 'type' in offer.keys(): # this type key should be "Offer" if offer['type'] == 'Offer': # convert this dict to an offer objetc then! offer_list.append(Offer().from_json(js=offer)) return offer_list
def NewOffer(settings=None, global_list=None, client=None, project=None): """Return new offer object according to settings defaults.""" # return empty offer, if there is no correct settings object given is_settings = type(settings) is Settings is_client = type(client) is Client is_project = type(project) is Project if not is_settings or not is_project or not is_client: return Offer() # get language from client lang = client.language # get replaces replace_dict = replacer( settings=settings, global_list=global_list, client=client, project=project ) title = settings.defaults[lang].offer_title.format_map(replace_dict) comment = settings.defaults[lang].offer_comment.format_map(replace_dict) comment_b = settings.defaults[lang].offer_comment_b.format_map(replace_dict) # get other values date_fmt = settings.defaults[lang].date_fmt round_price = settings.defaults[lang].get_offer_round_price() # return new Offer object return Offer( title=title, comment=comment, comment_b=comment_b, date_fmt=date_fmt, date=date.today(), commodity=client.def_commodity, round_price=round_price )
def load_item_from_file(self, filename=None): """Load the item from the file.""" filename = str(filename) # cancel if the file does not exist if not os.path.isfile(filename): return False # try to load the file try: with open(filename, 'r') as f: dic = json.load(f) except Exception: return False # get type typ = False if 'item' in dic.keys(): if 'type' in dic['item'].keys(): typ = dic['item']['type'] # has no type, so cancel if not typ: return False # convert item json to Offer if typ == 'Offer': dic['item'] = Offer().from_json(js=dic['item']) # convert item json to Invoice elif typ == 'Invoice': dic['item'] = Invoice().from_json(js=dic['item']) # convert item json to BaseEntry elif typ == 'BaseEntry': dic['item'] = BaseEntry().from_json(js=dic['item']) # convert item json to MultiplyEntry elif typ == 'MultiplyEntry': dic['item'] = MultiplyEntry().from_json(js=dic['item']) # convert item json to ConnectEntry elif typ == 'ConnectEntry': dic['item'] = ConnectEntry().from_json(js=dic['item']) # otherwise cancel else: return False return dic
def test_project_copy(): """Copy a project.""" a = Project( title='Project A' ) a.append_offer(Offer( title='Offer A' )) b = a.copy() # both should have the same title assert a.title == b.title # both also should have one offer with the same title assert a.get_offer_list()[0].title == b.get_offer_list()[0].title
def test_offer_copy(): """Convert offer and convert it back.""" a = Offer(title='Testuel', date_fmt='%d.%m.%Y', date='2017-01-01', wage=Decimal('50.0'), round_price=True) b = a.copy() # both have the same assert a.title == b.title assert a.date_fmt == b.date_fmt assert a.get_date() == b.get_date() assert a.get_wage() == b.get_wage() a.title = 'other' a.date_fmt = '%d. in %m, %Y' a.set_date(date.today()) a.set_wage('40.0') # both now don't have the same assert a.title != b.title assert a.date_fmt != b.date_fmt assert a.get_date() != b.get_date() assert a.get_wage() != b.get_wage()
def test_price_total(): """Test the total methods.""" off = Offer() off.append(BaseEntry(quantity=1.0, price=100.0, tax=19)) off.append(BaseEntry(quantity=1.0, price=10.0, tax=7)) off.append(ConnectEntry(quantity=1.0, tax=19, multiplicator=1)) off.get_entry_list()[2].connect_entry( entry_list=off.get_entry_list(), entry_id=off.get_entry_list()[1].get_id()) wage = Decimal('50.00') assert off.get_price_total(wage=wage) == Decimal('120') assert off.get_price_tax_total(wage=wage) == Decimal('21.6')
def onStart(self): """Create all the forms and variables, which are needed.""" # get global variables for the app self.S = Settings() self.L = List(data_path=self.S.data_path) self.L.update_inactive_list(settings=self.S) self.P = Preset(data_path=self.S.data_path) self.P_what = 'offer' self.H = 'Fallback helptext is: learn by doing! (;' # set global temp variables self.tmpDefault = Default() self.tmpDefault_new = True self.tmpClient = Client() self.tmpClient_new = True self.tmpProject = Project() self.tmpProject_new = True self.tmpOffer = Offer() self.tmpOffer_new = True self.tmpOffer_index = -1 self.tmpInvoice = Invoice() self.tmpInvoice_new = True self.tmpInvoice_index = -1 self.tmpEntry = BaseEntry() self.tmpEntry_new = True self.tmpEntry_index = -1 self.tmpEntry_change_type = False self.tmpEntry_offer_invoice = 'offer' # create the forms self.addForm('MAIN', MainForm, name='Freelance') self.addForm('Help', HelpForm, name='Freelance - Help') self.addForm('Settings', SettingsForm, name='Freelance > Settings') self.addForm('Defaults', DefaultsForm, name='Freelance > Settings > Defaults') self.addForm('Defaults_general', DefaultsGeneralForm, name='Freelance > Settings > Defaults > General') self.addForm('Defaults_offer', DefaultsOfferForm, name='Freelance > Settings > Defaults > Offer') self.addForm('Defaults_invoice', DefaultsInvoiceForm, name='Freelance > Settings > Defaults > Invoice') self.addForm('Defaults_clientproject', DefaultsClientProjectForm, name='Freelance > Settings > Defaults > Client / Project') self.addForm('Defaults_entry', DefaultsEntryForm, name='Freelance > Settings > Defaults > Entry') self.addForm('Client', ClientForm, name='Freelance > Client', color='NO_EDIT') self.addForm('Project', ProjectForm, name='Freelance > Project', color='NO_EDIT') self.addForm('Inactive', InactiveForm, name='Freelance > Inactive clients and projects', color='WARNING') self.addForm('Offer', OfferForm, name='Freelance > Project > Offer', color='NO_EDIT') self.addForm('Invoice', InvoiceForm, name='Freelance > Project > Invoice', color='NO_EDIT') self.addForm('UnpaidInvoice', UnpaidInvoiceForm, name='Freelance > Unpaid invoices', color='DANGER') self.addForm('AllInvoices', AllInvoicesForm, name='Freelance > All invoices', color='WARNING') self.addForm('EntryChoose', EntryChooseForm, name='Freelance > Project > Offer > Entry') self.addForm('BaseEntry', BaseEntryForm, name='Freelance > Project > Offer > Base entry', color='NO_EDIT') self.addForm('MultiplyEntry', MultiplyEntryForm, name='Freelance > Project > Offer > Multiply entry', color='NO_EDIT') self.addForm('ConnectEntry', ConnectEntryForm, name='Freelance > Project > Offer > Connect entry', color='NO_EDIT') self.addForm('Presets', PresetForm, name='Choose a preset', color='WARNING') self.addForm('Export', ExportForm, name='Choose a template')