diff --git a/check_run/check_run/doctype/check_run/check_run.py b/check_run/check_run/doctype/check_run/check_run.py index 5ed3e6e5..33e4beeb 100644 --- a/check_run/check_run/doctype/check_run/check_run.py +++ b/check_run/check_run/doctype/check_run/check_run.py @@ -20,6 +20,7 @@ from frappe.contacts.doctype.address.address import get_default_address from frappe.query_builder.custom import ConstantColumn from frappe.query_builder.functions import Coalesce, Sum +from frappe.desk.form.load import get_attachments from erpnext.accounts.utils import get_balance_on from erpnext.accounts.doctype.payment_entry.payment_entry import PaymentEntry @@ -607,6 +608,12 @@ def get_entries(doc: CheckRun | str) -> dict: query, {"company": company, "pay_to_account": pay_to_account, "end_date": end_date}, as_dict=True ) for transaction in transactions: + doc_name = transaction.ref_number if transaction.ref_number else transaction.name + transaction.attachments = [ + attachment for attachment in get_attachments(transaction.doctype, doc_name) + if attachment.file_url.endswith('.pdf') + ] or [{'file_name': doc_name, 'file_url': f'/app/Form/{transaction.doctype}/{doc_name}'}] + if settings and settings.pre_check_overdue_items: if transaction.due_date < doc.posting_date: transaction.pay = 1 diff --git a/check_run/check_run/report/__init__.py b/check_run/check_run/report/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/check_run/check_run/report/payables_attachments/__init__.py b/check_run/check_run/report/payables_attachments/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/check_run/check_run/report/payables_attachments/payables_attachments.js b/check_run/check_run/report/payables_attachments/payables_attachments.js new file mode 100644 index 00000000..c71ad7eb --- /dev/null +++ b/check_run/check_run/report/payables_attachments/payables_attachments.js @@ -0,0 +1,13 @@ +// Copyright (c) 2023, AgriTheory and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports['Payables Attachments'] = { + filters: [], +} + +frappe.ui.addFilePreviewWrapper() + +function pdf_preview(file_url) { + frappe.ui.pdfPreview(cur_frm, file_url) +} diff --git a/check_run/check_run/report/payables_attachments/payables_attachments.json b/check_run/check_run/report/payables_attachments/payables_attachments.json new file mode 100644 index 00000000..96f252df --- /dev/null +++ b/check_run/check_run/report/payables_attachments/payables_attachments.json @@ -0,0 +1,35 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2023-08-11 10:09:28.938669", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "modified": "2023-08-11 10:09:28.938669", + "modified_by": "Administrator", + "module": "Check Run", + "name": "Payables Attachments", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Purchase Invoice", + "report_name": "Payables Attachments", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Purchase User" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Auditor" + } + ] +} \ No newline at end of file diff --git a/check_run/check_run/report/payables_attachments/payables_attachments.py b/check_run/check_run/report/payables_attachments/payables_attachments.py new file mode 100644 index 00000000..b479a7be --- /dev/null +++ b/check_run/check_run/report/payables_attachments/payables_attachments.py @@ -0,0 +1,145 @@ +# Copyright (c) 2022, AgriTheory and contributors +# For license information, please see license.txt + +import frappe +from frappe.desk.form.load import get_attachments +from frappe.query_builder import DocType +from pypika import Order + + +def execute(filters=None): + return get_columns(filters), get_data(filters) + +def get_data(filters): + PurchaseInvoice = DocType("Purchase Invoice") + data = ( + frappe.qb.from_(PurchaseInvoice) + .select( + PurchaseInvoice.name, PurchaseInvoice.title, PurchaseInvoice.supplier, PurchaseInvoice.company, + PurchaseInvoice.posting_date, PurchaseInvoice.grand_total, PurchaseInvoice.status, PurchaseInvoice.currency, + PurchaseInvoice.supplier_name, PurchaseInvoice.grand_total, PurchaseInvoice.outstanding_amount, + PurchaseInvoice.due_date, PurchaseInvoice.is_return, PurchaseInvoice.release_date, PurchaseInvoice.represents_company, + PurchaseInvoice.is_internal_supplier + ) + .orderby('modified', Order.desc) + ).run(as_dict=True) + + for row in data: + row['attachments'] = " ".join([ + f"""{attachment.file_name}""" + for attachment in get_attachments('Purchase Invoice', row['name']) if attachment.file_url.endswith('.pdf') + ]) + return data + +def get_columns(filters): + return [ + + { + "label": frappe._("Name"), + "fieldname": "name", + "fieldtype": "Link", + "options": "Purchase Invoice", + "width": "150px", + }, + { + "label": frappe._("Title"), + "fieldname": "title", + "fieldtype": "Data", + "width": "200px", + }, + { + "label": frappe._("Supplier"), + "fieldname": "supplier", + "fieldtype": "Link", + "options": "Supplier", + "width": "200px", + }, + { + "label": frappe._("Supplier Name"), + "fieldname": "supplier_name", + "fieldtype": "Data", + "width": "200px", + }, + { + "label": frappe._("Company"), + "fieldname": "company", + "fieldtype": "Link", + "options": "Company", + "width": "200px", + }, + { + "label": frappe._("Date"), + "fieldname": "posting_date", + "fieldtype": "Date", + "width": "200px", + }, + { + "label": frappe._("Grand Total"), + "fieldname": "grand_total", + "fieldtype": "Currency", + "width": "200px", + }, + { + "label": frappe._("Status"), + "fieldname": "status", + "fieldtype": "Data", + "width": "200px", + }, + { + "label": frappe._("Currency"), + "fieldname": "currency", + "fieldtype": "Link", + "options": "Currency", + "width": "200px", + }, + { + "label": frappe._("Grand Total (Company Currency)"), + "fieldname": "grand_total", + "fieldtype": "Currency", + "width": "200px", + }, + { + "label": frappe._("Outstanding Amount"), + "fieldname": "outstanding_amount", + "fieldtype": "Currency", + "width": "200px", + }, + { + "label": frappe._("Due Date"), + "fieldname": "due_date", + "fieldtype": "Date", + "width": "200px", + }, + { + "label": frappe._("Is Return (Debit Note)"), + "fieldname": "is_return", + "fieldtype": "Check", + "width": "200px", + }, + { + "label": frappe._("Release Date"), + "fieldname": "release_date", + "fieldtype": "Date", + "width": "200px", + }, + { + "label": frappe._("Represents Company"), + "fieldname": "represents_company", + "fieldtype": "Link", + "options": "Company", + "width": "200px", + }, + { + "label": frappe._("Is Internal Supplier"), + "fieldname": "is_internal_supplier", + "fieldtype": "Check", + "width": "200px", + }, + { + "label": frappe._("Attachments"), + "fieldname": "attachments", + "fieldtype": "Data", + "width": "400px", + }, + ] + diff --git a/check_run/hooks.py b/check_run/hooks.py index 361a6e6a..b829b54d 100644 --- a/check_run/hooks.py +++ b/check_run/hooks.py @@ -18,6 +18,8 @@ app_include_js = [ "check_run.bundle.js", ] +app_include_css = "/assets/check_run/css/file_preview.css" + # include js, css files in header of web template # web_include_css = "/assets/check_run/css/check_run.css" diff --git a/check_run/public/css/file_preview.css b/check_run/public/css/file_preview.css new file mode 100644 index 00000000..5d577a8d --- /dev/null +++ b/check_run/public/css/file_preview.css @@ -0,0 +1,61 @@ +.fa-file-pdf-o { + font-size: 120%; + padding-left: 0.5ch; + color: var(--brand-secondary); +} +#close-pdf-button { + position: absolute; + top: 10px; + right: 10px; +} +#pdf-preview-wrapper { + position: fixed; + width: calc(1290px / 2); + height: calc(100vh - 135px); + top: 135px; + right: calc((100vw - 1290px) / 2); + display: none; +} +#pdf-preview-wrapper.pdf-preview-wrapper-fw { + width: calc(90vw / 2); + height: calc(100vh - 135px); + right: calc(10vw / 2); +} +#pdf-preview-wrapper.pdf-preview-wrapper-fw #pdf-preview { + width: calc(90vw / 2); +} +.page-body.show-pdf-preview #pdf-preview-wrapper { + display: block; +} +#pdf-preview { + position: absolute; + top: 50px; + left: 0; + right: 0; + bottom: 0; + width: calc(1290px / 2); + height: calc(100vh - 135px - 20px); +} +.page-body.show-pdf-preview .page-wrapper .page-content { + width: calc(50% - 10px); +} + +.portal-widget { + position: absolute; + top: 5px; + right:5px; + bottom:5px; + left:5px; + border-radius: 5px; + box-shadow: 0px 1px 2px rgba(25, 39, 52, 0.05), 0px 0px 4px rgba(25, 39, 52, 0.1); +} +a.portal-widget-col { + position: relative; + padding: 20px; + text-decoration: none; +} + +.widget-row { + margin-top: 10px; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/check_run/public/js/check_run.bundle.js b/check_run/public/js/check_run.bundle.js index f81c5c24..24c936cb 100644 --- a/check_run/public/js/check_run.bundle.js +++ b/check_run/public/js/check_run.bundle.js @@ -1,2 +1,3 @@ import './check_run/check_run_quick_entry.js' import './check_run/check_run.js' +import './custom/file_preview.js' diff --git a/check_run/public/js/check_run/CheckRun.vue b/check_run/public/js/check_run/CheckRun.vue index a7038d1a..adda310b 100644 --- a/check_run/public/js/check_run/CheckRun.vue +++ b/check_run/public/js/check_run/CheckRun.vue @@ -43,7 +43,7 @@ >⬍ -