mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add default build order report
Toot toot refactor tractor
This commit is contained in:
parent
f87b15e4ea
commit
46f20593c5
@ -18,6 +18,66 @@ class ReportConfig(AppConfig):
|
||||
"""
|
||||
|
||||
self.create_default_test_reports()
|
||||
self.create_default_build_reports()
|
||||
|
||||
def create_default_reports(self, model, reports):
|
||||
"""
|
||||
Copy defualt report files across to the media directory.
|
||||
"""
|
||||
|
||||
# Source directory for report templates
|
||||
src_dir = os.path.join(
|
||||
os.path.dirname(os.path.realpath(__file__)),
|
||||
'templates',
|
||||
'report',
|
||||
)
|
||||
|
||||
# Destination directory
|
||||
dst_dir = os.path.join(
|
||||
settings.MEDIA_ROOT,
|
||||
'report',
|
||||
'inventree',
|
||||
model.getSubdir(),
|
||||
)
|
||||
|
||||
if not os.path.exists(dst_dir):
|
||||
logger.info(f"Creating missing directory: '{dst_dir}'")
|
||||
os.makedirs(dst_dir, exist_ok=True)
|
||||
|
||||
# Copy each report template across (if required)
|
||||
for report in reports:
|
||||
|
||||
# Destination filename
|
||||
filename = os.path.join(
|
||||
'report',
|
||||
'inventree',
|
||||
model.getSubdir(),
|
||||
report['file'],
|
||||
)
|
||||
|
||||
src_file = os.path.join(src_dir, report['file'])
|
||||
dst_file = os.path.join(settings.MEDIA_ROOT, filename)
|
||||
|
||||
if not os.path.exists(dst_file):
|
||||
logger.info(f"Copying test report template '{dst_file}'")
|
||||
shutil.copyfile(src_file, dst_file)
|
||||
|
||||
try:
|
||||
# Check if a report matching the template already exists
|
||||
if model.objects.filter(template=filename).exists():
|
||||
continue
|
||||
|
||||
logger.info(f"Creating new TestReport for '{report['name']}'")
|
||||
|
||||
model.objects.create(
|
||||
name=report['name'],
|
||||
description=report['description'],
|
||||
template=filename,
|
||||
enabled=True
|
||||
)
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
def create_default_test_reports(self):
|
||||
"""
|
||||
@ -31,23 +91,6 @@ class ReportConfig(AppConfig):
|
||||
# Database is not ready yet
|
||||
return
|
||||
|
||||
src_dir = os.path.join(
|
||||
os.path.dirname(os.path.realpath(__file__)),
|
||||
'templates',
|
||||
'report',
|
||||
)
|
||||
|
||||
dst_dir = os.path.join(
|
||||
settings.MEDIA_ROOT,
|
||||
'report',
|
||||
'inventree', # Stored in secret directory!
|
||||
'test',
|
||||
)
|
||||
|
||||
if not os.path.exists(dst_dir):
|
||||
logger.info(f"Creating missing directory: '{dst_dir}'")
|
||||
os.makedirs(dst_dir, exist_ok=True)
|
||||
|
||||
# List of test reports to copy across
|
||||
reports = [
|
||||
{
|
||||
@ -57,36 +100,27 @@ class ReportConfig(AppConfig):
|
||||
},
|
||||
]
|
||||
|
||||
for report in reports:
|
||||
self.create_default_reports(TestReport, reports)
|
||||
|
||||
# Create destination file name
|
||||
filename = os.path.join(
|
||||
'report',
|
||||
'inventree',
|
||||
'test',
|
||||
report['file']
|
||||
)
|
||||
def create_default_build_reports(self):
|
||||
"""
|
||||
Create database entries for the default BuildReport templates
|
||||
(if they do not already exist)
|
||||
"""
|
||||
|
||||
src_file = os.path.join(src_dir, report['file'])
|
||||
dst_file = os.path.join(settings.MEDIA_ROOT, filename)
|
||||
try:
|
||||
from .models import BuildReport
|
||||
except:
|
||||
# Database is not ready yet
|
||||
return
|
||||
|
||||
if not os.path.exists(dst_file):
|
||||
logger.info(f"Copying test report template '{dst_file}'")
|
||||
shutil.copyfile(src_file, dst_file)
|
||||
# List of Build reports to copy across
|
||||
reports = [
|
||||
{
|
||||
'file': 'inventree_build_order.html',
|
||||
'name': 'InvenTree Build Order',
|
||||
'description': 'Build Order job sheet',
|
||||
}
|
||||
]
|
||||
|
||||
try:
|
||||
# Check if a report matching the template already exists
|
||||
if TestReport.objects.filter(template=filename).exists():
|
||||
continue
|
||||
|
||||
logger.info(f"Creating new TestReport for '{report['name']}'")
|
||||
|
||||
TestReport.objects.create(
|
||||
name=report['name'],
|
||||
description=report['description'],
|
||||
template=filename,
|
||||
filters='',
|
||||
enabled=True
|
||||
)
|
||||
except:
|
||||
pass
|
||||
self.create_default_reports(BuildReport, reports)
|
||||
|
@ -62,7 +62,6 @@ class ReportFileUpload(FileSystemStorage):
|
||||
|
||||
def get_available_name(self, name, max_length=None):
|
||||
|
||||
print("Name:", name)
|
||||
return super().get_available_name(name, max_length)
|
||||
|
||||
|
||||
@ -128,7 +127,8 @@ class ReportBase(models.Model):
|
||||
def __str__(self):
|
||||
return "{n} - {d}".format(n=self.name, d=self.description)
|
||||
|
||||
def getSubdir(self):
|
||||
@classmethod
|
||||
def getSubdir(cls):
|
||||
return ''
|
||||
|
||||
def rename_file(self, filename):
|
||||
@ -267,7 +267,8 @@ class TestReport(ReportTemplateBase):
|
||||
Render a TestReport against a StockItem object.
|
||||
"""
|
||||
|
||||
def getSubdir(self):
|
||||
@classmethod
|
||||
def getSubdir(cls):
|
||||
return 'test'
|
||||
|
||||
filters = models.CharField(
|
||||
@ -313,7 +314,8 @@ class BuildReport(ReportTemplateBase):
|
||||
Build order / work order report
|
||||
"""
|
||||
|
||||
def getSubdir(self):
|
||||
@classmethod
|
||||
def getSubdir(cls):
|
||||
return 'build'
|
||||
|
||||
filters = models.CharField(
|
||||
@ -349,7 +351,8 @@ class BillOfMaterialsReport(ReportTemplateBase):
|
||||
Render a Bill of Materials against a Part object
|
||||
"""
|
||||
|
||||
def getSubdir(self):
|
||||
@classmethod
|
||||
def getSubdir(cls):
|
||||
return 'bom'
|
||||
|
||||
filters = models.CharField(
|
||||
|
@ -0,0 +1,3 @@
|
||||
{% extends "report/inventree_build_order_base.html" %}
|
||||
|
||||
<!-- Refer to the inventree_build_order_base template -->
|
@ -0,0 +1,185 @@
|
||||
{% extends "report/inventree_report_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load report %}
|
||||
{% load inventree_extras %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block page_margin %}
|
||||
margin: 2cm;
|
||||
margin-top: 4cm;
|
||||
{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
|
||||
.header-right {
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 20mm;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.part-image {
|
||||
border: 1px solid;
|
||||
border-radius: 2px;
|
||||
vertical-align: middle;
|
||||
height: 40mm;
|
||||
display: inline-block;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.details-image {
|
||||
max-width: 25%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.details {
|
||||
width: 100%;
|
||||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
padding: 5px;
|
||||
min-height: 42mm;
|
||||
}
|
||||
|
||||
.details table {
|
||||
overflow-x: scroll
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
width: 70%;
|
||||
table-layout: fixed;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.details table td:not(:last-child){
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.details table td:last-child{
|
||||
width: 50%;
|
||||
padding-left: 1cm;
|
||||
padding-right: 1cm;
|
||||
}
|
||||
|
||||
.details-table td {
|
||||
padding-left: 10px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #555;
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block bottom_left %}
|
||||
content: "v{{report_revision}} - {{ date.isoformat }}";
|
||||
{% endblock %}
|
||||
|
||||
{% block bottom_center %}
|
||||
content: "www.currawong.aero";
|
||||
{% endblock %}
|
||||
|
||||
{% block header_content %}
|
||||
<img class='logo' src="{% asset 'logo_black_with_black_bird.png' %}" alt="hello" width="150">
|
||||
|
||||
<div class='header-right'>
|
||||
<h3>
|
||||
Build Order {{ build }}
|
||||
</h3>
|
||||
<small>{{ quantity }} x {{ part.full_name }}</small>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
|
||||
<div class='details'>
|
||||
<div class='details-image float-right'>
|
||||
<img class='part-image' src="{% part_image part %}">
|
||||
</div>
|
||||
|
||||
<div class='details-container'>
|
||||
|
||||
<table class='details-table'>
|
||||
<tr>
|
||||
<th>{% trans "Build Order" %}</th>
|
||||
<td>{% internal_link build.get_absolute_url build %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Part" %}</th>
|
||||
<td>{% internal_link part.get_absolute_url part.full_name %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Quantity" %}</th>
|
||||
<td>{{ build.quantity }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<td>{{ build.title }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Issued" %}</th>
|
||||
<td>{{ build.creation_date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Target Date" %}</th>
|
||||
<td>
|
||||
{% if build.target_date %}
|
||||
{{ build.target_date }}
|
||||
{% else %}
|
||||
<i>Not specified</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Sales Order" %}</th>
|
||||
<td>
|
||||
{% if build.sales_order %}
|
||||
{% internal_link build.sales_order.get_absolute_url build.sales_order %}
|
||||
{% else %}
|
||||
<i>Not specified</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if build.parent %}
|
||||
<tr>
|
||||
<th>{% trans "Required For" %}</th>
|
||||
<td>{% internal_link build.parent.get_absolute_url build.parent %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.issued_by %}
|
||||
<tr>
|
||||
<th>{% trans "Issued By" %}</th>
|
||||
<td>{{ build.issued_by }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.responsible %}
|
||||
<tr>
|
||||
<th>{% trans "Responsible" %}</th>
|
||||
<td>{{ build.responsible }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.link %}
|
||||
<tr>
|
||||
<th>{% trans "Link" %}</th>
|
||||
<td><a href="{{ build.link }}">{{ build.link }}</a></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>{% trans "Notes" %}</h3>
|
||||
|
||||
{% if build.notes %}
|
||||
{{ build.notes|markdownify }}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user