mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-11 20:59:36 +00:00
Erweitere Exportfunktion um lesbare BOM-Option (PDF-Ausgabe).
Neue Auswahloption "Lesbarer Export" hinzugefügt, die den Export hierarchischer Baugruppen als PDF ermöglicht.
This commit is contained in:
parent
5e3a9ec90c
commit
82d867f5be
19 changed files with 571 additions and 44 deletions
|
|
@ -7,30 +7,41 @@ export default class extends Controller {
|
|||
};
|
||||
|
||||
connect() {
|
||||
this.readableCheckbox = this.element.querySelector("#readable");
|
||||
this.displayCheckbox = this.element.querySelector("#display");
|
||||
this.displaySelect = this.element.querySelector("select#display");
|
||||
|
||||
if (!this.readableCheckbox) {
|
||||
return;
|
||||
if (this.displayCheckbox) {
|
||||
this.toggleContainers(this.displayCheckbox.checked);
|
||||
|
||||
this.displayCheckbox.addEventListener("change", (event) => {
|
||||
this.toggleContainers(event.target.checked);
|
||||
});
|
||||
}
|
||||
|
||||
// Apply the initial visibility state based on the checkbox being checked or not
|
||||
this.toggleContainers(this.readableCheckbox.checked);
|
||||
if (this.displaySelect) {
|
||||
this.toggleContainers(this.hasDisplaySelectValue());
|
||||
|
||||
this.displaySelect.addEventListener("change", () => {
|
||||
this.toggleContainers(this.hasDisplaySelectValue());
|
||||
});
|
||||
}
|
||||
|
||||
// Add a change event listener to the 'readable' checkbox
|
||||
this.readableCheckbox.addEventListener("change", (event) => {
|
||||
// Toggle container visibility when the checkbox value changes
|
||||
this.toggleContainers(event.target.checked);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the visibility of containers based on the checkbox state.
|
||||
* Hides specified containers if the checkbox is checked and shows them otherwise.
|
||||
*
|
||||
* @param {boolean} isChecked - The current state of the checkbox:
|
||||
* true if checked (hide elements), false if unchecked (show them).
|
||||
* Check whether a value was selected in the selectbox
|
||||
* @returns {boolean} True when a value has not been selected that is not empty
|
||||
*/
|
||||
toggleContainers(isChecked) {
|
||||
hasDisplaySelectValue() {
|
||||
return this.displaySelect && this.displaySelect.value !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides specified containers if the state is active (checkbox checked or select with value).
|
||||
*
|
||||
* @param {boolean} isActive - True when the checkbox is activated or the selectbox has a value.
|
||||
*/
|
||||
toggleContainers(isActive) {
|
||||
if (!Array.isArray(this.classesValue) || this.classesValue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -42,11 +53,10 @@ export default class extends Controller {
|
|||
return;
|
||||
}
|
||||
|
||||
// Update the visibility for each selected element
|
||||
elements.forEach((element) => {
|
||||
// If the checkbox is checked, hide the container; otherwise, show it
|
||||
element.style.display = isChecked ? "none" : "";
|
||||
element.style.display = isActive ? "none" : "";
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,16 @@ namespace App\Helpers\Assemblies;
|
|||
|
||||
use App\Entity\AssemblySystem\Assembly;
|
||||
use App\Entity\Parts\Part;
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
use Twig\Environment;
|
||||
|
||||
class AssemblyPartAggregator
|
||||
{
|
||||
public function __construct(private readonly Environment $twig)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregate the required parts and their total quantities for an assembly.
|
||||
*
|
||||
|
|
@ -80,4 +87,181 @@ class AssemblyPartAggregator
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a hierarchical Bill of Materials (BOM) for assemblies and parts in a readable format,
|
||||
* including the multiplier for each part and assembly.
|
||||
*
|
||||
* @param Assembly $assembly The root assembly to export.
|
||||
* @param string $indentationSymbol The symbol used for indentation (e.g., ' ').
|
||||
* @param int $initialDepth The starting depth for formatting (default: 0).
|
||||
* @return string Human-readable hierarchical BOM list.
|
||||
*/
|
||||
public function exportReadableHierarchy(Assembly $assembly, string $indentationSymbol = ' ', int $initialDepth = 0): string
|
||||
{
|
||||
// Start building the hierarchy
|
||||
$output = '';
|
||||
$this->processAssemblyHierarchy($assembly, $initialDepth, 1, $indentationSymbol, $output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function exportReadableHierarchyForPdf(array $assemblyHierarchies): string
|
||||
{
|
||||
$html = $this->twig->render('assemblies/export_bom_pdf.html.twig', [
|
||||
'assemblies' => $assemblyHierarchies,
|
||||
]);
|
||||
|
||||
$options = new Options();
|
||||
$options->set('isHtml5ParserEnabled', true);
|
||||
$options->set('isPhpEnabled', true);
|
||||
|
||||
$dompdf = new Dompdf($options);
|
||||
$dompdf->loadHtml($html);
|
||||
$dompdf->setPaper('A4');
|
||||
$dompdf->render();
|
||||
|
||||
$canvas = $dompdf->getCanvas();
|
||||
$font = $dompdf->getFontMetrics()->getFont('Arial', 'normal');
|
||||
|
||||
return $dompdf->output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method to process assemblies and their parts.
|
||||
*
|
||||
* @param Assembly $assembly The current assembly to process.
|
||||
* @param int $depth The current depth in the hierarchy.
|
||||
* @param float $parentMultiplier The multiplier inherited from the parent (default is 1 for root).
|
||||
* @param string $indentationSymbol The symbol used for indentation.
|
||||
* @param string &$output The cumulative output string.
|
||||
*/
|
||||
private function processAssemblyHierarchy(Assembly $assembly, int $depth, float $parentMultiplier, string $indentationSymbol, string &$output): void
|
||||
{
|
||||
// Add the current assembly to the output
|
||||
if ($depth === 0) {
|
||||
$output .= sprintf(
|
||||
"%sAssembly: %s [IPN: %s]\n\n",
|
||||
str_repeat($indentationSymbol, $depth),
|
||||
$assembly->getName(),
|
||||
$assembly->getIpn(),
|
||||
);
|
||||
} else {
|
||||
$output .= sprintf(
|
||||
"%sAssembly: %s [IPN: %s, Multiplier: %.2f]\n\n",
|
||||
str_repeat($indentationSymbol, $depth),
|
||||
$assembly->getName(),
|
||||
$assembly->getIpn(),
|
||||
$parentMultiplier
|
||||
);
|
||||
}
|
||||
|
||||
// Gruppiere BOM-Einträge in Kategorien
|
||||
$parts = [];
|
||||
$referencedAssemblies = [];
|
||||
$others = [];
|
||||
|
||||
foreach ($assembly->getBomEntries() as $bomEntry) {
|
||||
if ($bomEntry->getPart() instanceof Part) {
|
||||
$parts[] = $bomEntry;
|
||||
} elseif ($bomEntry->getReferencedAssembly() instanceof Assembly) {
|
||||
$referencedAssemblies[] = $bomEntry;
|
||||
} else {
|
||||
$others[] = $bomEntry;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($parts)) {
|
||||
// Process each BOM entry for the current assembly
|
||||
foreach ($parts as $bomEntry) {
|
||||
$effectiveQuantity = $bomEntry->getQuantity() * $parentMultiplier;
|
||||
|
||||
$output .= sprintf(
|
||||
"%sPart: %s [IPN: %s, MPNR: %s, Quantity: %.2f%s, EffectiveQuantity: %.2f]\n",
|
||||
str_repeat($indentationSymbol, $depth + 1),
|
||||
$bomEntry->getPart()?->getName(),
|
||||
$bomEntry->getPart()?->getIpn() ?? '-',
|
||||
$bomEntry->getPart()?->getManufacturerProductNumber() ?? '-',
|
||||
$bomEntry->getQuantity(),
|
||||
$parentMultiplier > 1 ? sprintf(", Multiplier: %.2f", $parentMultiplier) : '',
|
||||
$effectiveQuantity,
|
||||
);
|
||||
}
|
||||
|
||||
$output .= "\n";
|
||||
}
|
||||
|
||||
foreach ($referencedAssemblies as $bomEntry) {
|
||||
// Add referenced assembly details
|
||||
$referencedQuantity = $bomEntry->getQuantity() * $parentMultiplier;
|
||||
|
||||
$output .= sprintf(
|
||||
"%sReferenced Assembly: %s [IPN: %s, Quantity: %.2f%s, EffectiveQuantity: %.2f]\n",
|
||||
str_repeat($indentationSymbol, $depth + 1),
|
||||
$bomEntry->getReferencedAssembly()->getName(),
|
||||
$bomEntry->getReferencedAssembly()->getIpn() ?? '-',
|
||||
$bomEntry->getQuantity(),
|
||||
$parentMultiplier > 1 ? sprintf(", Multiplier: %.2f", $parentMultiplier) : '',
|
||||
$referencedQuantity,
|
||||
);
|
||||
|
||||
// Recurse into the referenced assembly
|
||||
$this->processAssemblyHierarchy(
|
||||
$bomEntry->getReferencedAssembly(),
|
||||
$depth + 2, // Increase depth for nested assemblies
|
||||
$referencedQuantity, // Pass the calculated multiplier
|
||||
$indentationSymbol,
|
||||
$output
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($others as $bomEntry) {
|
||||
$output .= sprintf(
|
||||
"%sOther: %s [Quantity: %.2f, Multiplier: %.2f]\n",
|
||||
str_repeat($indentationSymbol, $depth + 1),
|
||||
$bomEntry->getName(),
|
||||
$bomEntry->getQuantity(),
|
||||
$parentMultiplier,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function processAssemblyHierarchyForPdf(Assembly $assembly, int $depth, float $quantity, float $parentMultiplier): array
|
||||
{
|
||||
$result = [
|
||||
'name' => $assembly->getName(),
|
||||
'ipn' => $assembly->getIpn(),
|
||||
'quantity' => $quantity,
|
||||
'multiplier' => $depth === 0 ? null : $parentMultiplier,
|
||||
'parts' => [],
|
||||
'referencedAssemblies' => [],
|
||||
'others' => [],
|
||||
];
|
||||
|
||||
foreach ($assembly->getBomEntries() as $bomEntry) {
|
||||
if ($bomEntry->getPart() instanceof Part) {
|
||||
$result['parts'][] = [
|
||||
'name' => $bomEntry->getPart()->getName(),
|
||||
'ipn' => $bomEntry->getPart()->getIpn(),
|
||||
'quantity' => $bomEntry->getQuantity(),
|
||||
'effectiveQuantity' => $bomEntry->getQuantity() * $parentMultiplier,
|
||||
];
|
||||
} elseif ($bomEntry->getReferencedAssembly() instanceof Assembly) {
|
||||
$result['referencedAssemblies'][] = $this->processAssemblyHierarchyForPdf(
|
||||
$bomEntry->getReferencedAssembly(),
|
||||
$depth + 1,
|
||||
$bomEntry->getQuantity(),
|
||||
$parentMultiplier * $bomEntry->getQuantity()
|
||||
);
|
||||
} else {
|
||||
$result['others'][] = [
|
||||
'name' => $bomEntry->getName(),
|
||||
'quantity' => $bomEntry->getQuantity(),
|
||||
'multiplier' => $parentMultiplier,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,8 +81,9 @@ class EntityExporter
|
|||
$resolver->setDefault('include_children', false);
|
||||
$resolver->setAllowedTypes('include_children', 'bool');
|
||||
|
||||
$resolver->setDefault('readable', false);
|
||||
$resolver->setAllowedTypes('readable', 'bool');
|
||||
$resolver->setDefault('readableSelect', null);
|
||||
$resolver->setAllowedValues('readableSelect', [null, 'readable', 'readable_bom']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -240,7 +241,7 @@ class EntityExporter
|
|||
$entities = [$entities];
|
||||
}
|
||||
|
||||
if ($request->get('readable', false)) {
|
||||
if ($request->get('readableSelect', false) === 'readable') {
|
||||
// Map entity classes to export functions
|
||||
$entityExportMap = [
|
||||
AttachmentType::class => fn($entities) => $this->exportReadable($entities, AttachmentType::class),
|
||||
|
|
@ -273,6 +274,23 @@ class EntityExporter
|
|||
|
||||
$options['format'] = 'csv';
|
||||
$options['level'] = 'readable';
|
||||
} if ($request->get('readableSelect', false) === 'readable_bom') {
|
||||
$hierarchies = [];
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
if (!$entity instanceof Assembly) {
|
||||
throw new InvalidArgumentException('Only assemblies can be exported in readable BOM format');
|
||||
}
|
||||
|
||||
$hierarchies[] = $this->assemblyPartAggregator->processAssemblyHierarchyForPdf($entity, 0, 1, 1);
|
||||
}
|
||||
|
||||
$pdfContent = $this->assemblyPartAggregator->exportReadableHierarchyForPdf($hierarchies);
|
||||
|
||||
$response = new Response($pdfContent);
|
||||
|
||||
$options['format'] = 'pdf';
|
||||
$options['level'] = 'readable_bom';
|
||||
} else {
|
||||
//Do the serialization with the given options
|
||||
$serialized_data = $this->exportEntities($entities, $options);
|
||||
|
|
@ -294,6 +312,7 @@ class EntityExporter
|
|||
'json' => 'application/json',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'pdf' => 'application/pdf',
|
||||
default => 'text/plain',
|
||||
};
|
||||
$response->headers->set('Content-Type', $content_type);
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@
|
|||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="offset-md-3 col-sm">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input form-check-input" name="readable" id="readable" type="checkbox" data-action="change->toggle-visibility#toggle">
|
||||
<label class="form-check-label form-check-label" for="readable">
|
||||
{% trans %}export.readable{% endtrans %}
|
||||
</label>
|
||||
</div>
|
||||
<label class="col-form-label col-md-3" for="readableSelect" >{% trans %}export.readable.label{% endtrans %}</label>
|
||||
<div class="col-md-9">
|
||||
<select id="display" name="readableSelect" class="form-select" data-action="change->action-handler#handleAction">
|
||||
<option value="" selected></option>
|
||||
<option value="readable">{% trans %}export.readable{% endtrans %}</option>
|
||||
<option value="readable_bom">{% trans %}export.readable_bom{% endtrans %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -50,4 +50,4 @@
|
|||
<button type="submit" class="btn btn-primary">{% trans %}export.btn{% endtrans %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
|||
103
templates/assemblies/export_bom_pdf.html.twig
Normal file
103
templates/assemblies/export_bom_pdf.html.twig
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Assembly Hierarchy</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
||||
table { border-collapse: collapse; width: 100%; margin-top: 10px; font-size: 10px;}
|
||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||
th { background-color: #f2f2f2; }
|
||||
.assembly-header { font-size: 14px; font-weight: bold; margin-top: 10px; margin-bottom: 10px; }
|
||||
.toc-table { margin-bottom: 40px; width: auto; font-size: 12px; }
|
||||
.toc-table th, .toc-table td { border: none; padding: 5px; text-align: left; }
|
||||
.referenced-assembly-table { margin-left: 20px; margin-top: 10px; }
|
||||
.page-break { page-break-after: always; }
|
||||
#footer { position: fixed; right: 0px; bottom: 10px; text-align: center; font-size: 10px; }
|
||||
#footer .page:after { content: counter(page, decimal); }
|
||||
@page { margin: 20px 30px 40px 50px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Inhaltsverzeichnis -->
|
||||
<h1>Table of Contents</h1>
|
||||
<table class="toc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Assembly Name</th>
|
||||
<th>IPN</th>
|
||||
<th>Section</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for assembly in assemblies %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
<td>Assembly: {{ assembly.name }}</td>
|
||||
<td>{% if assembly.ipn != '' %}{{ assembly.ipn }}{% else %}-{% endif %}</td>
|
||||
<td>{{ loop.index + 1 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="page-break"></div>
|
||||
|
||||
<!-- Assembly Details -->
|
||||
{% for assembly in assemblies %}
|
||||
<div class="assembly-header">Assembly: {{ assembly.name }}</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>IPN</th>
|
||||
<th>Quantity</th>
|
||||
<th>Multiplier</th>
|
||||
<th>Effective Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for part in assembly.parts %}
|
||||
<tr>
|
||||
<td>{{ part.name }}</td>
|
||||
<td>{{ part.ipn }}</td>
|
||||
<td>{{ part.quantity }}</td>
|
||||
<td>{% if assembly.multiplier %}{{ assembly.multiplier }}{% else %}-{% endif %}</td>
|
||||
<td>{{ part.effectiveQuantity }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for other in assembly.others %}
|
||||
<tr>
|
||||
<td>{{ other.name }}</td>
|
||||
<td>{{ other.ipn }}</td>
|
||||
<td>{{ other.quantity }}</td>
|
||||
<td>{{ other.multiplier }}</td>
|
||||
<td>{{ other.effectiveQuantity }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for referencedAssembly in assembly.referencedAssemblies %}
|
||||
<tr>
|
||||
<td>{{ referencedAssembly.name }}</td>
|
||||
<td>{{ referencedAssembly.ipn }}</td>
|
||||
<td>{{ referencedAssembly.quantity }}</td>
|
||||
<td></td>
|
||||
<td>{{ referencedAssembly.quantity }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% for refAssembly in assembly.referencedAssemblies %}
|
||||
{% include 'assemblies/export_bom_referenced_assembly_pdf.html.twig' with {'assembly': refAssembly} only %}
|
||||
{% endfor %}
|
||||
|
||||
{% if not loop.last %}
|
||||
<div style="page-break-after: always;"></div>
|
||||
{% endif %}
|
||||
|
||||
<div id="footer">
|
||||
<p class="page">Section </p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<div class="referenced-assembly-table">
|
||||
<div class="assembly-header">Referenced Assembly: {{ assembly.name }} [IPN: {% if assembly.ipn != '' %}{{ assembly.ipn }}{% else %}-{% endif %}, quantity: {{ assembly.quantity }}]</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Name</th>
|
||||
<th>IPN</th>
|
||||
<th>Quantity</th>
|
||||
<th>Multiplier</th>
|
||||
<th>Effective Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for part in assembly.parts %}
|
||||
<tr>
|
||||
<td>Part</td>
|
||||
<td>{{ part.name }}</td>
|
||||
<td>{{ part.ipn }}</td>
|
||||
<td>{{ part.quantity }}</td>
|
||||
<td>{% if assembly.multiplier %}{{ assembly.multiplier }}{% else %}-{% endif %}</td>
|
||||
<td>{{ part.effectiveQuantity }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% for other in assembly.others %}
|
||||
<tr>
|
||||
<td>Other</td>
|
||||
<td>{{ other.name }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ other.quantity }}</td>
|
||||
<td>{{ other.multiplier }}</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% for referencedAssembly in assembly.referencedAssemblies %}
|
||||
<tr>
|
||||
<td>Referenced assembly</td>
|
||||
<td>{{ referencedAssembly.name }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ referencedAssembly.quantity }}</td>
|
||||
<td></td>
|
||||
<td>{{ referencedAssembly.multiplier }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Rekursive Auflistung weiterer Assemblies -->
|
||||
{% for refAssembly in assembly.referencedAssemblies %}
|
||||
{% include 'assemblies/export_bom_referenced_assembly_pdf.html.twig' with {'assembly': refAssembly} only %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Exportovat všechny prvky</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Čitelný export</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Čitelné CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="M.rXmnA" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Eksportér alle elementer</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Læsbar eksport</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Læsbar CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zPSdxU4" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -1010,10 +1010,22 @@ Subelemente werden beim Löschen nach oben verschoben.</target>
|
|||
<target>Unterelemente auch exportieren</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Lesbarer Export</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Lesbares CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Pdmfku8" name="export.btn">
|
||||
|
|
|
|||
|
|
@ -228,10 +228,22 @@
|
|||
<target>Εξαγωγή όλων των στοιχείων</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Αναγνώσιμη εξαγωγή</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Αναγνώσιμο CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zPSdxU4" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Export all elements</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Readable Export</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Readable CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="M.rXmnA" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Exportar todos los elementos</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Exportación legible</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>CSV legible</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="M.rXmnA" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -320,10 +320,22 @@
|
|||
<target>Exporter tous les éléments</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Export lisible</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>CSV lisible</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zPSdxU4" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Esportare tutti gli elementi</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Esporta leggibile</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>CSV leggibile</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="M.rXmnA" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -320,10 +320,22 @@
|
|||
<target>すべてエクスポートする</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>読みやすいエクスポート</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>読みやすいCSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zPSdxU4" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Exporteer alle elementen</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Leesbare export</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Leesbare CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zPSdxU4" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Eksportuj wszystkie elementy</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Eksport czytelny</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Czytelny CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="M.rXmnA" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>Экспортировать всё</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>Читаемый экспорт</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>Читаемый CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="M.rXmnA" name="mass_creation.help">
|
||||
|
|
|
|||
|
|
@ -351,10 +351,22 @@
|
|||
<target>导出所有元素</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Ujhd6e3" name="export.readable.label">
|
||||
<segment state="translated">
|
||||
<source>export.readable.label</source>
|
||||
<target>可读导出</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="a5h8ltP" name="export.readable">
|
||||
<segment state="translated">
|
||||
<source>export.readable</source>
|
||||
<target>可读的 CSV</target>
|
||||
<target>CSV</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="keJnq8f" name="export.readable_bom">
|
||||
<segment state="translated">
|
||||
<source>export.readable_bom</source>
|
||||
<target>PDF</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="zPSdxU4" name="mass_creation.help">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue