mutipart
This commit is contained in:
@@ -344,6 +344,53 @@ export async function restoreAttachmentsFromApi(apiFiles = [], existingAttachmen
|
||||
return attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect new or modified attachments for multipart upload
|
||||
* @param {Array<{file: File, name: string, type: string, thumbnail?: string, text?: string, parentPdfId?: string|number, isPersisted?: boolean, isDirty?: boolean}>} attachments
|
||||
* @param {{ onlyNew?: boolean }} [options]
|
||||
* @returns {Array<{file: File, name: string, mimetype: string, meta?: object}>}
|
||||
*/
|
||||
export function collectFilesForUpload(attachments = [], { onlyNew = false } = {}) {
|
||||
const files = [];
|
||||
for (const attachment of attachments) {
|
||||
if (!attachment) continue;
|
||||
// Skip already persisted attachments in update mode unless modified
|
||||
if (onlyNew && attachment.isPersisted && !attachment.isDirty) {
|
||||
continue;
|
||||
}
|
||||
if (attachment.isPersisted && !attachment.isDirty && (!attachment.file || attachment.file.size === 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let fileToUpload = attachment.file;
|
||||
if (!fileToUpload || fileToUpload.size === 0) {
|
||||
if (attachment.text) {
|
||||
fileToUpload = new File([attachment.text], attachment.name || 'file.txt', {
|
||||
type: 'text/plain;charset=utf-8',
|
||||
});
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const meta = {};
|
||||
if (attachment.parentPdfId) {
|
||||
meta.parentPdfId = String(attachment.parentPdfId);
|
||||
}
|
||||
if (attachment.text) {
|
||||
meta.text = String(attachment.text);
|
||||
}
|
||||
|
||||
files.push({
|
||||
file: fileToUpload,
|
||||
name: attachment.name || fileToUpload.name,
|
||||
mimetype: attachment.type || fileToUpload.type,
|
||||
meta: Object.keys(meta).length > 0 ? meta : undefined,
|
||||
});
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ number: string, externalNumber?: string, date: string, partyId: number|null, lines: object[], attachments?: object[] }} form
|
||||
* @param {{ partyField: 'supplierId'|'entityId', requireAtLeastOne: boolean, externalNumber?: boolean }} opts
|
||||
@@ -380,9 +427,22 @@ export async function buildManifestBody(
|
||||
// Add files if attachments exist
|
||||
if (form.attachments && form.attachments.length > 0) {
|
||||
const isUpdate = !requireAtLeastOne;
|
||||
const filesToUpload = await buildFilesForUpload(form.attachments, { onlyNew: isUpdate });
|
||||
const filesToUpload = collectFilesForUpload(form.attachments, { onlyNew: isUpdate });
|
||||
if (filesToUpload.length > 0) {
|
||||
body.files = filesToUpload;
|
||||
const filesMeta = filesToUpload
|
||||
.filter((f) => f.meta)
|
||||
.map((f) => ({ name: f.name, meta: f.meta }));
|
||||
|
||||
if (filesMeta.length > 0) {
|
||||
body.filesMeta = filesMeta;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(body));
|
||||
for (const item of filesToUpload) {
|
||||
formData.append('files', item.file, item.name);
|
||||
}
|
||||
return formData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user