Currently orders support a "Customer" and "Administrator" view mode. However, we don't really have support for e-mailing "invoices" or receipts to customers beyond a simple textarea with order tokens. What I propose is adding a new "Invoice" view mode (though it might better be called "E-mail"?) that would be used for sending these types of e-mails. The view mode will let you make certain fields visible or not visible when e-mailing an order page. It will also allow modules to hook into it specifically using hook_commerce_order_view().

I'm not sure if we can have view mode specific templates, but we'll also need to figure out a way to ensure that the e-mailed invoice is passed through a theme function so it can generate e-mail safe HTML. Perhaps this can be handled through an API function that prepares an order for e-mail and then we can call that API function instead of just commerce_order_build_content() from the Rules action for e-mailing an invoice. Perhaps commerce_order_build_email_content()?

Comments

xibun’s picture

+1

xlyz’s picture

+1

btw invoices here (italy) can not be plain email, but shall be a pdf.

so my vote goes for calling it "E-mail" as well.

damien tournoud’s picture

Let's settle on 'email'. Those things are not technically invoices anyway, it's just an order summary sent by mail.

essbee’s picture

For those interested I have actually created an Invoice / printable order view just using Views and the Print module (http://drupal.org/project/print).

This gives a very customisable invoice/print display with header footer etc and also outputs nicely to PDF, thus also satisfying the PDF requirement. All themeable via CSS.

Potentially DC does not need this functionality inbuilt as core, but rather can leverage existing capabilities. This would align nicely to the ethos of stripping out functionality not actually core to commerce.

Cheers,
Sam

essbee’s picture

Oh, and by making the path of my order View /user/%/orders/% you override the existing User order view so all the existing links take you to your View outputted display, which provides the various print/pdf/email options.

arbel’s picture

is there anyway to send the "print" page to the user after an order is completed?

Scott J’s picture

Hey essbee,
I like your idea of using Views and Print module. Any chance of exporting your View so I can try it out?

WilliamV’s picture

Count me in on the example to test.

essbee’s picture

Sure thing. Here is the view. Note it is going to cause a few issues importing as I have added a bunch of fields to the order.

The customer field is a taxonomy reference - I have created a taxonomy of customers so I can leverage the taxonomy reference capabilities to attach a customer to an order. I also moved the customer profile reference from the order into the taxonomy ter.m As such all the customer information comes in via that reference.

I use globals to create header and footer with the company information, payment terms etc.

I also use the Print module to create PDF and Printable views of the page.

Hopefully it gives a general idea.


$view = new view;
$view->name = 'order';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'commerce_order';
$view->human_name = 'Order';
$view->core = 7;
$view->api_version = '3.0-alpha1';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['access']['type'] = 'role';
$handler->display->display_options['access']['role'] = array(
  3 => '3',
  4 => '4',
  5 => '5',
  6 => '6',
);
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Header: Global: Text area */
$handler->display->display_options['header']['area']['id'] = 'area';
$handler->display->display_options['header']['area']['table'] = 'views';
$handler->display->display_options['header']['area']['field'] = 'area';
$handler->display->display_options['header']['area']['label'] = 'Header';
$handler->display->display_options['header']['area']['empty'] = FALSE;
$handler->display->display_options['header']['area']['content'] = '<p style="margin: 0;"><img src="/sites/all/themes/THEMENAME/logo.png" width="217.7px" height="117.6px" style="float: left; margin-right: auto; margin-top: 0;"></p><p style="text-align: right;">COMPANY Pty Ltd<br>ABN 12 345 678 901</p><p style="text-align: right;">COMPANY ADDRESS</p><p style="text-align: right;">Phone: 1234 123 123<br>email: test@test.com</p><h4 style="text-align: center;"><strong>TAX INVOICE</strong></h4>';
/* Footer: Global: Text area */
$handler->display->display_options['footer']['area']['id'] = 'area';
$handler->display->display_options['footer']['area']['table'] = 'views';
$handler->display->display_options['footer']['area']['field'] = 'area';
$handler->display->display_options['footer']['area']['empty'] = FALSE;
$handler->display->display_options['footer']['area']['content'] = '<p style="text-align: right;"><strong>Payment terms: 30 days from end of sale month</strong></p><p><strong>bank details:</strong></p><p style="margin-left: 30px;">Bank: Bank Name<br>BSB: 123-456<br>Account Number: 123 456 789&nbsp;</p>';
/* Relationship: Order: Customer (field_customer) - tid */
$handler->display->display_options['relationships']['field_customer_tid']['id'] = 'field_customer_tid';
$handler->display->display_options['relationships']['field_customer_tid']['table'] = 'field_data_field_customer';
$handler->display->display_options['relationships']['field_customer_tid']['field'] = 'field_customer_tid';
$handler->display->display_options['relationships']['field_customer_tid']['required'] = 0;
/* Field: Commerce Order: Created date */
$handler->display->display_options['fields']['created']['id'] = 'created';
$handler->display->display_options['fields']['created']['table'] = 'commerce_order';
$handler->display->display_options['fields']['created']['field'] = 'created';
$handler->display->display_options['fields']['created']['label'] = 'Date';
$handler->display->display_options['fields']['created']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['created']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['created']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['created']['alter']['external'] = 0;
$handler->display->display_options['fields']['created']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['created']['alter']['trim'] = 0;
$handler->display->display_options['fields']['created']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['created']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['created']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['created']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['created']['alter']['html'] = 0;
$handler->display->display_options['fields']['created']['element_label_colon'] = 1;
$handler->display->display_options['fields']['created']['element_default_classes'] = 1;
$handler->display->display_options['fields']['created']['hide_empty'] = 0;
$handler->display->display_options['fields']['created']['empty_zero'] = 0;
$handler->display->display_options['fields']['created']['date_format'] = 'custom';
$handler->display->display_options['fields']['created']['custom_date_format'] = 'd/m/Y';
/* Field: Commerce Order: Order ID */
$handler->display->display_options['fields']['order_id']['id'] = 'order_id';
$handler->display->display_options['fields']['order_id']['table'] = 'commerce_order';
$handler->display->display_options['fields']['order_id']['field'] = 'order_id';
$handler->display->display_options['fields']['order_id']['label'] = 'Invoice #';
$handler->display->display_options['fields']['order_id']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['external'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['trim'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['order_id']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['order_id']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['order_id']['alter']['html'] = 0;
$handler->display->display_options['fields']['order_id']['element_type'] = 'span';
$handler->display->display_options['fields']['order_id']['element_label_type'] = 'span';
$handler->display->display_options['fields']['order_id']['element_label_colon'] = 1;
$handler->display->display_options['fields']['order_id']['element_default_classes'] = 1;
$handler->display->display_options['fields']['order_id']['hide_empty'] = 0;
$handler->display->display_options['fields']['order_id']['empty_zero'] = 0;
/* Field: Taxonomy term: Address - Billing */
$handler->display->display_options['fields']['field_address_billing']['id'] = 'field_address_billing';
$handler->display->display_options['fields']['field_address_billing']['table'] = 'field_data_field_address_billing';
$handler->display->display_options['fields']['field_address_billing']['field'] = 'field_address_billing';
$handler->display->display_options['fields']['field_address_billing']['relationship'] = 'field_customer_tid';
$handler->display->display_options['fields']['field_address_billing']['label'] = 'BILL TO';
$handler->display->display_options['fields']['field_address_billing']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['external'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['trim'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['field_address_billing']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['field_address_billing']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['field_address_billing']['alter']['html'] = 0;
$handler->display->display_options['fields']['field_address_billing']['element_label_type'] = 'strong';
$handler->display->display_options['fields']['field_address_billing']['element_label_colon'] = 1;
$handler->display->display_options['fields']['field_address_billing']['element_default_classes'] = 1;
$handler->display->display_options['fields']['field_address_billing']['hide_empty'] = 0;
$handler->display->display_options['fields']['field_address_billing']['empty_zero'] = 0;
$handler->display->display_options['fields']['field_address_billing']['click_sort_column'] = 'country';
$handler->display->display_options['fields']['field_address_billing']['field_api_classes'] = 0;
/* Field: Taxonomy term: Address - Shipping */
$handler->display->display_options['fields']['field_address_shipping']['id'] = 'field_address_shipping';
$handler->display->display_options['fields']['field_address_shipping']['table'] = 'field_data_field_address_shipping';
$handler->display->display_options['fields']['field_address_shipping']['field'] = 'field_address_shipping';
$handler->display->display_options['fields']['field_address_shipping']['relationship'] = 'field_customer_tid';
$handler->display->display_options['fields']['field_address_shipping']['label'] = 'SHIP TO';
$handler->display->display_options['fields']['field_address_shipping']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['external'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['trim'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['field_address_shipping']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['field_address_shipping']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['alter']['html'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['element_label_type'] = 'strong';
$handler->display->display_options['fields']['field_address_shipping']['element_label_colon'] = 1;
$handler->display->display_options['fields']['field_address_shipping']['element_default_classes'] = 1;
$handler->display->display_options['fields']['field_address_shipping']['hide_empty'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['empty_zero'] = 0;
$handler->display->display_options['fields']['field_address_shipping']['click_sort_column'] = 'country';
$handler->display->display_options['fields']['field_address_shipping']['field_api_classes'] = 0;
/* Field: Order: Line items */
$handler->display->display_options['fields']['commerce_line_items']['id'] = 'commerce_line_items';
$handler->display->display_options['fields']['commerce_line_items']['table'] = 'field_data_commerce_line_items';
$handler->display->display_options['fields']['commerce_line_items']['field'] = 'commerce_line_items';
$handler->display->display_options['fields']['commerce_line_items']['label'] = '';
$handler->display->display_options['fields']['commerce_line_items']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['external'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['trim'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['commerce_line_items']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['commerce_line_items']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['alter']['html'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['element_label_colon'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['element_default_classes'] = 1;
$handler->display->display_options['fields']['commerce_line_items']['hide_empty'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['empty_zero'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['click_sort_column'] = 'line_item_id';
$handler->display->display_options['fields']['commerce_line_items']['settings'] = array(
  'view' => 'commerce_line_item_table|default',
);
$handler->display->display_options['fields']['commerce_line_items']['group_rows'] = 1;
$handler->display->display_options['fields']['commerce_line_items']['delta_offset'] = '0';
$handler->display->display_options['fields']['commerce_line_items']['delta_reversed'] = 0;
$handler->display->display_options['fields']['commerce_line_items']['field_api_classes'] = 0;
/* Field: Order: Order total */
$handler->display->display_options['fields']['commerce_order_total']['id'] = 'commerce_order_total';
$handler->display->display_options['fields']['commerce_order_total']['table'] = 'field_data_commerce_order_total';
$handler->display->display_options['fields']['commerce_order_total']['field'] = 'commerce_order_total';
$handler->display->display_options['fields']['commerce_order_total']['label'] = '';
$handler->display->display_options['fields']['commerce_order_total']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['external'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['trim'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['commerce_order_total']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['commerce_order_total']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['alter']['html'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['element_label_colon'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['element_default_classes'] = 1;
$handler->display->display_options['fields']['commerce_order_total']['hide_empty'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['empty_zero'] = 0;
$handler->display->display_options['fields']['commerce_order_total']['click_sort_column'] = 'amount';
$handler->display->display_options['fields']['commerce_order_total']['type'] = 'commerce_price_formatted_components';
$handler->display->display_options['fields']['commerce_order_total']['field_api_classes'] = 0;
/* Contextual filter: Commerce Order: Uid */
$handler->display->display_options['arguments']['uid']['id'] = 'uid';
$handler->display->display_options['arguments']['uid']['table'] = 'commerce_order';
$handler->display->display_options['arguments']['uid']['field'] = 'uid';
$handler->display->display_options['arguments']['uid']['default_action'] = 'default';
$handler->display->display_options['arguments']['uid']['default_argument_type'] = 'current_user';
$handler->display->display_options['arguments']['uid']['default_argument_skip_url'] = 0;
$handler->display->display_options['arguments']['uid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['uid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['uid']['summary_options']['items_per_page'] = '25';
$handler->display->display_options['arguments']['uid']['specify_validation'] = 1;
$handler->display->display_options['arguments']['uid']['validate']['type'] = 'current_user_or_role';
$handler->display->display_options['arguments']['uid']['validate_options']['restrict_roles'] = '1';
$handler->display->display_options['arguments']['uid']['validate_options']['roles'] = array(
  3 => '3',
  4 => '4',
  6 => '6',
);
$handler->display->display_options['arguments']['uid']['break_phrase'] = 0;
$handler->display->display_options['arguments']['uid']['not'] = 0;
/* Contextual filter: Commerce Order: Order ID */
$handler->display->display_options['arguments']['order_id']['id'] = 'order_id';
$handler->display->display_options['arguments']['order_id']['table'] = 'commerce_order';
$handler->display->display_options['arguments']['order_id']['field'] = 'order_id';
$handler->display->display_options['arguments']['order_id']['default_action'] = 'not found';
$handler->display->display_options['arguments']['order_id']['default_argument_type'] = 'fixed';
$handler->display->display_options['arguments']['order_id']['default_argument_skip_url'] = 0;
$handler->display->display_options['arguments']['order_id']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['order_id']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['order_id']['summary_options']['items_per_page'] = '25';
$handler->display->display_options['arguments']['order_id']['break_phrase'] = 0;
$handler->display->display_options['arguments']['order_id']['not'] = 0;

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'user/%/orders/%';
$handler->display->display_options['menu']['type'] = 'tab';
$handler->display->display_options['menu']['title'] = 'Orders';
$handler->display->display_options['menu']['weight'] = '0';
$translatables['order'] = array(
  t('Master'),
  t('more'),
  t('Apply'),
  t('Reset'),
  t('Sort by'),
  t('Asc'),
  t('Desc'),
  t('Items per page'),
  t('- All -'),
  t('Offset'),
  t('Header'),
  t('<p style="margin: 0;"><img src="/sites/all/themes/THEMENAME/logo.png" width="217.7px" height="117.6px" style="float: left; margin-right: auto; margin-top: 0;"></p><p style="text-align: right;">COMPANY Pty Ltd<br>ABN 12 345 678 901</p><p style="text-align: right;">COMPANY ADDRESS</p><p style="text-align: right;">Phone: 1234 123 123<br>email: test@test.com</p><h4 style="text-align: center;"><strong>TAX INVOICE</strong></h4>'),
  t('<p style="text-align: right;"><strong>Payment terms: 30 days from end of sale month</strong></p><p><strong>bank details:</strong></p><p style="margin-left: 30px;">Bank: Bank Name<br>BSB: 123-456<br>Account Number: 123 456 789&nbsp;</p>'),
  t('term from field_customer'),
  t('Date'),
  t('Invoice #'),
  t('BILL TO'),
  t('SHIP TO'),
  t('All'),
  t('Page'),
);
zkrebs’s picture

subscribe

fall_0ut’s picture

subscribe

rfay’s picture

subscribe

Scott J’s picture

There is a new module called Views PDF which should be perfect for this. It is being used by Ubercart PDF Invoice module.

hunziker’s picture

Scott this is a good idea. At the moment the Views PDF does not have stable support for Drupal 7. I will push it forward, but this take some time. The creation of the view itself is not very complicated. So if we can build a HTML view of an invoice, it is a small effort to transform it to using with Views PDF.

felipepodesta’s picture

+1
Subs

hunziker’s picture

I add a new project for this purpose. See Commerce PDF Invoice.

At the moment there are some issues with the positioning of the included view. Additionally we need a way to display the order totals in a appropriated way. Possibly we need this module here for the order totals: Order Totals

artusamak’s picture

Status: Active » Closed (won't fix)

Closing this one, as discussed with rfay, the module Commerce PDF Invoice refeered in #16 seems to do the job.
We added the reference on http://www.drupalcommerce.org/contrib page.

rfay’s picture

Status: Closed (won't fix) » Fixed

Or maybe "fixed" :-) Yay Hunziker.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

j0rd’s picture

+1 for invoice functionality ala Ubercart. This means HTML & Emailable invoices. PDFs are nice too, but less important and more work.

It doesn't need to be a view. A simple themable page is good enough & more flexible (just not in the UI). Some people require fairly flexible invoices & they want to style them with their own branding.

Invoices are important for B2B records. Currently if Drupal Commerce doesn't support printable invoices / receipts, it's no good for businesses & tax purposes.

Yuri’s picture

I agree, html invoices are very imporant. Subscribing.

gagoo’s picture

The same.
subscribe

Fidelix’s picture

I believe HTML, emailable invoices are even more important than PDF.

zambrey’s picture

Let's move to separate issue for HTML invoices: #1214592: Support for HTML invoices
Thanks.