Hello, previously I was able to attach a file when before_save a doctype, but I wanted to attach it to a folder other than the Attachments folder but because I have no clue how to do it, so I want to use another method, namely by uploading the file to the file manager but to a specific folder such as the /docs/letter folder.
This is the logic flow
- The user creates a letter doctype, by filling in the requirements and letter number (I have successfully created it)
- In the server_script, before_save will create a word file from what the user filled in (I have successfully created it)
3.a. The word file will be attached but should go into the Attachments/docs/letter folder (Don’t know how)
3.b. Or the word file will be uploaded to the file manager and go into the Docs/letter folder (Don’t know how)
For now what I have succeeded in doing is the word file is successfully attached, but it goes into the Attachments folder in the file manager, and I don’t want that.
What I’ve done
- Use AI
- Find out on the internet
This is the code
# Copyright (c) 2024, Wahyu Triono and contributors
# For license information, please see license.txt
import frappe
from docxtpl import DocxTemplate, InlineImage
from frappe.model.document import Document
from docx.shared import Mm
class SuratTugas(Document):
def before_save(self):
karyawan_items = self.get_karyawan_data()
nama_surat = f'{self.no_surat.replace('/', '-')}.docx'
self.create_document(nama_surat, karyawan_items)
self.attach_file_to_document(nama_surat)
# Membuat array yang berisi data karyawan untuk dimasukan kedalam dokumen
def get_karyawan_data(self):
karyawan_items = []
for item in self.karyawan:
karyawan_doc = frappe.get_doc('User', item.email)
karyawan_items.append({
'nama': karyawan_doc.full_name,
'ktp': karyawan_doc.user_image,
# 'department': karyawan_doc.department,
# 'image': karyawan_doc.foto # asumsikan ada field foto
})
return karyawan_items
def create_document(self, nama_surat, karyawan_items):
template_path = frappe.utils.get_site_path('private', 'templates', 'st_kelompok.docx')
doc = DocxTemplate(template_path)
tanggal = frappe.utils.formatdate(frappe.utils.nowdate(), "dddd, dd MMMM yyyy")
table_context = []
for karyawan in karyawan_items:
image_path = None
if karyawan['ktp']:
image_name = karyawan['ktp'].split('/')[-1]
image_path = frappe.utils.get_site_path('private', 'files', image_name)
table_context.append({
'nama': karyawan['nama'],
'image': InlineImage(doc, image_path, width=Mm(20), height=Mm(20)) if image_path else None
})
# Siapkan context untuk template
context = {
'no_surat': self.no_surat,
'keperluan': self.keperluan,
'site': self.site,
'tanggal': tanggal,
'table': table_context
}
# Render template
doc.render(context)
# Simpan dokumen yang dihasilkan
docx_file_path = frappe.utils.get_site_path('private', 'files', nama_surat)
doc.save(docx_file_path)
# pdf_file_path = frappe.utils.get_site_path('private', 'files', 'surat_keterangan.pdf')
# pypandoc.convert_file(docx_file_path, 'pdf', outputfile=pdf_file_path)
def attach_file_to_document(self, nama_surat):
# Path relatif ke file dalam folder private
file_path = frappe.utils.get_site_path('private', 'files', nama_surat)
# Buat file di Frappe dengan path file lokal
file_doc = frappe.get_doc({
'doctype': 'File',
'file_name': nama_surat,
'file_path': file_path, # Gunakan file_path untuk path lokal
'is_private': 1,
'attached_to_doctype': 'Surat Tugas',
'attached_to_name': self.name, # Attach ke dokumen Surat Tugas saat ini
})
file_doc.insert()
# Jika ingin menyimpan path file ke field di dokumen
self.dokumen = file_path