Configuring Production Sheets

Configuring Production Sheets

Overview

Production sheet templates allow you to customize the PDF production sheets generated for parts, jobs, and batches in your Production Management system. By default, the platform includes built-in production sheet templates as part of the codebase. These default templates are used automatically unless you add your own custom templates.

This article explains how to add and configure custom production sheet templates in the Admin Panel. When you add a custom template, it replaces the corresponding built-in default template for the selected type and service.

Location in Admin Panel:
Home › B3_Pdf › Production sheet templates

Adding a Custom Production Sheet Template

To add your own production sheet template and override the default:

  1. Go to the Production sheet templates section in the Admin Panel.

  2. Click Add Production Sheet Template.

  3. Complete the required fields as described below.

  4. Click Save to apply your changes.

Once a custom template is added for a specific type and service, it will be used instead of the default template provided by the platform.

image-20251017-144221.png
A custom batch production sheet

Configuring Production Sheet Templates

When creating or editing a production sheet template, the following fields are available:

Field

Description

Field

Description

Template

The Django template in HTML format used to generate the PDF file. You must input a valid template here. See the Appendix for sample templates.

See the Appendix for sample templates. For available template variables, see

https://3yourmind.atlassian.net/wiki/spaces/PD/pages/1852538881

Template name

A unique, internal name for the template (e.g., batch_production_sheet.html). This name is visible only in the Admin Panel.

Label

The name displayed in the user interface (UI) when downloading the sheet.

Service

The service this sheet is associated with. Leave empty to make the sheet available for all services.

Use one page per part

Forces the PDF exporter to create a separate page for each part within a batch.
Note: Contact Technical Support to adjust this setting.

Type

The primary entity this sheet applies to: Part, Job, or Batch (formerly called “Sequence”). Used to filter suitable sheets in the UI.

image-20251017-144301.png
Configuration of a custom batch production sheet

Types of Production Sheets

  • Part: Contains information about one or more MES parts. Downloadable from the MES Parts list or Part detail page.

  • Job: Contains information about a single job and its batches. Downloadable from the Job detail page.

  • Sequence (Batch): Contains information about one or more batches. Downloadable from the MES Part detail page.

How Production Sheets Are Selected

  1. When downloading a production sheet:

    1. No custom template defined: The default template from the codebase is used.

    2. One custom template defined: That template is used automatically (no dropdown).

    3. Multiple custom templates defined: A dropdown appears, allowing you to select the desired template.

Appendix - Sample Production Sheet Templates

In this appendix we are listing the default production sheet templates used on the platform. They can serve as a basis or inspiration for custom production sheets.

Sample Part Production Sheet

Documentation last updated: 2025-10-17

Link to latest version: part_production_sheet.html

{% load i18n static qr_code %} {% get_current_language as LANGUAGE_CODE %} <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{% trans 'Production sheet' %}</title> <style> /* Printer page */ @page { size: A4 portrait; margin: 10mm 10mm 7mm; @bottom-right { font-size: 0.8rem; color: #555; content: 'Page ' counter(page) ' / ' counter(pages); } } html { font-family: 'Open Sans', sans-serif; font-size: 12px; background: transparent; color: #333; } body { background: transparent; margin: 0; padding: 0; } b, p, section h3 { font-size: 1rem; } table { border-spacing: 0; width: 100%; } td { vertical-align: top } .thumbnail-container { text-align: center; } .title { font-weight: bold; font-size: 2rem; } .subtitle { font-weight: bold; } .info { padding: 0.5rem 0.5rem; height: 2rem; margin-top: 1rem; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; } .line-image { max-width: 3cm; max-height: 1.8cm; } .logo-image { max-width: 4cm; max-height: 1cm; } .line-image img, .logo-image img{ width: 100%; display: block; } .el-label { color: #999; font-weight: bold; font-size: 10px; padding-right: 10px; } .el-value-bold { font-weight: bold; } .kt-table td, .kt-table th { border-bottom: 1px solid #ddd; vertical-align: middle; } .kt-table th { color: #999; padding: 0.5rem 0; font-weight: bold; font-size: 10px; } .kt-table td { padding: 1rem 0; } th.status-number, th.status-box { width: 3%; } th.status-remarks { width: 24%; } .square { width: 12px; height: 12px; border: 1px solid #777; } .info--grey td div { display: inline-block; } .info--grey td { padding-right: 1rem; } .pad-top { padding-top: 15px; } .small-pad-top { padding-top: 5px; } .part-page { page-break-after: always; } .part-page-header { } .part-page-general-info-nav { } .part-page-part-detail { background: #eee; padding: 10px; margin-top: 15px; display: flex; justify-content: space-around; align-items: center; } .part-page-part-requirements { margin-top: 15px; } .part-page-workflow-statuses { margin-top: 15px; } .part-page-part-instructions { margin-top: 15px; } .part-page-part-attachments { margin-top: 15px; } .part-page-footer { position: absolute; bottom: 0; width: 100%; border-top: 1px solid #ddd; } </style> </head> <body> {% include "b3_pdf/extra_header.html" %} {% for part in parts %} <section class="part-page"> <section class="part-page-header"> <table> <tr> <td> <div class="title">{% trans 'Part Production Sheet' %}</div> <div class="subtitle"> {% trans 'Issue date:' %} {{ part.issue_date|date:theme_date_format }} </div> </td> <td> {% qr_from_text part.part_url size="2" image_format="png" error_correction="L" %} </td> <td class="logo" style="text-align: right"> <img src="{{ logo_url }}" alt="Default Logo" class="logo-image" > </td> </tr> </table> </section> <section class="part-page-general-info-nav"> <table class="info"> <tr> <td class="element"> <div class="el-label">{% trans 'Order #' %}</div> <div class="el-value">{{ part.order_number }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Project Name' %}</div> <div class="el-value">{{ part.project_name|truncatechars:30|default:"-" }}</div> </td> <td class="element" style="text-align:right;"> <div class="el-label">{% trans 'Order Date' %}</div> <div class="el-value">{{ part.order_date|date:theme_date_format }}</div> </td> <td class="element" style="text-align:right;"> <div class="el-label">{% trans 'Target Date' %}</div> <div class="el-value">{{ part.target_date|date:theme_date_format }}</div> </td> </tr> </table> </section> <section class="part-page-part-detail"> <table style="width: 50%"> <tr> <td class="element"> <div class="el-label">{% trans 'Part Name' %}</div> <div class="el-value-bold">{{ part.name|default:'-'|truncatechars:85 }}</div> </td> </tr> <tr> <td class="element pad-top"> <div class="el-label">{% trans 'Part Number' %}</div> <div class="el-value">{{ part.number }}</div> </td> <td class="element pad-top"> <div class="el-label">{% trans 'Technology' %}</div> <div class="el-value">{{ part.technology }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Quantity' %}</div> <div class="el-value">{{ part.quantity }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Material' %}</div> <div class="el-value">{{ part.material }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Post-processings' %}</div> <div class="el-value"> {% if part.post_processings %} {% for pp in part.post_processings %} {{ pp.title }}{% if pp.colorTitle %}: {{ pp.colorTitle }}{% endif %}{% if not forloop.last %} | {% endif %} {% endfor %} {% else %} --/-- {% endif %} </div> <div class="el-label">{% trans 'Inserts' %}</div> <div class="el-value"> {% if part.inserts %} {% for pp in part.inserts %} {{ pp.title }} {% for insert_detail in pp.details %} {{ insert_detail.thread_size }}: {{ insert_detail.quantity }} {% endfor %} {% if not forloop.last %} | {% endif %} {% endfor %} {% else %} --/-- {% endif %} </div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans "Priority" %}</div> <div class="el-value">{{ part.priority }}</div> </td> </tr> </table> <div class="thumbnail-container"> <img src="{{ part.picture_url }}" alt="{{ part.name|truncatechars:9 }}" class="line-image" > <div class="el-value"> {{ part.dimensions.h|floatformat:2 }} x {{ part.dimensions.w|floatformat:2 }} x {{ part.dimensions.d|floatformat:2 }} {{ part.measure_unit }} </div> </div> </section> <section class="part-page-part-requirements"> {% if part.part_requirements %} <div id="part_requirements" style="margin: 5mm 0"> {% for field in part.part_requirements %} <div style="margin-top: 2mm"> <span><b>{{ field.label }}:</b></span> <span>{{ field.value }}</span> </div> {% endfor %} </div> {% endif %} </section> <section class="part-page-workflow-statuses"> <table class="kt-table"> <thead> <tr> <th class="status-number">#</th> <th class="status-name">{% trans 'Production Step' %}</th> <th class="status-workstation">{% trans 'Workstation' %}</th> <th class="status-assignee">{% trans 'Job Assignee' %}</th> <th class="status-duration">{% trans 'Duration/Date' %}</th> <th class="status-box"> </th> <th class="status-remarks">{% trans 'Remarks' %}</th> </tr> </thead> <tbody> {% for step in part.production_steps %} <tr> <td>{{ forloop.counter }}</td> <td>{{ step.name }}</td> <td>{{ step.workstation }}</td> <td>{% if step.assignees %}{{ step.assignees|join:', ' }}{% endif %}</td> <td>{% if step.duration %} {% if step.duration.days %}{{ step.duration.days }}d{% endif %} {{ step.duration.hours }}h {{ step.duration.minutes }}m &nbsp;&nbsp; {{ step.duration.date|date:"d.m.Y" }} {% endif %} </td> <td> <div class="square">&nbsp;</div> </td> <td></td> </tr> {% endfor %} </tbody> </table> </section> <section class="part-page-part-instructions"> <div class="el-label">{% trans 'Instructions' %}</div> <p>{{ part.instructions|linebreaks }}</p> </section> <section class="part-page-part-attachments"> <div class="el-label">{% trans 'Attachments' %}</div> {% for attachment in part.attachments %} <div>{{ attachment.filename }}</div> {% endfor %} </section> <section class="part-page-footer"> <table> <tr> <td class="element"> <div class="el-label">{% trans 'Part Assignee' %}</div> {% for assignee in part.assignees %} <div class="el-value">{{ assignee.userprofile.full_name }}</div> {% endfor %} </td> <td class="element"> <div class="el-label">{% trans 'Shipping Method' %}</div> <div class="el-value">{{ part.shipping_method }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Payment Method' %}</div> <div class="el-value">{{ part.payment_method }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Customer' %}</div> <div class="el-value">{{ part.customer_name }}</div> <div class="el-value">{{ part.customer_phone }}</div> <div class="el-value">{{ part.customer_email }}</div> </td> </tr> </table> </section> </section> {% endfor %} </body> </html>

Sample Job Production Sheet

Documentation last updated: 2025-10-17

Link to latest version: job_production_sheet.html

{% load i18n static qr_code %} {% get_current_language as LANGUAGE_CODE %} <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{% trans 'Production sheet' %}</title> <style> /* Printer page */ @page { size: A4 portrait; margin: 10mm 10mm 7mm; @bottom-right { font-size: 0.8rem; color: #555; content: 'Page ' counter(page) ' / ' counter(pages); } } html { font-family: 'Open Sans', sans-serif; font-size: 12px; background: transparent; color: #333; } body { background: transparent; margin: 0; padding: 0; } b, p, section h3 { font-size: 1rem; } table { border-spacing: 0; width: 100%; } td { vertical-align: top } .thumbnail-container { text-align: center; } .title { font-weight: bold; font-size: 2rem; } .subtitle { font-weight: bold; } .info { padding: 0.5rem 0.5rem; height: 2rem; margin-top: 1rem; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; } .line-image { max-width: 3cm; max-height: 1.8cm; } .logo-image { max-width: 4cm; max-height: 1cm; } .line-image img, .logo-image img{ width: 100%; display: block; } .el-label { color: #999; font-weight: bold; font-size: 10px; padding-right: 10px; } .el-value-bold { font-weight: bold; } .kt-table td, .kt-table th { border-bottom: 1px solid #ddd; vertical-align: middle; } .kt-table th { color: #999; padding: 0.5rem 0; font-weight: bold; font-size: 10px; } .kt-table td { padding: 1rem 0; } th.status-number, th.status-box { width: 3%; } th.part-number { width: 6%; } th.sequence-number, th.sequence-quantity{ width: 10%; } th.target-date{ width: 15%; } th.status-remarks { width: 24%; } .square { width: 12px; height: 12px; border: 1px solid #777; } .info--grey td div { display: inline-block; } .info--grey td { padding-right: 1rem; } .pad-top { padding-top: 15px; } .small-pad-top { padding-top: 5px; } .small-marg-top { margin-top: 5px; } .title-page { page-break-after: always; height: 100%; position: relative; } .title-page-header { } .title-page-job-detail { background: #eee; padding: 10px; margin-top: 15px; } .title-page-part-list { margin-top: 15px; } .title-page-job-documentation { margin-top: 15px; } .title-page-job-attachments { margin-top: 15px; } .part-page { page-break-after: always; } .part-page-header { } .part-page-general-info-nav { } .part-page-part-detail { background: #eee; padding: 10px; margin-top: 15px; display: flex; justify-content: space-around; align-items: center; } .part-page-part-requirements { margin-top: 15px; } .part-page-workflow-statuses { margin-top: 15px; } .part-page-part-instructions { margin-top: 15px; } .part-page-part-attachments { margin-top: 15px; } .part-page-footer { position: absolute; bottom: 0; width: 100%; border-top: 1px solid #ddd; } </style> </head> <body> {% include "b3_pdf/extra_header.html" %} <section class="title-page"> <section class="title-page-header"> <table> <tr> <td> <div class="title">{% trans 'Job Production Sheet' %}</div> <div class="subtitle"> {% trans 'Issue date:' %} {{ issue_date|date:theme_date_format }} </div> </td> <td> {% qr_from_text job_url size="2" image_format="png" error_correction="L" %} </td> <td class="logo" style="text-align: right"> <img src="{{ logo_url }}" alt="Default Logo" class="logo-image" > </td> </tr> </table> </section> <section class="title-page-job-detail"> <table> <tr> <td class="element"> <div class="el-label">{% trans 'Job Name' %}</div> <div class="el-value-bold">{{ job.name|default:'-'|truncatechars:85 }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Job Number' %}</div> <div class="el-value-bold">{{ job.id|default:'-'|truncatechars:85 }}</div> </td> </tr> <tr> <td class="element pad-top"> <div class="el-label">{% trans 'Workstation' %}</div> <div class="el-value">{{ job.workstation.name }}</div> </td> <td class="element pad-top"> <div class="el-label">{% trans 'Technology' %}</div> <div class="el-value">{{ job_technology }}</div> </td> <td class="element pad-top"> <div class="el-label">{% trans 'Assignees' %}</div> <div class="el-value">{{ job_assignees|default:"--/--" }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Scheduled Start' %}</div> <div class="el-value">{{ job.start_time|date:"d M Y H:i:s e"|default:"--/--" }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Material' %}</div> <div class="el-value">{{ job_material }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Build Volume' %}</div> <div class="el-value">{{ job.build_volume|floatformat:5 }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Duration' %}</div> <div class="el-value">{{ job_duration|default:"--/--" }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Material Lot IDs' %}</div> <div class="el-value">{{ job_material_lots|default:"--/--" }}</div> </td> </tr> </table> </section> <section class="title-page-part-list"> <table class="kt-table"> <thead> <tr> <th class="part-number">{% trans 'Part#' %}</th> <th>{% trans 'Part name' %}</th> <th class="sequence-number">{% trans 'Sequence#' %}</th> <th class="sequence-quantity">{% trans 'Quantity' %}</th> <th class="target-date">{% trans 'Target Date' %}</th> <th>{% trans 'Order#' %}</th> <th>{% trans 'Priority' %} </tr> </thead> <tbody> {% for part in parts %} <tr> <td>{{ part.number }}</td> <td>{{ part.name }}</td> <td>{{ part.sequence_id }}</td> <td>{{ part.sequence_amount }}</td> <td>{{ part.target_date|date:"d M Y" }}</td> <td>{{ part.order_number }}</td> <td>{{ part.priority }}</td> </tr> {% endfor %} </tbody> </table> </section> <section class="title-page-job-documentation"> <div class="el-label">{% trans 'Job documentation' %}</div> {% if job_documentation %} {% for field in job_documentation %} <div class="small-marg-top"> <span><b>{{ field.label }}:</b></span> <span>{{ field.value }}</span> </div> {% endfor %} {% endif %} </section> <section class="title-page-job-attachments"> <div class="el-label">{% trans 'Attachments' %}</div> {% if job_attachments %} {% for attachment in job_attachments %} <div>{{ attachment.filename }}</div> {% endfor %} {% endif %} </section> </section> {% for part in parts %} <section class="part-page"> <section class="part-page-header"> <table> <tr> <td> <div class="title">{% trans 'Sequence Production Sheet' %}</div> <div class="subtitle"> {% trans 'Issue date:' %} {{ part.issue_date|date:theme_date_format }} </div> </td> <td> {% qr_from_text part.sequence_url size="2" image_format="png" error_correction="L" %} </td> <td class="logo" style="text-align: right"> <img src="{{ logo_url }}" alt="Default Logo" class="logo-image" > </td> </tr> </table> </section> <section class="part-page-general-info-nav"> <table class="info"> <tr> <td class="element"> <div class="el-label">{% trans 'Order #' %}</div> <div class="el-value">{{ part.order_number }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Project Name' %}</div> <div class="el-value">{{ part.project_name|truncatechars:30|default:"-" }}</div> </td> <td class="element" style="text-align:right;"> <div class="el-label">{% trans 'Order Date' %}</div> <div class="el-value">{{ part.order_date|date:theme_date_format }}</div> </td> <td class="element" style="text-align:right;"> <div class="el-label">{% trans 'Target Date' %}</div> <div class="el-value">{{ part.target_date|date:theme_date_format }}</div> </td> </tr> </table> </section> <section class="part-page-part-detail"> <table style="width: 50%"> <tr> <td class="element"> <div class="el-label">{% trans 'Part Name' %}</div> <div class="el-value-bold">{{ part.name|default:'-'|truncatechars:85 }}</div> </td> </tr> <tr> <td class="element pad-top"> <div class="el-label">{% trans 'Part Number' %}</div> <div class="el-value">{{ part.number }}</div> </td> <td class="element pad-top"> <div class="el-label">{% trans 'Technology' %}</div> <div class="el-value">{{ part.technology }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Sequence Group Number' %}</div> <div class="el-value">{{ part.sequence_id }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Material' %}</div> <div class="el-value">{{ part.material }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Quantity' %}</div> <div class="el-value">{{ part.sequence_amount }} / {{ part.quantity }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Post-processings' %}</div> <div class="el-value"> {% if part.post_processings %} {% for pp in part.post_processings %} {{ pp.title }}{% if pp.colorTitle %}: {{ pp.colorTitle }}{% endif %}{% if not forloop.last %} | {% endif %} {% endfor %} {% else %} --/-- {% endif %} </div> <div class="el-label">{% trans 'Inserts' %}</div> <div class="el-value"> {% if part.inserts %} {% for pp in part.inserts %} {{ pp.title }} {% for insert_detail in pp.details %} {{ insert_detail.thread_size }}: {{ insert_detail.quantity }} {% endfor %} {% if not forloop.last %} | {% endif %} {% endfor %} {% else %} --/-- {% endif %} </div> </td> </tr> </table> <div class="thumbnail-container"> <img src="{{ part.picture_url }}" alt="{{ part.name|truncatechars:9 }}" class="line-image" > <div class="el-value"> {{ part.dimensions.h|floatformat:2 }} x {{ part.dimensions.w|floatformat:2 }} x {{ part.dimensions.d|floatformat:2 }} {{ part.measure_unit }} </div> </div> </section> <section class="part-page-part-requirements"> {% if part.part_requirements %} <div id="part_requirements" style="margin: 5mm 0"> {% for field in part.part_requirements %} <div style="margin-top: 2mm"> <span><b>{{ field.label }}:</b></span> <span>{{ field.value }}</span> </div> {% endfor %} </div> {% endif %} </section> <section class="part-page-workflow-statuses"> <table class="kt-table"> <thead> <tr> <th class="status-number">#</th> <th class="status-name">{% trans 'Production Step' %}</th> <th class="status-workstation">{% trans 'Workstation' %}</th> <th class="status-job-id">{% trans 'Job ID' %}</th> <th class="status-assignee">{% trans 'Assignee' %}</th> <th class="status-duration">{% trans 'Duration/Date' %}</th> <th class="status-box"> </th> <th class="status-remarks">{% trans 'Remarks' %}</th> </tr> </thead> <tbody> {% for step in part.sequence_steps %} <tr> <td>{{ forloop.counter }}</td> <td>{{ step.name }}</td> <td>{{ step.workstation }}</td> <td>{{ step.job_id }}</td> <td>{% if step.assignees %}{{ step.assignees|join:', ' }}{% endif %}</td> <td>{% if step.duration %} {% if step.duration.days %}{{ step.duration.days }}d{% endif %} {{ step.duration.hours }}h {{ step.duration.minutes }}m &nbsp;&nbsp; {{ step.duration.date|date:"d.m.Y" }} {% endif %} </td> <td> <div class="square">&nbsp;</div> </td> <td></td> </tr> {% endfor %} </tbody> </table> </section> <section class="part-page-part-instructions"> <div class="el-label">{% trans 'Instructions' %}</div> <p>{{ part.instructions|linebreaks }}</p> </section> <section class="part-page-part-attachments"> <div class="el-label">{% trans 'Attachments' %}</div> {% for attachment in part.attachments %} <div>{{ attachment.filename }}</div> {% endfor %} </section> <section class="part-page-footer"> <table> <tr> <td class="element"> <div class="el-label">{% trans 'Assignee' %}</div> {% for assignee in part.assignees %} <div class="el-value">{{ assignee.userprofile.full_name }}</div> {% endfor %} </td> <td class="element"> <div class="el-label">{% trans 'Shipping Method' %}</div> <div class="el-value">{{ part.shipping_method }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Payment Method' %}</div> <div class="el-value">{{ part.payment_method }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Customer' %}</div> <div class="el-value">{{ part.customer_name }}</div> <div class="el-value">{{ part.customer_phone }}</div> <div class="el-value">{{ part.customer_email }}</div> </td> </tr> </table> </section> </section> {% endfor %} </body> </html>

Sample Sequence Production Sheet

Documentation last updated: 2025-10-17

Link to latest version: sequence_production_sheet.html

{% load i18n static qr_code %} {% get_current_language as LANGUAGE_CODE %} <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{% trans 'Production sheet' %}</title> <style> /* Printer page */ @page { size: A4 portrait; margin: 10mm 10mm 7mm; @bottom-right { font-size: 0.8rem; color: #555; content: 'Page ' counter(page) ' / ' counter(pages); } } html { font-family: 'Open Sans', sans-serif; font-size: 12px; background: transparent; color: #333; } body { background: transparent; margin: 0; padding: 0; } b, p, section h3 { font-size: 1rem; } table { border-spacing: 0; width: 100%; } td { vertical-align: top } .thumbnail-container { text-align: center; } .title { font-weight: bold; font-size: 2rem; } .subtitle { font-weight: bold; } .info { padding: 0.5rem 0.5rem; height: 2rem; margin-top: 1rem; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; } .line-image { max-width: 3cm; max-height: 1.8cm; } .logo-image { max-width: 4cm; max-height: 1cm; } .line-image img, .logo-image img{ width: 100%; display: block; } .el-label { color: #999; font-weight: bold; font-size: 10px; padding-right: 10px; } .el-value-bold { font-weight: bold; } .kt-table td, .kt-table th { border-bottom: 1px solid #ddd; vertical-align: middle; } .kt-table th { color: #999; padding: 0.5rem 0; font-weight: bold; font-size: 10px; } .kt-table td { padding: 1rem 0; } th.status-number, th.status-box { width: 3%; } th.status-remarks { width: 24%; } .square { width: 12px; height: 12px; border: 1px solid #777; } .info--grey td div { display: inline-block; } .info--grey td { padding-right: 1rem; } .pad-top { padding-top: 15px; } .small-pad-top { padding-top: 5px; } .part-page { page-break-after: always; } .part-page-header { } .part-page-general-info-nav { } .part-page-part-detail { background: #eee; padding: 10px; margin-top: 15px; display: flex; justify-content: space-around; align-items: center; } .part-page-part-requirements { margin-top: 15px; } .part-page-workflow-statuses { margin-top: 15px; } .part-page-part-instructions { margin-top: 15px; } .part-page-part-attachments { margin-top: 15px; } .part-page-footer { position: absolute; bottom: 0; width: 100%; border-top: 1px solid #ddd; } </style> </head> <body> {% include "b3_pdf/extra_header.html" %} {% for part in parts %} <section class="part-page"> <section class="part-page-header"> <table> <tr> <td> <div class="title">{% trans 'Sequence Production Sheet' %}</div> <div class="subtitle"> {% trans 'Issue date:' %} {{ part.issue_date|date:theme_date_format }} </div> </td> <td> {% qr_from_text part.sequence_url size="2" image_format="png" error_correction="L" %} </td> <td class="logo" style="text-align: right"> <img src="{{ logo_url }}" alt="Default Logo" class="logo-image" > </td> </tr> </table> </section> <section class="part-page-general-info-nav"> <table class="info"> <tr> <td class="element"> <div class="el-label">{% trans 'Order #' %}</div> <div class="el-value">{{ part.order_number }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Project Name' %}</div> <div class="el-value">{{ part.project_name|truncatechars:30|default:"-" }}</div> </td> <td class="element" style="text-align:right;"> <div class="el-label">{% trans 'Order Date' %}</div> <div class="el-value">{{ part.order_date|date:theme_date_format }}</div> </td> <td class="element" style="text-align:right;"> <div class="el-label">{% trans 'Target Date' %}</div> <div class="el-value">{{ part.target_date|date:theme_date_format }}</div> </td> </tr> </table> </section> <section class="part-page-part-detail"> <table style="width: 50%"> <tr> <td class="element"> <div class="el-label">{% trans 'Part Name' %}</div> <div class="el-value-bold">{{ part.name|default:'-'|truncatechars:85 }}</div> </td> </tr> <tr> <td class="element pad-top"> <div class="el-label">{% trans 'Part Number' %}</div> <div class="el-value">{{ part.number }}</div> </td> <td class="element pad-top"> <div class="el-label">{% trans 'Technology' %}</div> <div class="el-value">{{ part.technology }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Sequence Group Number' %}</div> <div class="el-value">{{ part.sequence_id }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Material' %}</div> <div class="el-value">{{ part.material }}</div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans 'Quantity' %}</div> <div class="el-value">{{ part.sequence_amount }} / {{ part.quantity }}</div> </td> <td class="element small-pad-top"> <div class="el-label">{% trans 'Post-processings' %}</div> <div class="el-value"> {% if part.post_processings %} {% for pp in part.post_processings %} {{ pp.title }}{% if pp.colorTitle %}: {{ pp.colorTitle }}{% endif %}{% if not forloop.last %} | {% endif %} {% endfor %} {% else %} --/-- {% endif %} </div> <div class="el-label">{% trans 'Inserts' %}</div> <div class="el-value"> {% if part.inserts %} {% for pp in part.inserts %} {{ pp.title }} {% for insert_detail in pp.details %} {{ insert_detail.thread_size }}: {{ insert_detail.quantity }} {% endfor %} {% if not forloop.last %} | {% endif %} {% endfor %} {% else %} --/-- {% endif %} </div> </td> </tr> <tr> <td class="element small-pad-top"> <div class="el-label">{% trans "Priority" %}</div> <div class="el-value">{{ part.priority }}</div> </td> </tr> </table> <div class="thumbnail-container"> <img src="{{ part.picture_url }}" alt="{{ part.name|truncatechars:9 }}" class="line-image" > <div class="el-value"> {{ part.dimensions.h|floatformat:2 }} x {{ part.dimensions.w|floatformat:2 }} x {{ part.dimensions.d|floatformat:2 }} {{ part.measure_unit }} </div> </div> </section> <section class="part-page-part-requirements"> {% if part.part_requirements %} <div id="part_requirements" style="margin: 5mm 0"> {% for field in part.part_requirements %} <div style="margin-top: 2mm"> <span><b>{{ field.label }}:</b></span> <span>{{ field.value }}</span> </div> {% endfor %} </div> {% endif %} </section> <section class="part-page-workflow-statuses"> <table class="kt-table"> <thead> <tr> <th class="status-number">#</th> <th class="status-name">{% trans 'Production Step' %}</th> <th class="status-workstation">{% trans 'Workstation' %}</th> <th class="status-job-id">{% trans 'Job ID' %}</th> <th class="status-assignee">{% trans 'Assignee' %}</th> <th class="status-duration">{% trans 'Duration/Date' %}</th> <th class="status-box"> </th> <th class="status-remarks">{% trans 'Remarks' %}</th> </tr> </thead> <tbody> {% for step in part.sequence_steps %} <tr> <td>{{ forloop.counter }}</td> <td>{{ step.name }}</td> <td>{{ step.workstation }}</td> <td>{{ step.job_id }}</td> <td>{% if step.assignees %}{{ step.assignees|join:', ' }}{% endif %}</td> <td>{% if step.duration %} {% if step.duration.days %}{{ step.duration.days }}d{% endif %} {{ step.duration.hours }}h {{ step.duration.minutes }}m &nbsp;&nbsp; {{ step.duration.date|date:"d.m.Y" }} {% endif %} </td> <td> <div class="square">&nbsp;</div> </td> <td></td> </tr> {% endfor %} </tbody> </table> </section> <section class="part-page-part-instructions"> <div class="el-label">{% trans 'Instructions' %}</div> <p>{{ part.instructions|linebreaks }}</p> </section> <section class="part-page-part-attachments"> <div class="el-label">{% trans 'Attachments' %}</div> {% for attachment in part.attachments %} <div>{{ attachment.filename }}</div> {% endfor %} </section> <section class="part-page-footer"> <table> <tr> <td class="element"> <div class="el-label">{% trans 'Assignee' %}</div> {% for assignee in part.assignees %} <div class="el-value">{{ assignee.userprofile.full_name }}</div> {% endfor %} </td> <td class="element"> <div class="el-label">{% trans 'Shipping Method' %}</div> <div class="el-value">{{ part.shipping_method }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Payment Method' %}</div> <div class="el-value">{{ part.payment_method }}</div> </td> <td class="element"> <div class="el-label">{% trans 'Customer' %}</div> <div class="el-value">{{ part.customer_name }}</div> <div class="el-value">{{ part.customer_phone }}</div> <div class="el-value">{{ part.customer_email }}</div> </td> </tr> </table> </section> </section> {% endfor %} </body> </html>