Skip to content

Commit

Permalink
Port preview to V14 (#153)
Browse files Browse the repository at this point in the history
* File Preview (#140)

* wip: file preview

* feat: preview in check run, allow to preview in non submittable documents

* feat: WIP payables attachment report

* feat: wip preview of attachments

* style: prettify code

* feat: close with space

* fix: do not open sidebar in check run

* wip: multiple attachments in check run

* fix: merge

* style: prettify code

* fix: df-preview-wrapper-fw

* feat: improve code

* feat: improve code

* feat: columns

---------

Co-authored-by: Tyler Matteson <[email protected]>
Co-authored-by: fproldan <[email protected]>

* feat: use query builder in payables attachments report'

* fix: build

* fix: add remove btn

* style: prettify code

---------

Co-authored-by: Tyler Matteson <[email protected]>
Co-authored-by: fproldan <[email protected]>
  • Loading branch information
3 people authored Sep 11, 2023
1 parent a3cfc97 commit 78d2666
Show file tree
Hide file tree
Showing 11 changed files with 382 additions and 3 deletions.
7 changes: 7 additions & 0 deletions check_run/check_run/doctype/check_run/check_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -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)
}
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
Original file line number Diff line number Diff line change
@@ -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"""<a data-pdf-preview="{attachment.file_url}" onclick="pdf_preview('{attachment.file_url}')">{attachment.file_name}</a>"""
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",
},
]

2 changes: 2 additions & 0 deletions check_run/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
61 changes: 61 additions & 0 deletions check_run/public/css/file_preview.css
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions check_run/public/js/check_run.bundle.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import './check_run/check_run_quick_entry.js'
import './check_run/check_run.js'
import './custom/file_preview.js'
23 changes: 20 additions & 3 deletions check_run/public/js/check_run/CheckRun.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
>&#11021;</span
>
</th>
<th v-if="state.status == 'Draft'" style="min-width: 200px; text-align: left">
<th v-if="state.status == 'Draft'" class="col col-sm-1" style="text-align: left">
<input
type="checkbox"
autocomplete="off"
Expand All @@ -52,7 +52,7 @@
id="select-all"
v-model="selectAll" /><span>Select All</span>
</th>
<th v-else class="col col-sm-2">Check Number | Reference</th>
<th v-else class="col col-sm-1">Check Number | Reference</th>
</tr>
</thead>
<tbody>
Expand All @@ -65,10 +65,22 @@
tabindex="1"
@click="state.selectedRow = i">
<td style="text-align: left">{{ item.party_name || item.party }}</td>
<td>
<td style="text-align: left;white-space: nowrap;">
<a :href="transactionUrl(item)" target="_blank">
{{ item.ref_number || item.name }}
</a>
<div v-if="item.attachments.length > 1" style="float: right;" class="dropdown show">
<a class="btn btn-default btn-xs dropdown-toggle" href="#" role="button" :id="item.name" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-search"></i>
</a>
<div class="dropdown-menu" :aria-labelledby="item.name">
<a v-for="attachment in item.attachments" class="dropdown-item" href="javascript:;" @click="showPreview(attachment.file_url)" data-pdf-preview="item">{{ attachment.file_name }}</a>
</div>
</div>

<button v-if="item.attachments.length == 1" style="float: right;" type="button" class="btn btn-secondary btn-xs" @click="showPreview(item.attachments)" data-pdf-preview="item">
<i @click="showPreview(item.attachments)" data-pdf-preview="item" class="fa fa-search"></i>
</button>
</td>
<td>{{ item.posting_date }}</td>
<td class="mop-onclick" :data-mop-index="i">
Expand Down Expand Up @@ -198,6 +210,11 @@ export default {
}
this.$refs.dropdowns[this.state.selectedRow].openWithSearch()
},
showPreview(attachment) {
var file_url = typeof attachment == 'string' ? attachment : attachment[0].file_url
frappe.ui.addFilePreviewWrapper()
frappe.ui.pdfPreview(cur_frm, file_url)
}
},
beforeMount() {
this.moment = moment
Expand Down
Loading

0 comments on commit 78d2666

Please sign in to comment.