def form_defaults(self): session = DBSession() company = session.query(Company).first() defaults = { 'currency': u'CHF', 'payment_term': 30, 'tax': company.tax, } if "invoice" in self.request.matchdict: invoice_id = self.request.matchdict['invoice'] invoice = session.query(Invoice).filter_by(id=invoice_id).first() if invoice: field_names = [ p.key for p in class_mapper(Invoice).iterate_properties ] form_fields = [field[0] for field in invoice_schema.attrs] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(invoice, field_name) defaults['payment_term'] = (invoice.due_date - invoice.date).days if invoice.recurring_date: defaults['recurring_term'] = (invoice.recurring_date - invoice.date).days else: defaults['recurring_term'] = None # Default values for the item subforms defaults['item_list'] = [] # Make test happy invoice.items.sort(key=lambda obj: obj.item_number) for item in invoice.items: item_defaults = {} field_names = [ p.key for p in class_mapper(InvoiceItem).iterate_properties ] form_fields = [ field[0] for field in invoice_item_schema.attrs ] for field_name in field_names: if field_name in form_fields: item_defaults[field_name] = getattr( item, field_name) item_defaults['item_id'] = item.id defaults['item_list'].append(item_defaults) return defaults
def test_handle_add(self): from seantisinvoice.models import Invoice from seantisinvoice.models import DBSession from seantisinvoice.views.invoice import InvoiceController # Register route for redirect in invoice form actions testing.registerRoute('/', 'invoices', factory=None) # Each invoice belongs to a customer, thus add one. customer = self._add_customer() request = testing.DummyRequest() view = InvoiceController(None, request) data = view.form_defaults() data['customer_contact_id'] = customer.contacts[0].id data['project_description'] = u'Project name' data['recurring_term'] = 30 data['date'] = datetime.date(2010, 1, 18) data['item_list'] = [ dict(item_id='', service_title=u'Testing', service_description=u'Work', amount=2000.0) ] view.handle_add(data) session = DBSession() invoice = session.query(Invoice).one() self.assertEquals(u'Project name', invoice.project_description) self.assertEquals(customer.contacts[0], invoice.contact) self.assertEquals(1, len(invoice.items)) self.assertEquals(u'Testing', invoice.items[0].service_title)
def form_defaults(self): defaults = {} if "customer" in self.request.matchdict: customer_id = self.request.matchdict['customer'] session = DBSession() customer = session.query(Customer).filter_by(id=customer_id).first() if customer: field_names = [ p.key for p in class_mapper(Customer).iterate_properties ] form_fields = [ field[0] for field in customer_schema.attrs ] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(customer, field_name) # Default values for the contact subforms defaults['contact_list'] = [] for contact in customer.contacts: contact_defaults = {} field_names = [ p.key for p in class_mapper(CustomerContact).iterate_properties ] form_fields = [ field[0] for field in customer_contact_schmema.attrs ] for field_name in field_names: if field_name in form_fields: contact_defaults[field_name] = getattr(contact, field_name) contact_defaults['contact_id'] = contact.id defaults['contact_list'].append(contact_defaults) return defaults
def test_next_invoice_number(self): from seantisinvoice.models import DBSession from seantisinvoice.models import Company from seantisinvoice.models import next_invoice_number session = DBSession() company = session.query(Company).one() company.invoice_start_number = 20 result = next_invoice_number() self.assertEqual(20, result) self.assertEqual(21, company.invoice_start_number)
def __call__(self): if "customer" in self.request.matchdict: customer_id = self.request.matchdict['customer'] session = DBSession() customer = session.query(Customer).filter_by(id=customer_id).first() if not customer: return Response(status = 404) main = get_template('templates/master.pt') return dict(request=self.request, main=main, msgs=statusmessage.messages(self.request))
def view_invoices(request): session = DBSession() query = session.query(Invoice) today = datetime.date.today() if 'recurring' in request.params: if request.params['recurring'] == '1': query = query.filter(Invoice.recurring_date != None) # We don't show the recurring invoices that have stop date in the past query = query.filter(Invoice.recurring_stop >= today or Invoice.recurring_stop == None) title = u'Recurring Invoices' elif request.params['recurring'] == '0': query = query.filter(Invoice.recurring_date == None) title = u'Non-recurring Invoices' elif 'due' in request.params and request.params['due'] == '1': query = query.filter(Invoice.due_date <= today) query = query.filter(Invoice.payment_date == None) title = u'Invoices due' else: title = u'All Invoices' # Sorting if 'sort' in request.params: sort_key = request.params['sort'] if hasattr(Invoice, sort_key): sort_attr = getattr(Invoice, sort_key) if 'reverse' in request.params: sort_attr = desc(sort_attr) query = query.order_by(sort_attr) else: query = query.order_by(desc(Invoice.date)) invoices = query.all() company = session.query(Company).first() main = get_template('templates/master.pt') return dict(request=request, main=main, invoices=invoices, company=company, title=title, msgs=statusmessage.messages(request), formatThousands=formatThousands)
def view_invoice_pdf(request): session = DBSession() company = session.query(Company).first() invoice_id = request.matchdict['invoice'] invoice = session.query(Invoice).filter_by(id=invoice_id).first() if not invoice: return Response(status=404) rml_template = 'templates/rml/' + company.invoice_template # Only jpeg without PIL logo_path = os.path.join(os.path.dirname(__file__), 'templates', 'static', 'uploads', 'logo.jpg') result = render_template(rml_template, invoice=invoice, logo_path=logo_path, formatThousands=formatThousands) response = Response(parseString(result.encode('utf-8')).read()) response.content_type = "application/pdf" return response
def __call__(self): if "invoice" in self.request.matchdict: session = DBSession() invoice_id = self.request.matchdict['invoice'] invoice = session.query(Invoice).filter_by(id=invoice_id).first() if not invoice: return Response(status = 404) main = get_template('templates/master.pt') return dict(request=self.request, main=main, msgs=statusmessage.messages(self.request))
def form_defaults(self): defaults = {} session = DBSession() company = session.query(Company).first() field_names = [p.key for p in class_mapper(Company).iterate_properties] form_fields = [field[0] for field in company_schema.attrs] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(company, field_name) return defaults
def form_defaults(self): defaults = {} session = DBSession() company = session.query(Company).first() field_names = [ p.key for p in class_mapper(Company).iterate_properties ] form_fields = [ field[0] for field in company_schema.attrs ] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(company, field_name) return defaults
def handle_submit(self, converted): session = DBSession() company = session.query(Company).first() changed = self._apply_data(company, converted) if changed: statusmessage.show(self.request, u"Changes saved.", "success") else: statusmessage.show(self.request, u"No changes saved.", "notice") return HTTPFound(location=route_url('company', self.request))
def form_widgets(self, fields): widgets = {} widgets['from_date'] = formish.DateParts(day_first=True) widgets['to_date'] = formish.DateParts(day_first=True) session = DBSession() query = session.query(Customer).order_by(Customer.name) options = [] for customer in query.all(): options.append((customer.id, customer.name)) widgets['customer'] = formish.SelectChoice(options=options) return widgets
def form_defaults(self): session = DBSession() company = session.query(Company).first() defaults = { 'currency' : u'CHF', 'payment_term' : 30, 'tax' : company.tax, } if "invoice" in self.request.matchdict: invoice_id = self.request.matchdict['invoice'] invoice = session.query(Invoice).filter_by(id=invoice_id).first() if invoice: field_names = [ p.key for p in class_mapper(Invoice).iterate_properties ] form_fields = [ field[0] for field in invoice_schema.attrs ] for field_name in field_names: if field_name in form_fields: defaults[field_name] = getattr(invoice, field_name) defaults['payment_term'] = (invoice.due_date - invoice.date).days if invoice.recurring_date: defaults['recurring_term'] = (invoice.recurring_date - invoice.date).days else: defaults['recurring_term'] = None # Default values for the item subforms defaults['item_list'] = [] # Make test happy invoice.items.sort(key=lambda obj: obj.item_number) for item in invoice.items: item_defaults = {} field_names = [ p.key for p in class_mapper(InvoiceItem).iterate_properties ] form_fields = [ field[0] for field in invoice_item_schema.attrs ] for field_name in field_names: if field_name in form_fields: item_defaults[field_name] = getattr(item, field_name) item_defaults['item_id'] = item.id defaults['item_list'].append(item_defaults) return defaults
def handle_submit(self, converted): invoice_id = self.request.matchdict['invoice'] session = DBSession() invoice = session.query(Invoice).filter_by(id=invoice_id).one() changed = self._apply_data(invoice, converted) if changed: statusmessage.show(self.request, u"Changes saved.", "success") else: statusmessage.show(self.request, u"No changes saved.", "notice") return HTTPFound(location=route_url('invoices', self.request))
def __call__(self): if "invoice" in self.request.matchdict: session = DBSession() invoice_id = self.request.matchdict['invoice'] invoice = session.query(Invoice).filter_by(id=invoice_id).first() if not invoice: return Response(status=404) main = get_template('templates/master.pt') return dict(request=self.request, main=main, msgs=statusmessage.messages(self.request))
def handle_submit(self, converted): customer_id = self.request.matchdict['customer'] session = DBSession() customer = session.query(Customer).filter_by(id=customer_id).one() changed = self._apply_data(customer, converted) if changed: statusmessage.show(self.request, u"Changes saved.", "success") else: statusmessage.show(self.request, u"No changes saved.", "notice") return HTTPFound(location=route_url('customers', self.request))
def test_next_invoice_number_used(self): from seantisinvoice.models import DBSession from seantisinvoice.models import Company from seantisinvoice.models import Invoice from seantisinvoice.models import next_invoice_number session = DBSession() company = session.query(Company).one() company.invoice_start_number = 20 invoice = Invoice(invoice_number=20) session.add(invoice) session.flush() result = next_invoice_number() self.assertEqual(21, result) self.assertEqual(22, company.invoice_start_number)
def handle_add(self, converted): session = DBSession() invoice = Invoice() invoice.company = session.query(Company).first() self._apply_data(invoice, converted) session.add(invoice) # Get and add unique invoice number if invoice.invoice_number is None: invoice.invoice_number = next_invoice_number() statusmessage.show(self.request, u"Invoice added.", "success") return HTTPFound(location=route_url('invoices', self.request))
def _set_company_profile(self): from seantisinvoice.models import Company from seantisinvoice.models import DBSession session = DBSession() company = session.query(Company).one() company.name = u'Example Inc.' company.address1 = u'Main street 1' company.postal_code = u'1000' company.city = u'Somewhere' company.email = u'*****@*****.**' company.phone = u'1233456789' company.hourly_rate = 100.0 company.daily_rate = 1000.0 company.invoice_template = u'invoice_pdf.pt' return company
def _set_company_profile(self): from seantisinvoice.models import Company from seantisinvoice.models import DBSession session = DBSession() company = session.query(Company).one() company.name = u"Example Inc." company.address1 = u"Main street 1" company.postal_code = u"1000" company.city = u"Somewhere" company.email = u"*****@*****.**" company.phone = u"1233456789" company.hourly_rate = 100.0 company.daily_rate = 1000.0 company.invoice_template = u"invoice_pdf.pt" return company
def invoices(self): session = DBSession() query = session.query(Invoice) if self.from_date and self.to_date: query = query.filter(and_(Invoice.date >= self.from_date, Invoice.date <= self.to_date)) if self.customer is not None: query = query.filter(Customer.id == self.customer) query = query.join(Invoice.contact) query = query.join(CustomerContact.customer) query = query.order_by(desc(Invoice.date)) invoices = query.all() if invoices and (self.from_date is None or self.to_date is None): self.from_date = invoices[-1].date self.to_date = invoices[0].date return invoices
def test_handle_add(self): from seantisinvoice.models import Customer from seantisinvoice.models import DBSession from seantisinvoice.views.customer import CustomerController # Register route for redirect in customer form actions testing.registerRoute("/customers", "customers", factory=None) request = testing.DummyRequest() view = CustomerController(None, request) # Add a new customer data = dict(name=u"Customers Inc.", address1=u"Street", postal_code=u"12234", city=u"Dublin") data["contact_list"] = [dict(first_name=u"Buck", last_name=u"Mulligan", title=u"Mr.", contact_id="")] view.handle_add(data) session = DBSession() customer = session.query(Customer).one() self.assertEquals(u"Customers Inc.", customer.name) self.assertEquals(u"Buck", customer.contacts[0].first_name)
def form_widgets(self, fields): widgets = {} widgets['date'] = formish.DateParts(day_first=True) widgets['recurring_stop'] = formish.DateParts(day_first=True) widgets['payment_date'] = formish.DateParts(day_first=True) session = DBSession() options = [] query = session.query(CustomerContact.id, Customer.name, CustomerContact.first_name, CustomerContact.last_name) query = query.join(CustomerContact.customer) query = query.order_by(Customer.name, CustomerContact.last_name, CustomerContact.first_name) for (contact_id, company, first_name, last_name) in query.all(): options.append((contact_id, '%s: %s %s' % (company, first_name, last_name))) widgets['customer_contact_id'] = formish.SelectChoice(options=options) widgets['item_list'] = formish.SequenceDefault(min_start_fields=1) widgets['item_list.*.item_id'] = formish.Hidden() widgets['item_list.*.service_description'] = formish.TextArea() return widgets
def test_recurring(self): from seantisinvoice.models import DBSession from seantisinvoice.models import Invoice, InvoiceItem from seantisinvoice.recurring import copy_recurring session = DBSession() copy_recurring() self.assertEquals(0, session.query(Invoice).count()) # Add a new invoice invoice = Invoice() invoice_date = datetime.date.today() - datetime.timedelta(days=100) invoice.date = invoice_date invoice.due_date = datetime.date.today() - datetime.timedelta(days=70) invoice.project_description = u'Invoice project description' session.add(invoice) # Add an item to the invoice item = InvoiceItem() item.item_number = 0 item.amount = 1000 item.service_description = u'Item description' item.service_title = u'Invoice item' item.invoice = invoice session.merge(item) copy_recurring() # Invoice not cloned as it has no recurring_date self.assertEquals(1, session.query(Invoice).count()) invoice = session.query(Invoice).one() # Set the recurring date on the invoice recurring_date = datetime.date.today() - datetime.timedelta(days=70) invoice.recurring_date = recurring_date copy_recurring() # There are now two invoices self.assertEquals(2, session.query(Invoice).count()) invoice = session.query(Invoice).filter_by(date=invoice_date).one() # Recurring date of the original invoice has been reset self.failIf(invoice.recurring_date) cloned_invoice = session.query(Invoice).filter_by( date=recurring_date).one() # New invoice has the recurring date of the original one as date self.assertEquals(recurring_date, cloned_invoice.date) self.assertEquals(recurring_date + datetime.timedelta(days=30), cloned_invoice.recurring_date) # Check whether attributes on invoice and invoice item have been cloned self.assertEquals(invoice.project_description, cloned_invoice.project_description) cloned_item = cloned_invoice.items[0] self.assertEquals(item.amount, cloned_item.amount) self.assertEquals(item.service_description, cloned_item.service_description) self.assertEquals(item.service_title, cloned_item.service_title)
def copy_recurring(): today = datetime.date.today() session = DBSession() query = session.query(Invoice) query = query.filter(Invoice.recurring_date <= today) query = query.filter( or_(Invoice.recurring_stop == None, Invoice.recurring_stop > today)) for invoice in query.all(): # Clone invoice and invoice items invoice_clone = Invoice() invoice_clone.company = invoice.company invoice_clone.contact = invoice.contact invoice_clone.project_description = invoice.project_description invoice_clone.currency = invoice.currency invoice_clone.tax = invoice.tax session.add(invoice_clone) for item in invoice.items: item_clone = InvoiceItem() item_clone.item_number = item.item_number item_clone.amount = item.amount item_clone.hours = item.hours item_clone.days = item.days item_clone.service_description = item.service_description item_clone.service_title = item.service_title item_clone.invoice = invoice_clone session.add(item_clone) # Get new invoice number invoice_clone.invoice_number = next_invoice_number() # Adjust dates on cloned invoice invoice_clone.date = invoice.recurring_date invoice_clone.due_date = invoice_clone.date + (invoice.due_date - invoice.date) invoice_clone.recurring_date = invoice_clone.date + ( invoice.recurring_date - invoice.date) invoice_clone.recurring_stop = invoice.recurring_stop # Old invoice is not recurring anymore invoice.recurring_date = None transaction.commit()
def form_widgets(self, fields): widgets = {} widgets['date'] = formish.DateParts(day_first=True) widgets['recurring_stop'] = formish.DateParts(day_first=True) widgets['payment_date'] = formish.DateParts(day_first=True) session = DBSession() options = [] query = session.query(CustomerContact.id, Customer.name, CustomerContact.first_name, CustomerContact.last_name) query = query.join(CustomerContact.customer) query = query.order_by(Customer.name, CustomerContact.last_name, CustomerContact.first_name) for (contact_id, company, first_name, last_name) in query.all(): options.append( (contact_id, '%s: %s %s' % (company, first_name, last_name))) widgets['customer_contact_id'] = formish.SelectChoice(options=options) widgets['item_list'] = formish.SequenceDefault(min_start_fields=1) widgets['item_list.*.item_id'] = formish.Hidden() widgets['item_list.*.service_description'] = formish.TextArea() return widgets
def test_recurring(self): from seantisinvoice.models import DBSession from seantisinvoice.models import Invoice, InvoiceItem from seantisinvoice.recurring import copy_recurring session = DBSession() copy_recurring() self.assertEquals(0, session.query(Invoice).count()) # Add a new invoice invoice = Invoice() invoice_date = datetime.date.today() - datetime.timedelta(days=100) invoice.date = invoice_date invoice.due_date = datetime.date.today() - datetime.timedelta(days=70) invoice.project_description = u"Invoice project description" session.add(invoice) # Add an item to the invoice item = InvoiceItem() item.item_number = 0 item.amount = 1000 item.service_description = u"Item description" item.service_title = u"Invoice item" item.invoice = invoice session.merge(item) copy_recurring() # Invoice not cloned as it has no recurring_date self.assertEquals(1, session.query(Invoice).count()) invoice = session.query(Invoice).one() # Set the recurring date on the invoice recurring_date = datetime.date.today() - datetime.timedelta(days=70) invoice.recurring_date = recurring_date copy_recurring() # There are now two invoices self.assertEquals(2, session.query(Invoice).count()) invoice = session.query(Invoice).filter_by(date=invoice_date).one() # Recurring date of the original invoice has been reset self.failIf(invoice.recurring_date) cloned_invoice = session.query(Invoice).filter_by(date=recurring_date).one() # New invoice has the recurring date of the original one as date self.assertEquals(recurring_date, cloned_invoice.date) self.assertEquals(recurring_date + datetime.timedelta(days=30), cloned_invoice.recurring_date) # Check whether attributes on invoice and invoice item have been cloned self.assertEquals(invoice.project_description, cloned_invoice.project_description) cloned_item = cloned_invoice.items[0] self.assertEquals(item.amount, cloned_item.amount) self.assertEquals(item.service_description, cloned_item.service_description) self.assertEquals(item.service_title, cloned_item.service_title)
def copy_recurring(): today = datetime.date.today() session = DBSession() query = session.query(Invoice) query = query.filter(Invoice.recurring_date <= today) query = query.filter(or_(Invoice.recurring_stop == None, Invoice.recurring_stop > today)) for invoice in query.all(): # Clone invoice and invoice items invoice_clone = Invoice() invoice_clone.company = invoice.company invoice_clone.contact = invoice.contact invoice_clone.project_description = invoice.project_description invoice_clone.currency = invoice.currency invoice_clone.tax = invoice.tax session.add(invoice_clone) for item in invoice.items: item_clone = InvoiceItem() item_clone.item_number = item.item_number item_clone.amount = item.amount item_clone.hours = item.hours item_clone.days = item.days item_clone.service_description = item.service_description item_clone.service_title = item.service_title item_clone.invoice = invoice_clone session.add(item_clone) # Get new invoice number invoice_clone.invoice_number = next_invoice_number() # Adjust dates on cloned invoice invoice_clone.date = invoice.recurring_date invoice_clone.due_date = invoice_clone.date + (invoice.due_date - invoice.date) invoice_clone.recurring_date = invoice_clone.date + (invoice.recurring_date - invoice.date) invoice_clone.recurring_stop = invoice.recurring_stop # Old invoice is not recurring anymore invoice.recurring_date = None transaction.commit()
def test_handle_add(self): from seantisinvoice.models import Invoice from seantisinvoice.models import DBSession from seantisinvoice.views.invoice import InvoiceController # Register route for redirect in invoice form actions testing.registerRoute("/", "invoices", factory=None) # Each invoice belongs to a customer, thus add one. customer = self._add_customer() request = testing.DummyRequest() view = InvoiceController(None, request) data = view.form_defaults() data["customer_contact_id"] = customer.contacts[0].id data["project_description"] = u"Project name" data["recurring_term"] = 30 data["date"] = datetime.date(2010, 1, 18) data["item_list"] = [dict(item_id="", service_title=u"Testing", service_description=u"Work", amount=2000.0)] view.handle_add(data) session = DBSession() invoice = session.query(Invoice).one() self.assertEquals(u"Project name", invoice.project_description) self.assertEquals(customer.contacts[0], invoice.contact) self.assertEquals(1, len(invoice.items)) self.assertEquals(u"Testing", invoice.items[0].service_title)
def test_handle_add(self): from seantisinvoice.models import Customer from seantisinvoice.models import DBSession from seantisinvoice.views.customer import CustomerController # Register route for redirect in customer form actions testing.registerRoute('/customers', 'customers', factory=None) request = testing.DummyRequest() view = CustomerController(None, request) # Add a new customer data = dict(name=u'Customers Inc.', address1=u'Street', postal_code=u'12234', city=u'Dublin') data['contact_list'] = [ dict(first_name=u'Buck', last_name=u'Mulligan', title=u'Mr.', contact_id='') ] view.handle_add(data) session = DBSession() customer = session.query(Customer).one() self.assertEquals(u'Customers Inc.', customer.name) self.assertEquals(u'Buck', customer.contacts[0].first_name)
def view_customers(request): session = DBSession() customers = session.query(Customer).order_by(Customer.name).all() main = get_template('templates/master.pt') return dict(request=request, main=main, customers=customers, msgs=statusmessage.messages(request))