"""Tools for generating reports.
They are often required, but who ever remembers the params and
criteria? These classes are designed to capture that knowledge
for re-use.
They should be pretty strightforward to use:
.. code-block:: python
report = POPurchaseOrderReport("PO0001", "PO0003")
report.generate(destination="preview")
To print to a file:
.. code-block:: python
report = POPurchaseOrderReport("PO0001", "PO0003")
report.generate(destination="file", path="C:\\Temp\\report.pdf")
To open the print dialogue, pass the UI instance:
.. code-block:: python
report = POPurchaseOrderReport("PO0001", "PO0003", ui=self)
report.generate(destination="file", path="C:\\Temp\\report.pdf")
To override a parameter:
.. code-block:: python
report = POPurchaseOrderReport("PO0001", "PO0003", ONHOLD="1")
report.generate(destination="file", path="C:\\Temp\\report.pdf")
To override the selection criteria:
.. code-block:: python
criteria = "((POPORH.ORDNUMBER = 'ORD00001'))"
report = POPurchaseOrderReport("PO0001", "PO0003",
**{"@SELECTION_CRITERIA": criteria})
report.generate(destination="file", path="C:\\Temp\\report.pdf")
"""
try:
from accpac import Report, getOrgPath, showMessageBox
except ImportError:
pass
import time
from pathlib import Path
from datetime import datetime
from extools.message import logger_for_module
[docs]def get_report_class_for_report_name(name):
for klass in REPORT_CLASSES:
if name in klass.reports:
return klass
return None
[docs]def get_report_class_for_parameter_set(paramset):
for klass in REPORT_CLASSES:
if klass.parameter_set == paramset:
return klass
return None
[docs]def get_report_class_for(report_name):
try:
parameter_set, _rest = report_name.split("[")
report = _rest.rstrip("]")
except ValueError as e:
return None
for klass in REPORT_CLASSES:
if klass.parameter_set == parameter_set and report in klass.reports:
return klass
return None
[docs]class ReportWrapper(object):
parameter_set = ""
reports = []
selection_criteria = ""
parameters = {}
def __init__(self, **kwargs):
self.kwargs = kwargs
self.log = logger_for_module('extools')
[docs] def generate(self, report_name, from_id="", to_id="",
destination="file", path="", ui=None):
report = Report()
report.reportName = report_name
report.destination = destination.lower()
if destination.lower() == "file":
if not path:
now = datetime.now().strftime("%Y%m%dT%H%M")
path = Path(getOrgPath(), '{}-report.pdf'.format(now))
report.printDirectory = str(path)
ui = None
criteria = self.selection_criteria.format(
from_id=from_id, to_id=to_id)
try:
for key, value in self.parameters.items():
if key not in self.kwargs:
val = value.replace(
"{to_id}", to_id
).replace("{from_id}", from_id)
report.setParameter(key, val)
if criteria and not "@SELECTION_CRITERIA" in self.kwargs:
report.setParameter("@SELECTION_CRITERIA", criteria)
for key, value in self.kwargs.items():
val = value.replace(
"{to_id}", to_id
).replace("{from_id}", from_id)
report.setParameter(key, val)
result = report.print(ui)
except Exception as err:
self.log.error("Failed to print {}: {}".format(report_name, err))
if destination == 'file':
if self.wait_for(path):
return path
return None
[docs] def wait_for(self, path, tries=5, sleep=3):
run = 0
while run < tries:
if path.exists():
return True
time.sleep(sleep)
run += 1
return False
[docs]class OEInvoiceReport(ReportWrapper):
parameter_set = "OEINV03"
reports = ("OEINV03.RPT", )
selection_criteria = ('(({{OEINVH.INVNUMBER}} >= "{from_id}") AND '
'({{OEINVH.INVNUMBER}} <= "{to_id}"))')
parameters = {
"SORTFROM": "{from_id}",
"SORTTO": "{to_id}",
"PRINTED": "1",
"QTYDEC": "0",
"PRINTKIT": "0",
"PRINTBOM": "0",
"SERIALLOTNUMBERS": "0",
"SWDELMETHOD": "3",
"ECENABLED": "0",
}
[docs]class POPurchaseOrderReport(ReportWrapper):
parameter_set = "POPOR04"
reports = ("POPOR04.RPT", )
selection_critieria = """
(({{POPORH1.PONUMBER}} >= "{from_id}")
AND ({{POPORH1.PONUMBER}} <= "{to_id}"))
"""
parameters = {
"PORFROM": "{from_id}",
"PORTO": "{to_id}",
"ACTIVE": "1",
"BLANKET": "1",
"FUTURE": "1",
"STANDING": "1",
"PRINTED": "1",
"DPRINTED": "1",
"ECENABLED": "0",
"DIRECTEC": "0",
"DELMETHOD": "1",
"SORTFROM": "{from_id}",
"SORTTO": "{ponumber}",
"SWDELMETHOD": "3",
"QTYDEC": "0",
}
[docs]class EFTVendorRemittanceReport(ReportWrapper):
parameter_set = "ELPAY01"
reports = ("ELPAY04.RPT", )
parameters = {
"BATCHTYPE": "PY",
"FROMBTCH": 0,
"TOBTCH": 0,
"FROMENTRY": 0,
"TOENTRY": 0,
"UNPOSTED": "0",
"DELMETHOD": "1",
}
[docs]class APChequeReport(ReportWrapper):
parameter_set = "BKCHKSTK"
reports = ("APCHK01.RPT", )
parameters = {
"STARTSERIAL": "{from_id}",
"ENDSERIAL": "{to_id}",
"APPRUNNUM": "",
"EXTPARAM1": "2", # Cheque Number
"EXTPARAM2": " ",
"EXTPARAM3": " ",
}
[docs]class PayrollChequeReportGenerator(ReportWrapper):
parameter_set = "BKCHKSTK"
reports = ("CPCHK4A.RPT", )
parameters = {
"STARTSERIAL": "{from_id}",
"ENDSERIAL": "{to_id}",
"APPRUNNUM": "",
"EXTPARAM1": "2",
"EXTPARAM2": "True",
"EXTPARAM3": " ",
}
REPORT_CLASSES = (
POPurchaseOrderReport,
OEInvoiceReport,
EFTVendorRemittanceReport,
PayrollChequeReportGenerator,
)
[docs]class InvoiceActionsReport(ReportWrapper):
parameter_set = "OEINACTS"
reports = ("OEINACTS.RPT", )
params = {
"REPORTTYPE": "1",
"FROMSHIPMENT": "{from_id}",
"TOSHIPMENT": "{to_id}",
"THENBY": "1",
"THENBYFROM": " ",
"THENBYTO": " ",
"FROMDATE": "0",
"TODATE": "20500101",
"PRINTAMTIN": "1",
"FUNCDECS": "2",
"QTYDECS": "4",
"SWMULTICURR": "0",
"SWPMACTIVE": "0",
"SWINCLJOB": "0",
"LEVEL1NAME": " ",
"LEVEL2NAME": " ",
"LEVEL3NAME": " ",
}