Browse Source

Import C4 Reports

master
Adam McGuigan 5 years ago
parent
commit
4601d36add
  1. 36
      Constants.py
  2. 2
      Costs.py
  3. 477
      Counter4.py
  4. 108
      FetchData.py
  5. 35
      GeneralUtils.py
  6. 234
      ImportFile.py
  7. 16
      ManageDB.py
  8. 2
      README.md
  9. 2
      Search.py
  10. 48
      Visual.py
  11. BIN
      executables/Linux/Counter 5 Report Tool.zip
  12. BIN
      executables/Windows/COUNTER 5 Report Tool.zip
  13. BIN
      executables/macOS/Counter 5 Report Tool.zip
  14. BIN
      images/import-report-updated.png
  15. 30
      tests/test_ImportFile.py
  16. 379
      ui/ImportReportTab.py
  17. 444
      ui/ImportReportTab.ui
  18. 160
      ui/VisualTab.py
  19. 362
      ui/VisualTab.ui
  20. 1
      vendor-lists/template-vendor-lists
  21. 115
      vendor-lists/vendors-template-R5-only.tsv
  22. 183
      vendor-lists/vendors-template-with-r4-vendors.tsv

36
Constants.py

@ -1,7 +1,7 @@
from enum import Enum from enum import Enum
# Variable Constants for MainDriver.py # Variable Constants for MainDriver.py
HELP_SITE = "https://git.library.upei.ca/mbelvadi/COUNTER-5-Report-Tool/wiki" HELP_SITE = "https://github.com/CS-4820-Library-Project/COUNTER-5-Report-Tool/wiki"
# region Variable Constants for ManageDB # region Variable Constants for ManageDB
@ -427,6 +427,7 @@ CURRENCY_LIST = ('USD', 'EUR', 'JPY', 'GBP', 'CHF', 'CAD', 'AUD')
JSON_FILTER = ('JSON files (*.dat)',) JSON_FILTER = ('JSON files (*.dat)',)
TSV_FILTER = ('TSV files (*.tsv)',) TSV_FILTER = ('TSV files (*.tsv)',)
CSV_FILTER = ('CSV files (*.csv)',) CSV_FILTER = ('CSV files (*.csv)',)
TSV_AND_CSV_FILTER = ('Report files (*.csv *.tsv)',)
EXCEL_FILTER = ('Excel files (*.xlsx)',) EXCEL_FILTER = ('Excel files (*.xlsx)',)
# endregion # endregion
@ -607,3 +608,36 @@ VENDORS_FILE_PATH = VENDORS_FILE_DIR + VENDORS_FILE_NAME
EXPORT_VENDORS_FILE_NAME = "exported_vendor_data.tsv" EXPORT_VENDORS_FILE_NAME = "exported_vendor_data.tsv"
# endregion # endregion
# region Variable Constants for ImportFile
COUNTER_4_REPORT_EQUIVALENTS = {
"BR1": "TR, TR_B1",
"BR1, BR2": "TR, TR_B1",
"BR1, BR2, BR3, JR1, JR2": "TR, TR_B1, TR_B2, TR_J1, TR_J2",
"BR2": "TR, TR_B1",
"BR3": "TR, TR_B2",
"DB1": "DR, DR_D1",
"DB1, DB2": "DR, DR_D1, DR_D2",
"DB2": "DR, DR_D2",
"JR1": "TR, TR_J1",
"JR1, JR2": "TR, TR_J1, TR_J2",
"JR2": "TR, TR_J2",
"PR1": "PR, PR_P1"
}
COUNTER_5_REPORT_EQUIVALENTS = {
"TR_B1": "BR1, BR2",
"TR_B2": "BR3",
"TR_J1": "JR1",
"TR_J2": "JR2",
"TR": "BR1, BR2, BR3, JR1, JR2",
"DR_D1": "DB1",
"DR_D2": "DB2",
"DR": "DB1, DB2",
"JR1": "TR_J1",
"JR2": "TR_J2",
"PR_P1": "PR1",
"PR": "PR1"
}
# endregion

2
Costs.py

@ -148,7 +148,7 @@ class CostsController:
self.names = [result[0] for result in names_results] self.names = [result[0] for result in names_results]
else: else:
self.names = [] self.names = []
if self.settings.show_debug_messages: print(names_results) # if self.settings.show_debug_messages: print(names_results)
costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter, costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter,
self.vendor_parameter, self.vendor_parameter,

477
Counter4.py

@ -0,0 +1,477 @@
import csv
from datetime import datetime, timezone
from os import path, makedirs
from PyQt5.QtCore import QDate
import GeneralUtils
from Constants import COUNTER_4_REPORT_EQUIVALENTS, COUNTER_5_REPORT_EQUIVALENTS, MajorReportType
from FetchData import ReportRow, ReportHeaderModel, TypeValueModel, NameValueModel, ReportWorker
from ManageVendors import Vendor
class Counter4ReportHeader:
def __init__(self, report_type: str, customer: str, institution_id: str, reporting_period: str, date_run: str):
self.report_type = report_type
self.customer = customer
self.institution_id = institution_id
self.reporting_period = reporting_period
self.date_run = date_run
class Counter4ReportModel:
def __init__(self, report_header: Counter4ReportHeader, header_list: list, row_dicts: list):
self.report_header = report_header
self.header_list = header_list
self.row_dicts = row_dicts
class Counter4To5Converter:
def __init__(self, vendor: Vendor, c4_report_types: str, file_paths: list, save_dir: str, date: QDate):
self.vendor = vendor
self.c4_report_types = c4_report_types
self.file_paths = file_paths
self.save_dir = save_dir
self.begin_date = QDate(date.year(), 1, 1)
self.end_date = QDate(date.year(), 12, 31)
self.target_c5_report_types = self.get_c5_equivalent(c4_report_types)
self.final_rows_dict = {}
def do_conversion(self) -> dict:
file_paths = {}
report_rows_dict = {} # {report_type: report_rows_dict}
c4_report_types_processed = []
c4_customer = ""
c4_institution_id = ""
for file_path in self.file_paths:
report_model = self.c4_file_to_c4_model(file_path)
c4_report_header = report_model.report_header
short_c4_report_type = self.get_short_c4_report_type(c4_report_header.report_type)
if short_c4_report_type not in self.c4_report_types:
continue
c4_report_types_processed.append(short_c4_report_type)
c4_customer = c4_report_header.customer
c4_institution_id = c4_report_header.institution_id
report_rows = self.c4_model_to_rows(report_model)
report_rows_dict[short_c4_report_type] = report_rows
if not c4_report_types_processed:
raise Exception("No valid COUNTER 4 report selected for this operation")
# Create a final COUNTER 5 file for each target c5 report type
for c5_report_type in self.target_c5_report_types.split(", "):
required_c4_report_types = self.get_c4_equivalent(c5_report_type).split(", ")
c4_report_types_used = []
c5_report_type_rows = []
# Fill up c5_report_type_rows with rows from required_c4_report_types
for c4_report_type in required_c4_report_types:
if c4_report_type in report_rows_dict:
c5_report_type_rows += report_rows_dict[c4_report_type]
c4_report_types_used.append(c4_report_type)
if not c4_report_types_used: # If no c4 file for this c5 report type is available
continue
# Sort the rows
c5_major_report_type = GeneralUtils.get_major_report_type(c5_report_type)
c5_report_type_rows = ReportWorker.sort_rows(c5_report_type_rows, c5_major_report_type)
# Create header for this report
c5_report_header = self.get_c5_report_header(c5_report_type,
", ".join(c4_report_types_used),
c4_customer,
c4_institution_id)
# Create the c5 file
file_path = self.create_c5_file(c5_report_header, c5_report_type_rows)
file_paths[c5_report_type] = file_path
return file_paths
def c4_file_to_c4_model(self, file_path: str) -> Counter4ReportModel:
file = open(file_path, 'r', encoding="utf-8")
extension = file_path[-4:]
delimiter = ""
if extension == ".csv":
delimiter = ","
elif extension == ".tsv":
delimiter = "\t"
# Process process report header into model
csv_reader = csv.reader(file, delimiter=delimiter)
report_type = ""
customer = ""
institution_id = ""
reporting_period = ""
date_run = ""
curr_line = 1
last_header_line = 7
for row in csv_reader:
if curr_line == 1:
report_type = row[0]
elif curr_line == 2:
customer = row[0]
elif curr_line == 3:
institution_id = row[0]
elif curr_line == 4 and row[0].lower() != "period covered by report:":
file.close()
raise Exception("'Period covered by Report:' missing from header line 4")
elif curr_line == 5:
reporting_period = row[0]
elif curr_line == 6 and row[0].lower() != "date run:":
file.close()
raise Exception("'Date run:' missing from header line 6")
elif curr_line == 7:
date_run = row[0]
is_valid_date = QDate().fromString(date_run, "yyyy-MM-dd").isValid() or \
QDate().fromString(date_run, "MM-dd-yy").isValid() or \
QDate().fromString(date_run, "M-d-yy").isValid()
if not is_valid_date:
file.close()
raise Exception("Invalid date on line 7")
curr_line += 1
if curr_line > last_header_line:
break
if curr_line <= last_header_line:
file.close()
raise Exception("Not enough lines in report header")
report_header = Counter4ReportHeader(report_type, customer, institution_id, reporting_period, date_run)
# Process process report rows into model
csv_dict_reader = csv.DictReader(file, delimiter=delimiter)
header_dict = csv_dict_reader.fieldnames
row_dicts = []
for row in csv_dict_reader:
row_dicts.append(row)
report_model = Counter4ReportModel(report_header, header_dict, row_dicts)
file.close()
return report_model
def c4_model_to_rows(self, report_model: Counter4ReportModel) -> list:
short_c4_report_type = self.get_short_c4_report_type(report_model.report_header.report_type)
c4_major_report_type = self.get_c4_major_report_type(short_c4_report_type)
report_rows_dict = {} # {name, metric_type: report_row}
for row_dict in report_model.row_dicts:
report_row = self.convert_c4_row_to_c5(short_c4_report_type, row_dict)
if report_row.total_count == 0: # Exclude rows with reporting total of 0
continue
if c4_major_report_type == MajorReportType.DATABASE:
if report_row.database.lower().startswith("total for all"): # Exclude total rows
continue
if (report_row.database, report_row.metric_type) not in report_rows_dict:
report_rows_dict[report_row.database, report_row.metric_type] = report_row
else:
existing_row: ReportRow = report_rows_dict[report_row.database, report_row.metric_type]
existing_metric_type_total = existing_row.total_count
new_metric_type_total = report_row.total_count
if existing_row.metric_type == "Total_Item_Investigations":
if new_metric_type_total > existing_metric_type_total:
report_rows_dict[report_row.database, report_row.metric_type] = report_row
elif c4_major_report_type == MajorReportType.TITLE:
if report_row.title.lower().startswith("total for all"): # Exclude total rows
continue
if (report_row.title, report_row.metric_type) not in report_rows_dict:
report_rows_dict[report_row.title, report_row.metric_type] = report_row
else:
existing_row: ReportRow = report_rows_dict[report_row.title, report_row.metric_type]
existing_metric_type_total = existing_row.total_count
new_metric_type_total = report_row.total_count
if existing_row.metric_type == "Total_Item_Investigations":
if new_metric_type_total > existing_metric_type_total:
report_rows_dict[report_row.title, report_row.metric_type] = report_row
elif c4_major_report_type == MajorReportType.PLATFORM:
report_rows_dict[report_row.platform, report_row.metric_type] = report_row
return list(report_rows_dict.values())
def convert_c4_row_to_c5(self, c4_report_type: str, row_dict: dict) -> ReportRow:
report_row = ReportRow(self.begin_date, self.end_date)
c4_major_report_type = self.get_c4_major_report_type(c4_report_type)
if c4_major_report_type == MajorReportType.DATABASE:
if "Database" in row_dict:
report_row.database = row_dict["Database"]
if "Publisher" in row_dict:
report_row.publisher = row_dict["Publisher"]
if "Platform" in row_dict:
report_row.platform = row_dict["Platform"]
# Metric type
if c4_report_type == "DB1":
if "User Activity" in row_dict:
ua = row_dict["User Activity"]
if ua == "Regular Searches":
report_row.metric_type = "Searches_Regular"
elif "federated and automated" in ua: # Searches-federated and automated
report_row.metric_type = "Searches_Automated"
elif ua == "Result Clicks" or ua == "Record Views":
report_row.metric_type = "Total_Item_Investigations"
elif c4_report_type == "DB2":
adc = None
if "Access Denied Category" in row_dict:
adc = row_dict["Access Denied Category"]
elif "Access denied category" in row_dict:
adc = row_dict["Access denied category"]
if adc:
if "limit exceded" in adc or "limit exceeded" in adc:
report_row.metric_type = "Limit_Exceeded"
elif "not licenced" in adc or "not licensed" in adc:
report_row.metric_type = "No_License"
elif c4_major_report_type == MajorReportType.TITLE:
if "" in row_dict:
report_row.title = row_dict[""]
if "Title" in row_dict:
report_row.title = row_dict["Title"]
if "Journal" in row_dict:
report_row.title = row_dict["Journal"]
if "Publisher" in row_dict:
report_row.publisher = row_dict["Publisher"]
if "Platform" in row_dict:
report_row.platform = row_dict["Publisher"]
if "Book DOI" in row_dict:
report_row.doi = row_dict["Book DOI"]
if "Journal DOI" in row_dict:
report_row.doi = row_dict["Journal DOI"]
if "Proprietary Identifier" in row_dict:
report_row.proprietary_id = row_dict["Proprietary Identifier"]
if "ISBN" in row_dict:
report_row.isbn = row_dict["ISBN"]
if "ISSN" in row_dict:
report_row.online_issn = row_dict["ISSN"]
if "Print ISSN" in row_dict:
report_row.print_issn = row_dict["Print ISSN"]
if "Online ISSN" in row_dict:
report_row.print_issn = row_dict["Online ISSN"]
# Metric type
if c4_report_type == "BR1":
report_row.metric_type = "Unique_Title_Requests"
elif c4_report_type == "BR2" or c4_report_type == "JR1":
report_row.metric_type = "Total_Item_Requests"
elif c4_report_type == "BR3" or c4_report_type == "JR2":
adc = None
if "Access Denied Category" in row_dict:
adc = row_dict["Access Denied Category"]
elif "Access denied category" in row_dict:
adc = row_dict["Access denied category"]
if adc:
if "limit exceded" in adc or "limit exceeded" in adc:
report_row.metric_type = "Limit_Exceeded"
elif "not licenced" in adc or "not licensed" in adc:
report_row.metric_type = "No_License"
elif c4_major_report_type == MajorReportType.PLATFORM:
if "Platform" in row_dict:
report_row.platform = row_dict["Platform"]
if "Publisher" in row_dict:
report_row.publisher = row_dict["Publisher"]
# Metric type
if c4_report_type == "PR1":
if "User Activity" in row_dict:
ua = row_dict["User Activity"]
if ua == "Regular Searches":
report_row.metric_type = "Searches_Regular"
elif ua == "Searches-federated and automated":
report_row.metric_type = "Searches_Automated"
elif ua == "Result Clicks" or ua == "Record Views":
report_row.metric_type = "Total_Item_Investigations"
if "Reporting Period Total" in row_dict:
if row_dict["Reporting Period Total"]:
report_row.total_count = int(row_dict["Reporting Period Total"])
else:
report_row.total_count = 0
# Month Columns
year = int(self.begin_date.toString("yyyy"))
year2 = int(self.begin_date.toString("yy"))
for i in range(0, 12):
month = QDate(year, i + 1, 1).toString("MMM")
month_year = f"{month}-{year}"
month_year2 = f"{month}-{year2}"
year_month = f"{year}-{month}"
year_month2 = f"{year2}-{month}"
month_value = ""
if month_year in row_dict:
month_value = row_dict[month_year]
elif month_year2 in row_dict:
month_value = row_dict[month_year2]
elif year_month in row_dict:
month_value = row_dict[year_month]
elif year_month2 in row_dict:
month_value = row_dict[year_month2]
if month_value:
report_row.month_counts[month_year] = int(month_value)
return report_row
def get_c5_report_header(self, target_c5_report_type, c4_report_types: str, customer: str,
institution_id: str) -> ReportHeaderModel:
return ReportHeaderModel(self.get_long_c5_report_type(target_c5_report_type),
target_c5_report_type,
"5",
customer,
[TypeValueModel("Institution_ID", institution_id)],
self.get_c5_header_report_filters(target_c5_report_type),
[],
[],
self.get_c5_header_created(),
self.get_c5_header_created_by(c4_report_types))
def create_c5_file(self, c5_report_header: ReportHeaderModel, report_rows: list) -> str:
c5_report_type = c5_report_header.report_id
file_path = self.save_dir + f"temp_converted_c5_file_{c5_report_type}.tsv"
if not path.isdir(self.save_dir):
makedirs(self.save_dir)
file = open(file_path, 'w', encoding="utf-8", newline='')
ReportWorker.add_report_header_to_file(c5_report_header, file, True)
ReportWorker.add_report_rows_to_file(c5_report_type, report_rows, self.begin_date, self.end_date,
file, False)
file.close()
return file_path
@staticmethod
def get_short_c4_report_type(long_c4_report_type: str) -> str:
short_report_type = ""
if "Book Report 1 (R4)" in long_c4_report_type:
short_report_type = "BR1"
elif "Book Report 2 (R4)" in long_c4_report_type:
short_report_type = "BR2"
elif "Book Report 3 (R4)" in long_c4_report_type:
short_report_type = "BR3"
elif "Database Report 1 (R4)" in long_c4_report_type:
short_report_type = "DB1"
elif "Database Report 2 (R4)" in long_c4_report_type:
short_report_type = "DB2"
elif "Journal Report 1 (R4)" in long_c4_report_type:
short_report_type = "JR1"
elif "Journal Report 2 (R4)" in long_c4_report_type:
short_report_type = "JR2"
elif "Platform Report 1 (R4)" in long_c4_report_type:
short_report_type = "PR1"
return short_report_type
@staticmethod
def get_long_c5_report_type(short_c5_report_type: str) -> str:
long_c5_report_type = ""
if short_c5_report_type == "DR":
long_c5_report_type = "Database Master Report"
elif short_c5_report_type == "DR_D1":
long_c5_report_type = "Database Search and Item Usage"
elif short_c5_report_type == "DR_D2":
long_c5_report_type = "Database Access Denied"
elif short_c5_report_type == "TR":
long_c5_report_type = "Title Master Report"
elif short_c5_report_type == "TR_B1":
long_c5_report_type = "Book Requests (Excluding OA_Gold)"
elif short_c5_report_type == "TR_B2":
long_c5_report_type = "Book Access Denied"
elif short_c5_report_type == "TR_J1":
long_c5_report_type = "Journal Requests (Excluding OA_Gold)"
elif short_c5_report_type == "TR_J2":
long_c5_report_type = "Journal Access Denied"
elif short_c5_report_type == "PR_P1":
long_c5_report_type = "Platform Usage"
return long_c5_report_type
def get_c5_header_report_filters(self, target_c5_report_type: str) -> list:
filters = []
if target_c5_report_type == "DR_D1":
filters = [NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Searches_Automated|Searches_Federated|Searches_Regular|"
"Total_Item_Investigations|Total_Item_Requests")]
elif target_c5_report_type == "DR_D2":
filters = [NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Limit_Exceeded|No_License")]
elif target_c5_report_type == "PR_P1":
filters = [NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Searches_Platform|Total_Item_Requests|Unique_Item_Requests|"
"Unique_Title_Requests")]
elif target_c5_report_type == "TR_B1":
filters = [NameValueModel("Data_Type", "Book"),
NameValueModel("Access_Type", "Controlled"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Total_Item_Requests|Unique_Title_Requests")]
elif target_c5_report_type == "TR_B2":
filters = [NameValueModel("Data_Type", "Book"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Limit_Exceeded|No_License")]
elif target_c5_report_type == "TR_J1":
filters = [NameValueModel("Data_Type", "Journal"),
NameValueModel("Access_Type", "Controlled"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Total_Item_Requests|Unique_Item_Requests")]
elif target_c5_report_type == "TR_J2":
filters = [NameValueModel("Data_Type", "Journal"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Limit_Exceeded|No_License")]
filters += [NameValueModel("Begin_Date", self.begin_date.toString("yyyy-MM-dd")),
NameValueModel("End_Date", self.end_date.toString("yyyy-MM-dd"))]
return filters
@staticmethod
def get_c5_header_created() -> str:
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
def get_c5_header_created_by(self, short_c4_report_type: str) -> str:
return f"COUNTER 5 Report Tool, converted from {self.vendor.name} COP4 {short_c4_report_type}"
@staticmethod
def get_c5_equivalent(counter4_report_type: str) -> str:
return COUNTER_4_REPORT_EQUIVALENTS[counter4_report_type]
@staticmethod
def get_c4_equivalent(counter5_report_type: str) -> str:
return COUNTER_5_REPORT_EQUIVALENTS[counter5_report_type]
@staticmethod
def get_c4_major_report_type(c4_report_type: str) -> MajorReportType:
"""Returns a major report type that a report type falls under"""
if c4_report_type == "DB1" or c4_report_type == "DB2":
return MajorReportType.DATABASE
elif c4_report_type == "BR1" or c4_report_type == "BR2" or c4_report_type == "BR3" \
or c4_report_type == "JR1" or c4_report_type == "JR2":
return MajorReportType.TITLE
elif c4_report_type == "PR1":
return MajorReportType.PLATFORM

108
FetchData.py

@ -191,7 +191,7 @@ class ReportModel(JsonModel):
report_header = ReportHeaderModel.from_json(json_dict["Report_Header"]) report_header = ReportHeaderModel.from_json(json_dict["Report_Header"])
report_type = report_header.report_id report_type = report_header.report_id
major_report_type = get_major_report_type(report_type) major_report_type = GeneralUtils.get_major_report_type(report_type)
report_header.major_report_type = major_report_type report_header.major_report_type = major_report_type
report_items = [] report_items = []
@ -509,23 +509,6 @@ def get_models(model_key: str, model_type, json_dict: dict) -> list:
return models return models
def get_major_report_type(report_type: str) -> MajorReportType:
"""Returns a major report type that a report type falls under"""
if report_type == "PR" or report_type == "PR_P1":
return MajorReportType.PLATFORM
elif report_type == "DR" or report_type == "DR_D1" or report_type == "DR_D2":
return MajorReportType.DATABASE
elif report_type == "TR" or report_type == "TR_B1" or report_type == "TR_B2" \
or report_type == "TR_B3" or report_type == "TR_J1" or report_type == "TR_J2" \
or report_type == "TR_J3" or report_type == "TR_J4":
return MajorReportType.TITLE
elif report_type == "IR" or report_type == "IR_A1" or report_type == "IR_M1":
return MajorReportType.ITEM
def get_month_years(begin_date: QDate, end_date: QDate) -> list: def get_month_years(begin_date: QDate, end_date: QDate) -> list:
"""Returns a list of month-year (MMM-yyyy) strings within a date range""" """Returns a list of month-year (MMM-yyyy) strings within a date range"""
month_years = [] month_years = []
@ -623,19 +606,6 @@ class ReportRow:
self.month_counts = {} self.month_counts = {}
# This only works with 12 months
# for i in range(12):
# curr_date: QDate
# if QDate(begin_date.year(), i + 1, 1) < begin_date:
# curr_date = QDate(end_date.year(), i + 1, 1)
# else:
# curr_date = QDate(begin_date.year(), i + 1, 1)
#
# self.month_counts[curr_date.toString("MMM-yyyy")] = 0
#
# self.total_count = 0
# This works with more than 12 months
for month_year_str in get_month_years(begin_date, end_date): for month_year_str in get_month_years(begin_date, end_date):
self.month_counts[month_year_str] = 0 self.month_counts[month_year_str] = 0
@ -1513,18 +1483,8 @@ class FetchSpecialReportsController(FetchReportsAbstract):
""" """
if date_type == "begin_date": if date_type == "begin_date":
self.begin_date = QDate(date.year(),self.begin_date.month(),self.begin_date.day()) self.begin_date = QDate(date.year(),self.begin_date.month(),self.begin_date.day())
# if self.begin_date.year() != self.end_date.year():
# self.end_date.setDate(self.begin_date.year(),
# self.end_date.month(),
# self.end_date.day())
# self.end_date_edit.setDate(self.end_date)
elif date_type == "end_date": elif date_type == "end_date":
self.end_date = QDate(date.year(),self.end_date.month(),self.end_date.day()) self.end_date = QDate(date.year(),self.end_date.month(),self.end_date.day())
# if self.end_date.year() != self.begin_date.year():
# self.begin_date.setDate(self.end_date.year(),
# self.begin_date.month(),
# self.begin_date.day())
# self.begin_date_edit.setDate(self.begin_date)
def on_date_month_changed(self, month: int, date_type: str): def on_date_month_changed(self, month: int, date_type: str):
"""Handles the signal emitted when a date's month is changed """Handles the signal emitted when a date's month is changed
@ -2068,7 +2028,7 @@ class ReportWorker(QObject):
attributes_to_show += f"|{option_name}" attributes_to_show += f"|{option_name}"
attr_count += 1 attr_count += 1
elif self.is_yearly and self.is_master: elif self.is_yearly and self.is_master:
major_report_type = get_major_report_type(self.report_type) major_report_type = GeneralUtils.get_major_report_type(self.report_type)
if major_report_type == MajorReportType.PLATFORM: if major_report_type == MajorReportType.PLATFORM:
attributes_to_show = "|".join(PLATFORM_REPORTS_ATTRIBUTES) attributes_to_show = "|".join(PLATFORM_REPORTS_ATTRIBUTES)
elif major_report_type == MajorReportType.DATABASE: elif major_report_type == MajorReportType.DATABASE:
@ -2460,7 +2420,8 @@ class ReportWorker(QObject):
report_rows = self.sort_rows(report_rows, major_report_type) report_rows = self.sort_rows(report_rows, major_report_type)
self.save_tsv_files(report_model.report_header, report_rows) self.save_tsv_files(report_model.report_header, report_rows)
def sort_rows(self, report_rows: list, major_report_type: MajorReportType) -> list: @staticmethod
def sort_rows(report_rows: list, major_report_type: MajorReportType) -> list:
"""Sorts the rows of the report """Sorts the rows of the report
:param report_rows: The report's rows :param report_rows: The report's rows
@ -2507,7 +2468,8 @@ class ReportWorker(QObject):
else: else:
self.add_report_header_to_file(report_header, file, True) self.add_report_header_to_file(report_header, file, True)
if not self.add_report_rows_to_file(report_type, report_rows, file, False): if not self.add_report_rows_to_file(report_type, report_rows, self.begin_date, self.end_date, file, False,
self.is_special, self.special_options):
self.process_result.completion_status = CompletionStatus.WARNING self.process_result.completion_status = CompletionStatus.WARNING
file.close() file.close()
@ -2528,12 +2490,13 @@ class ReportWorker(QObject):
protected_file_path = f"{protected_file_dir}{file_name}" protected_file_path = f"{protected_file_dir}{file_name}"
protected_file = open(protected_file_path, 'w', encoding="utf-8", newline='') protected_file = open(protected_file_path, 'w', encoding="utf-8", newline='')
self.add_report_header_to_file(report_header, protected_file, True) self.add_report_header_to_file(report_header, protected_file, True)
self.add_report_rows_to_file(report_type, report_rows, protected_file, True) self.add_report_rows_to_file(report_type, report_rows, self.begin_date, self.end_date, protected_file, True)
protected_file.close() protected_file.close()
self.process_result.protected_file_path = protected_file_path self.process_result.protected_file_path = protected_file_path
def add_report_header_to_file(self, report_header: ReportHeaderModel, file, include_attributes: bool): @staticmethod
def add_report_header_to_file(report_header: ReportHeaderModel, file, include_attributes: bool):
"""Adds the report header to a TSV file """Adds the report header to a TSV file
:param report_header: The report header model :param report_header: The report header model
@ -2580,21 +2543,28 @@ class ReportWorker(QObject):
tsv_writer.writerow(["Created_By", report_header.created_by]) tsv_writer.writerow(["Created_By", report_header.created_by])
tsv_writer.writerow([]) tsv_writer.writerow([])
def add_report_rows_to_file(self, report_type: str, report_rows: list, file, include_all_attributes: bool) -> bool: @staticmethod
def add_report_rows_to_file(report_type: str, report_rows: list, begin_date: QDate, end_date: QDate, file,
include_all_attributes: bool, is_special: bool = False,
special_options: SpecialReportOptions = None) -> bool:
"""Adds the report's rows to a TSV file """Adds the report's rows to a TSV file
:param report_type: The report type :param report_type: The report type
:param report_rows: The report's rows :param report_rows: The report's rows
:param begin_date: The first date in the report
:param end_date: The last date in the report
:param file: The TSV file to write to :param file: The TSV file to write to
:param include_all_attributes: Option to include all possible attributes for this report type to the report :param include_all_attributes: Option to include all possible attributes for this report type to the report
:param is_special: If this is a special report
:param special_options: The special options if this is a special report
""" """
column_names = [] column_names = []
row_dicts = [] row_dicts = []
if report_type == "PR": if report_type == "PR":
column_names += ["Platform"] column_names += ["Platform"]
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: column_names.append("Data_Type") if special_options_dict["data_type"][0]: column_names.append("Data_Type")
if special_options_dict["access_method"][0]: column_names.append("Access_Method") if special_options_dict["access_method"][0]: column_names.append("Access_Method")
elif include_all_attributes: elif include_all_attributes:
@ -2604,8 +2574,8 @@ class ReportWorker(QObject):
row: ReportRow row: ReportRow
for row in report_rows: for row in report_rows:
row_dict = {"Platform": row.platform} row_dict = {"Platform": row.platform}
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type
if special_options_dict["access_method"][0]: row_dict["Access_Method"] = row.access_method if special_options_dict["access_method"][0]: row_dict["Access_Method"] = row.access_method
@ -2635,8 +2605,8 @@ class ReportWorker(QObject):
elif report_type == "DR": elif report_type == "DR":
column_names += ["Database", "Publisher", "Publisher_ID", "Platform", "Proprietary_ID"] column_names += ["Database", "Publisher", "Publisher_ID", "Platform", "Proprietary_ID"]
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: column_names.append("Data_Type") if special_options_dict["data_type"][0]: column_names.append("Data_Type")
if special_options_dict["access_method"][0]: column_names.append("Access_Method") if special_options_dict["access_method"][0]: column_names.append("Access_Method")
elif include_all_attributes: elif include_all_attributes:
@ -2651,8 +2621,8 @@ class ReportWorker(QObject):
"Platform": row.platform, "Platform": row.platform,
"Proprietary_ID": row.proprietary_id} "Proprietary_ID": row.proprietary_id}
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type
if special_options_dict["access_method"][0]: row_dict["Access_Method"] = row.access_method if special_options_dict["access_method"][0]: row_dict["Access_Method"] = row.access_method
@ -2687,8 +2657,8 @@ class ReportWorker(QObject):
elif report_type == "TR": elif report_type == "TR":
column_names += ["Title", "Publisher", "Publisher_ID", "Platform", "DOI", "Proprietary_ID", "ISBN", column_names += ["Title", "Publisher", "Publisher_ID", "Platform", "DOI", "Proprietary_ID", "ISBN",
"Print_ISSN", "Online_ISSN", "URI"] "Print_ISSN", "Online_ISSN", "URI"]
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: column_names.append("Data_Type") if special_options_dict["data_type"][0]: column_names.append("Data_Type")
if special_options_dict["section_type"][0]: column_names.append("Section_Type") if special_options_dict["section_type"][0]: column_names.append("Section_Type")
if special_options_dict["yop"][0]: column_names.append("YOP") if special_options_dict["yop"][0]: column_names.append("YOP")
@ -2714,8 +2684,8 @@ class ReportWorker(QObject):
"Online_ISSN": row.online_issn, "Online_ISSN": row.online_issn,
"URI": row.uri} "URI": row.uri}
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type
if special_options_dict["section_type"][0]: row_dict["Section_Type"] = row.section_type if special_options_dict["section_type"][0]: row_dict["Section_Type"] = row.section_type
if special_options_dict["yop"][0]: row_dict["YOP"] = row.yop if special_options_dict["yop"][0]: row_dict["YOP"] = row.yop
@ -2851,8 +2821,8 @@ class ReportWorker(QObject):
elif report_type == "IR": elif report_type == "IR":
column_names += ["Item", "Publisher", "Publisher_ID", "Platform"] column_names += ["Item", "Publisher", "Publisher_ID", "Platform"]
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["authors"][0]: column_names.append("Authors") if special_options_dict["authors"][0]: column_names.append("Authors")
if special_options_dict["publication_date"][0]: column_names.append("Publication_Date") if special_options_dict["publication_date"][0]: column_names.append("Publication_Date")
if special_options_dict["article_version"][0]: column_names.append("Article_version") if special_options_dict["article_version"][0]: column_names.append("Article_version")
@ -2861,8 +2831,8 @@ class ReportWorker(QObject):
column_names.append("Publication_Date") column_names.append("Publication_Date")
column_names.append("Article_version") column_names.append("Article_version")
column_names += ["DOI", "Proprietary_ID", "ISBN", "Print_ISSN", "Online_ISSN", "URI"] column_names += ["DOI", "Proprietary_ID", "ISBN", "Print_ISSN", "Online_ISSN", "URI"]
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["include_parent_details"][0]: if special_options_dict["include_parent_details"][0]:
column_names += ["Parent_Title", "Parent_Authors", "Parent_Publication_Date", column_names += ["Parent_Title", "Parent_Authors", "Parent_Publication_Date",
"Parent_Article_Version", "Parent_Data_Type", "Parent_DOI", "Parent_Article_Version", "Parent_Data_Type", "Parent_DOI",
@ -2901,8 +2871,8 @@ class ReportWorker(QObject):
"Online_ISSN": row.online_issn, "Online_ISSN": row.online_issn,
"URI": row.uri} "URI": row.uri}
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if special_options_dict["authors"][0]: row_dict["Authors"] = row.authors if special_options_dict["authors"][0]: row_dict["Authors"] = row.authors
if special_options_dict["publication_date"][0]: row_dict["Publication_Date"] = row.publication_date if special_options_dict["publication_date"][0]: row_dict["Publication_Date"] = row.publication_date
if special_options_dict["article_version"][0]: row_dict["Article_version"] = row.article_version if special_options_dict["article_version"][0]: row_dict["Article_version"] = row.article_version
@ -3028,12 +2998,12 @@ class ReportWorker(QObject):
column_names += ["Metric_Type", "Reporting_Period_Total"] column_names += ["Metric_Type", "Reporting_Period_Total"]
if self.is_special: if is_special:
special_options_dict = self.special_options.__dict__ special_options_dict = special_options.__dict__
if not special_options_dict["exclude_monthly_details"][0]: if not special_options_dict["exclude_monthly_details"][0]:
column_names += get_month_years(self.begin_date, self.end_date) column_names += get_month_years(begin_date, end_date)
else: else:
column_names += get_month_years(self.begin_date, self.end_date) column_names += get_month_years(begin_date, end_date)
tsv_dict_writer = csv.DictWriter(file, column_names, delimiter='\t') tsv_dict_writer = csv.DictWriter(file, column_names, delimiter='\t')
tsv_dict_writer.writeheader() tsv_dict_writer.writeheader()

35
GeneralUtils.py

@ -7,6 +7,7 @@ from typing import Sequence, Any
from os import path, makedirs, system from os import path, makedirs, system
from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog
from PyQt5.QtCore import QDate from PyQt5.QtCore import QDate
from Constants import *
main_window: QWidget = None main_window: QWidget = None
@ -66,7 +67,7 @@ def open_file_or_dir(target_path: str):
def choose_file(name_filters) -> str: def choose_file(name_filters) -> str:
file_path = "" file_path = ""
dialog = QFileDialog(main_window, directory=".") dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.ExistingFile) dialog.setFileMode(QFileDialog.ExistingFile)
dialog.setNameFilters(name_filters) dialog.setNameFilters(name_filters)
if dialog.exec_(): if dialog.exec_():
@ -75,9 +76,20 @@ def choose_file(name_filters) -> str:
return file_path return file_path
def choose_files(name_filters) -> list:
file_paths = []
dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.ExistingFiles)
dialog.setNameFilters([x for x in name_filters])
if dialog.exec_():
file_paths = dialog.selectedFiles()
return file_paths
def choose_directory() -> str: def choose_directory() -> str:
dir_path = "" dir_path = ""
dialog = QFileDialog(main_window, directory=".") dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.Directory) dialog.setFileMode(QFileDialog.Directory)
if dialog.exec_(): if dialog.exec_():
dir_path = dialog.selectedFiles()[0] + "/" dir_path = dialog.selectedFiles()[0] + "/"
@ -87,7 +99,7 @@ def choose_directory() -> str:
def choose_save(name_filters) -> str: def choose_save(name_filters) -> str:
file_path = "" file_path = ""
dialog = QFileDialog(main_window, directory=".") dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.AnyFile) dialog.setFileMode(QFileDialog.AnyFile)
dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setAcceptMode(QFileDialog.AcceptSave)
dialog.setNameFilters(name_filters) dialog.setNameFilters(name_filters)
@ -125,6 +137,23 @@ def get_other_file_name(vendor_name: str, report_type: str, begin_date: QDate, e
return f"{vendor_name}_{report_type}_{begin_date.toString('yyyy-MMM')}_{end_date.toString('yyyy-MMM')}.tsv" return f"{vendor_name}_{report_type}_{begin_date.toString('yyyy-MMM')}_{end_date.toString('yyyy-MMM')}.tsv"
def get_major_report_type(report_type: str) -> MajorReportType:
"""Returns a major report type that a report type falls under"""
if report_type == "PR" or report_type == "PR_P1":
return MajorReportType.PLATFORM
elif report_type == "DR" or report_type == "DR_D1" or report_type == "DR_D2":
return MajorReportType.DATABASE
elif report_type == "TR" or report_type == "TR_B1" or report_type == "TR_B2" \
or report_type == "TR_B3" or report_type == "TR_J1" or report_type == "TR_J2" \
or report_type == "TR_J3" or report_type == "TR_J4":
return MajorReportType.TITLE
elif report_type == "IR" or report_type == "IR_A1" or report_type == "IR_M1":
return MajorReportType.ITEM
def save_data_as_tsv(file_name: str, data: Sequence[Any]): def save_data_as_tsv(file_name: str, data: Sequence[Any]):
"""Saves data in a TSV file """Saves data in a TSV file

234
ImportFile.py

@ -4,17 +4,19 @@ import shutil
import platform import platform
import ctypes import ctypes
import csv import csv
from tempfile import TemporaryDirectory
from os import path, makedirs from os import path, makedirs
from PyQt5.QtCore import QModelIndex, QDate, Qt from PyQt5.QtCore import QDate, Qt
from PyQt5.QtWidgets import QWidget, QDialog, QDialogButtonBox from PyQt5.QtWidgets import QWidget, QDialog, QDialogButtonBox, QLabel
from PyQt5.QtGui import QStandardItemModel, QStandardItem from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
import GeneralUtils import GeneralUtils
from Constants import * from Constants import *
from Counter4 import Counter4To5Converter
from ui import ImportReportTab, ReportResultWidget from ui import ImportReportTab, ReportResultWidget
from ManageVendors import Vendor from ManageVendors import Vendor
from FetchData import ALL_REPORTS, CompletionStatus from FetchData import CompletionStatus
from Settings import SettingsModel from Settings import SettingsModel
from ManageDB import UpdateDatabaseWorker from ManageDB import UpdateDatabaseWorker
@ -25,6 +27,7 @@ class ProcessResult:
:param vendor: The target vendor :param vendor: The target vendor
:param report_type: The target report type :param report_type: The target report type
""" """
def __init__(self, vendor: Vendor, report_type: str): def __init__(self, vendor: Vendor, report_type: str):
self.vendor = vendor self.vendor = vendor
self.report_type = report_type self.report_type = report_type
@ -35,6 +38,10 @@ class ProcessResult:
self.file_path = "" self.file_path = ""
def get_c5_equivalent(counter4_report_type: str) -> str:
return COUNTER_4_REPORT_EQUIVALENTS[counter4_report_type]
class ImportReportController: class ImportReportController:
"""Controls the Import Report tab """Controls the Import Report tab
@ -43,6 +50,7 @@ class ImportReportController:
:param import_report_widget: The import report widget. :param import_report_widget: The import report widget.
:param import_report_ui: The UI for the import_report_widget. :param import_report_ui: The UI for the import_report_widget.
""" """
def __init__(self, vendors: list, settings: SettingsModel, import_report_widget: QWidget, def __init__(self, vendors: list, settings: SettingsModel, import_report_widget: QWidget,
import_report_ui: ImportReportTab.Ui_import_report_tab): import_report_ui: ImportReportTab.Ui_import_report_tab):
@ -51,43 +59,75 @@ class ImportReportController:
self.vendors = vendors self.vendors = vendors
self.date = QDate.currentDate() self.date = QDate.currentDate()
self.selected_vendor_index = -1 self.selected_vendor_index = -1
self.selected_report_type_index = -1 self.selected_c5_report_type_index = -1
self.selected_file_path: str = "" self.selected_c4_report_type_index = -1
self.c5_selected_file_path: str = ""
self.c4_selected_file_paths: list = []
self.settings = settings self.settings = settings
self.result_dialog = None self.result_dialog = None
# endregion # endregion
# region Vendors # region Vendors
self.vendor_list_view = import_report_ui.vendors_list_view_import self.vendor_combo_box = import_report_ui.vendor_combo_box
self.vendor_list_model = QStandardItemModel(self.vendor_list_view) self.vendor_list_model = QStandardItemModel(self.vendor_combo_box)
self.vendor_list_view.setModel(self.vendor_list_model) self.vendor_combo_box.setModel(self.vendor_list_model)
self.vendor_list_view.clicked.connect(self.on_vendor_selected) self.vendor_combo_box.currentIndexChanged.connect(self.on_vendor_selected)
self.update_vendors_ui() self.update_vendors_ui()
self.selected_vendor_index = self.vendor_combo_box.currentIndex()
# endregion # endregion
# region Report Types # region Counter 5
self.report_type_list_view = import_report_ui.report_types_list_view_import self.c5_report_type_combo_box = import_report_ui.c5_report_type_combo_box
self.report_type_list_model = QStandardItemModel(self.report_type_list_view) self.c5_report_type_model = QStandardItemModel(self.c5_report_type_combo_box)
self.report_type_list_view.setModel(self.report_type_list_model) self.c5_report_type_combo_box.setModel(self.c5_report_type_model)
self.report_type_list_view.clicked.connect(self.on_report_type_selected) self.c5_report_type_combo_box.currentIndexChanged.connect(self.on_c5_report_type_selected)
for report_type in ALL_REPORTS: for report_type in ALL_REPORTS:
item = QStandardItem(report_type) item = QStandardItem(report_type)
item.setEditable(False) item.setEditable(False)
self.report_type_list_model.appendRow(item) self.c5_report_type_model.appendRow(item)
self.selected_c5_report_type_index = self.c5_report_type_combo_box.currentIndex()
self.c5_select_file_btn = import_report_ui.c5_select_file_button
self.c5_select_file_btn.clicked.connect(self.on_c5_select_file_clicked)
self.c5_selected_file_edit = import_report_ui.c5_selected_file_edit
self.c5_import_report_button = import_report_ui.c5_import_report_button
self.c5_import_report_button.clicked.connect(self.on_c5_import_clicked)
# endregion # endregion
# region Others # region Counter 4
self.year_date_edit = import_report_ui.report_year_date_edit self.c4_report_type_combo_box = import_report_ui.c4_report_type_combo_box
self.year_date_edit.setDate(self.date) self.c4_report_type_model = QStandardItemModel(self.c4_report_type_combo_box)
self.year_date_edit.dateChanged.connect(self.on_date_changed) self.c4_report_type_combo_box.setModel(self.c4_report_type_model)
self.c4_report_type_combo_box.currentIndexChanged.connect(self.on_c4_report_type_selected)
self.c4_report_type_equiv_label = import_report_ui.c4_report_type_equiv_label
for report_type in COUNTER_4_REPORT_EQUIVALENTS.keys():
item = QStandardItem(report_type)
item.setEditable(False)
self.c4_report_type_model.appendRow(item)
self.select_file_btn = import_report_ui.select_file_button self.selected_c4_report_type_index = self.c4_report_type_combo_box.currentIndex()
self.select_file_btn.clicked.connect(self.on_select_file_clicked) self.c4_report_type_equiv_label.setText(get_c5_equivalent(self.c4_report_type_combo_box.currentText()))
self.selected_file_edit = import_report_ui.selected_file_edit self.c4_select_file_btn = import_report_ui.c4_select_file_button
self.c4_select_file_btn.clicked.connect(self.on_c4_select_file_clicked)
self.import_report_button = import_report_ui.import_report_button self.c4_selected_files_frame = import_report_ui.c4_selected_files_frame
self.import_report_button.clicked.connect(self.on_import_clicked) self.c4_selected_files_frame_layout = self.c4_selected_files_frame.layout()
self.c4_import_report_button = import_report_ui.c4_import_report_button
self.c4_import_report_button.clicked.connect(self.on_c4_import_clicked)
# endregion
# region Date
self.year_date_edit = import_report_ui.report_year_date_edit
self.year_date_edit.setDate(self.date)
self.year_date_edit.dateChanged.connect(self.on_date_changed)
# endregion # endregion
def on_vendors_changed(self, vendors: list): def on_vendors_changed(self, vendors: list):
@ -95,9 +135,9 @@ class ImportReportController:
:param vendors: An updated list of the system's vendors :param vendors: An updated list of the system's vendors
""" """
self.selected_vendor_index = -1
self.update_vendors(vendors) self.update_vendors(vendors)
self.update_vendors_ui() self.update_vendors_ui()
self.selected_vendor_index = self.vendor_combo_box.currentIndex()
def update_vendors(self, vendors: list): def update_vendors(self, vendors: list):
""" Updates the local copy of vendors that support report import """ Updates the local copy of vendors that support report import
@ -114,54 +154,135 @@ class ImportReportController:
item.setEditable(False) item.setEditable(False)
self.vendor_list_model.appendRow(item) self.vendor_list_model.appendRow(item)
def on_vendor_selected(self, model_index: QModelIndex): def on_vendor_selected(self, index: int):
"""Handles the signal emitted when a vendor is selected""" """Handles the signal emitted when a vendor is selected"""
self.selected_vendor_index = model_index.row() self.selected_vendor_index = index
def on_report_type_selected(self, model_index: QModelIndex): def on_c5_report_type_selected(self, index: int):
"""Handles the signal emitted when a report type is selected""" """Handles the signal emitted when a report type is selected"""
self.selected_report_type_index = model_index.row() self.selected_c5_report_type_index = index
def on_c4_report_type_selected(self, index: int):
"""Handles the signal emitted when a report type is selected"""
self.selected_c4_report_type_index = index
self.c4_report_type_equiv_label.setText(get_c5_equivalent(self.c4_report_type_combo_box.currentText()))
def on_date_changed(self, date: QDate): def on_date_changed(self, date: QDate):
"""Handles the signal emitted when the target date is changed""" """Handles the signal emitted when the target date is changed"""
self.date = date self.date = date
def on_select_file_clicked(self): def on_c5_select_file_clicked(self):
"""Handles the signal emitted when the select file button is clicked""" """Handles the signal emitted when the select file button is clicked"""
file_path = GeneralUtils.choose_file(TSV_FILTER + CSV_FILTER) file_path = GeneralUtils.choose_file(TSV_FILTER + CSV_FILTER)
if file_path: if file_path:
self.selected_file_path = file_path self.c5_selected_file_path = file_path
self.selected_file_edit.setText(file_path) file_name = file_path.split("/")[-1]
self.c5_selected_file_edit.setText(file_name)
def on_import_clicked(self): def on_c4_select_file_clicked(self):
"""Handles the signal emitted when the select file button is clicked"""
file_paths = GeneralUtils.choose_files(TSV_AND_CSV_FILTER)
if file_paths:
self.c4_selected_file_paths = file_paths
file_names = [file_path.split("/")[-1] for file_path in file_paths]
# Remove existing options from ui
for i in reversed(range(self.c4_selected_files_frame_layout.count())):
widget = self.c4_selected_files_frame_layout.itemAt(i).widget()
# remove it from the layout list
self.c4_selected_files_frame_layout.removeWidget(widget)
# remove it from the gui
widget.deleteLater()
# Add new file names
for file_name in file_names:
label = QLabel(file_name)
self.c4_selected_files_frame_layout.addWidget(label)
def on_c5_import_clicked(self):
"""Handles the signal emitted when the import button is clicked""" """Handles the signal emitted when the import button is clicked"""
if self.selected_vendor_index == -1: if self.selected_vendor_index == -1:
GeneralUtils.show_message("Select a vendor") GeneralUtils.show_message("Select a vendor")
return return
elif self.selected_report_type_index == -1: elif self.selected_c5_report_type_index == -1:
GeneralUtils.show_message("Select a report type") GeneralUtils.show_message("Select a report type")
return return
elif self.selected_file_path == "": elif self.c5_selected_file_path == "":
GeneralUtils.show_message("Select a file")
return
vendor = self.vendors[self.selected_vendor_index]
report_type = ALL_REPORTS[self.selected_c5_report_type_index]
process_result = self.import_report(vendor, report_type, self.c5_selected_file_path)
self.show_results([process_result])
def on_c4_import_clicked(self):
"""Handles the signal emitted when the import button is clicked"""
if self.selected_vendor_index == -1:
GeneralUtils.show_message("Select a vendor")
return
elif not self.c4_selected_file_paths:
GeneralUtils.show_message("Select a file") GeneralUtils.show_message("Select a file")
return return
vendor = self.vendors[self.selected_vendor_index] vendor = self.vendors[self.selected_vendor_index]
report_type = ALL_REPORTS[self.selected_report_type_index] report_types = get_c5_equivalent(self.c4_report_type_combo_box.currentText())
# Check if target C5 file already exists
existing_report_types = []
for report_type in report_types.split(", "):
if self.check_if_c5_report_exists(vendor.name, report_type):
existing_report_types.append(report_type)
# Confirm overwrite
if existing_report_types:
if not GeneralUtils.ask_confirmation(f"COUNTER 5 [{', '.join(existing_report_types)}] already exist in the "
"database for this vendor, do you want to overwrite them?"):
return
with TemporaryDirectory("") as dir_path:
converter = Counter4To5Converter(self.vendors[self.selected_vendor_index],
self.c4_report_type_combo_box.currentText(),
self.c4_selected_file_paths,
dir_path + path.sep,
self.year_date_edit.date())
try:
c5_file_paths = converter.do_conversion()
except Exception as e:
process_result = ProcessResult(vendor, report_types)
process_result.completion_status = CompletionStatus.FAILED
process_result.message = "Error converting file. " + str(e)
self.show_results([process_result])
return
if not c5_file_paths: # If nothing was processed
process_result = ProcessResult(vendor, report_types)
process_result.completion_status = CompletionStatus.FAILED
process_result.message = "No COUNTER 5 report was created, make sure the COUNTER 4 input files are " \
"correct"
self.show_results([process_result])
return
process_result = self.import_report(vendor, report_type) process_results = []
self.show_result(process_result) for report_type in c5_file_paths:
file_path = c5_file_paths[report_type]
process_result = self.import_report(vendor, report_type, file_path)
process_results.append(process_result)
def import_report(self, vendor: Vendor, report_type: str) -> ProcessResult: self.show_results(process_results)
def import_report(self, vendor: Vendor, report_type: str, origin_file_path: str) -> ProcessResult:
""" Imports the selected file using the selected parameters """ Imports the selected file using the selected parameters
:param vendor: The target vendor :param vendor: The target vendor
:param report_type: The target report type :param report_type: The target report type
:param origin_file_path: The path of the file to be imported
:raises Exception: If anything goes wrong while importing the report :raises Exception: If anything goes wrong while importing the report
""" """
process_result = ProcessResult(vendor, report_type) process_result = ProcessResult(vendor, report_type)
try: try:
dest_file_dir = GeneralUtils.get_yearly_file_dir(self.settings.yearly_directory, vendor.name, self.date) dest_file_dir = GeneralUtils.get_yearly_file_dir(self.settings.yearly_directory, vendor.name, self.date)
dest_file_name = GeneralUtils.get_yearly_file_name(vendor.name, report_type, self.date) dest_file_name = GeneralUtils.get_yearly_file_name(vendor.name, report_type, self.date)
dest_file_path = f"{dest_file_dir}{dest_file_name}" dest_file_path = f"{dest_file_dir}{dest_file_name}"
@ -171,8 +292,8 @@ class ImportReportController:
makedirs(dest_file_dir) makedirs(dest_file_dir)
# Validate report header # Validate report header
delimiter = DELIMITERS[self.selected_file_path[-4:].lower()] delimiter = DELIMITERS[origin_file_path[-4:].lower()]
file = open(self.selected_file_path, 'r', encoding='utf-8-sig') file = open(origin_file_path, 'r', encoding='utf-8-sig')
reader = csv.reader(file, delimiter=delimiter, quotechar='\"') reader = csv.reader(file, delimiter=delimiter, quotechar='\"')
if file.mode == 'r': if file.mode == 'r':
header = {} header = {}
@ -199,7 +320,7 @@ class ImportReportController:
raise Exception('Could not open file') raise Exception('Could not open file')
# Copy selected_file_path to dest_file_path # Copy selected_file_path to dest_file_path
self.copy_file(self.selected_file_path, dest_file_path) self.copy_file(origin_file_path, dest_file_path)
process_result.file_dir = dest_file_dir process_result.file_dir = dest_file_dir
process_result.file_name = dest_file_name process_result.file_name = dest_file_name
@ -214,7 +335,7 @@ class ImportReportController:
ctypes.windll.kernel32.SetFileAttributesW(PROTECTED_DATABASE_FILE_DIR, 2) # Hide folder ctypes.windll.kernel32.SetFileAttributesW(PROTECTED_DATABASE_FILE_DIR, 2) # Hide folder
protected_file_path = f"{protected_file_dir}{dest_file_name}" protected_file_path = f"{protected_file_dir}{dest_file_name}"
self.copy_file(self.selected_file_path, protected_file_path) self.copy_file(origin_file_path, protected_file_path)
# Add file to database # Add file to database
database_worker = UpdateDatabaseWorker([{'file': protected_file_path, database_worker = UpdateDatabaseWorker([{'file': protected_file_path,
@ -229,28 +350,32 @@ class ImportReportController:
return process_result return process_result
def check_if_c5_report_exists(self, vendor_name, report_type) -> bool:
protected_file_dir = f"{PROTECTED_DATABASE_FILE_DIR}{self.date.toString('yyyy')}/{vendor_name}/"
protected_file_name = GeneralUtils.get_yearly_file_name(vendor_name, report_type, self.date)
protected_file_path = f"{protected_file_dir}{protected_file_name}"
return path.isfile(protected_file_path)
def copy_file(self, origin_path: str, dest_path: str): def copy_file(self, origin_path: str, dest_path: str):
"""Copies a file from origin_path to dest_path""" """Copies a file from origin_path to dest_path"""
shutil.copy2(origin_path, dest_path) shutil.copy2(origin_path, dest_path)
def show_result(self, process_result: ProcessResult): def show_results(self, process_results: list):
"""Shows the result of the import process to the user """Shows the result of the import process to the user
:param process_result: The result of the import process :param process_results: The results of the import process
""" """
self.result_dialog = QDialog(self.import_report_widget, flags=Qt.WindowCloseButtonHint) self.result_dialog = QDialog(self.import_report_widget, flags=Qt.WindowCloseButtonHint)
self.result_dialog.setWindowTitle("Import Result") self.result_dialog.setWindowTitle("Import Result")
vertical_layout = QtWidgets.QVBoxLayout(self.result_dialog) vertical_layout = QtWidgets.QVBoxLayout(self.result_dialog)
vertical_layout.setContentsMargins(5, 5, 5, 5) vertical_layout.setContentsMargins(5, 5, 5, 5)
for process_result in process_results:
report_result_widget = QWidget(self.result_dialog) report_result_widget = QWidget(self.result_dialog)
report_result_ui = ReportResultWidget.Ui_ReportResultWidget() report_result_ui = ReportResultWidget.Ui_ReportResultWidget()
report_result_ui.setupUi(report_result_widget) report_result_ui.setupUi(report_result_widget)
button_box = QtWidgets.QDialogButtonBox(QDialogButtonBox.Ok, self.result_dialog)
button_box.setCenterButtons(True)
button_box.accepted.connect(self.result_dialog.accept)
vendor = process_result.vendor vendor = process_result.vendor
report_type = process_result.report_type report_type = process_result.report_type
@ -263,7 +388,7 @@ class ImportReportController:
report_result_ui.file_label.setText(f"Saved as: {process_result.file_name}") report_result_ui.file_label.setText(f"Saved as: {process_result.file_name}")
report_result_ui.file_label.mousePressEvent = \ report_result_ui.file_label.mousePressEvent = \
lambda event: GeneralUtils.open_file_or_dir(process_result.file_path) lambda event, file_path = process_result.file_path: GeneralUtils.open_file_or_dir(file_path)
report_result_ui.folder_button.clicked.connect( report_result_ui.folder_button.clicked.connect(
lambda: GeneralUtils.open_file_or_dir(process_result.file_dir)) lambda: GeneralUtils.open_file_or_dir(process_result.file_dir))
@ -278,7 +403,10 @@ class ImportReportController:
report_result_ui.message_label.setText(process_result.message) report_result_ui.message_label.setText(process_result.message)
vertical_layout.addWidget(report_result_widget) vertical_layout.addWidget(report_result_widget)
vertical_layout.addWidget(button_box)
self.result_dialog.show()
button_box = QtWidgets.QDialogButtonBox(QDialogButtonBox.Ok, self.result_dialog)
button_box.setCenterButtons(True)
button_box.accepted.connect(self.result_dialog.accept)
vertical_layout.addWidget(button_box)
self.result_dialog.show()

16
ManageDB.py

@ -398,7 +398,7 @@ def read_report_file(file_name: str, vendor: str, year: int) -> Union[Tuple[str,
:param vendor: the vendor name of the data in the file :param vendor: the vendor name of the data in the file
:param year: the year of the data in the file :param year: the year of the data in the file
:returns: (file_name, report, values) a Tuple with the file name, the kind of report, and the data from the file""" :returns: (file_name, report, values) a Tuple with the file name, the kind of report, and the data from the file"""
if ManageDBSettingsHandler.settings.show_debug_messages: print('READ ' + file_name) # if ManageDBSettingsHandler.settings.show_debug_messages: print('READ ' + file_name)
delimiter = DELIMITERS[file_name[-4:].lower()] delimiter = DELIMITERS[file_name[-4:].lower()]
file = open(file_name, 'r', encoding='utf-8-sig') file = open(file_name, 'r', encoding='utf-8-sig')
reader = csv.reader(file, delimiter=delimiter, quotechar='\"') reader = csv.reader(file, delimiter=delimiter, quotechar='\"')
@ -411,13 +411,13 @@ def read_report_file(file_name: str, vendor: str, year: int) -> Union[Tuple[str,
header[key] = cells[1].strip() header[key] = cells[1].strip()
else: else:
header[key] = None header[key] = None
if ManageDBSettingsHandler.settings.show_debug_messages: print(header) # if ManageDBSettingsHandler.settings.show_debug_messages: print(header)
for row in range(BLANK_ROWS): for row in range(BLANK_ROWS):
next(reader) next(reader)
column_headers = next(reader) column_headers = next(reader)
column_headers = list(map((lambda column_header: column_header.lower()), column_headers = list(map((lambda column_header: column_header.lower()),
column_headers)) # reads column headers column_headers)) # reads column headers
if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers) # if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers)
values = [] values = []
for cells in list(reader): for cells in list(reader):
for month in MONTHS: # makes value from each month with metric > 0 for each row for month in MONTHS: # makes value from each month with metric > 0 for each row
@ -458,7 +458,7 @@ def read_costs_file(file_name: str) -> Union[Sequence[Dict[str, Any]], None]:
column_headers = next(reader) column_headers = next(reader)
column_headers = list(map((lambda column_header: column_header.lower()), column_headers = list(map((lambda column_header: column_header.lower()),
column_headers)) # reads column headers column_headers)) # reads column headers
if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers) # if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers)
values = [] values = []
for cells in list(reader): for cells in list(reader):
value = {} value = {}
@ -843,9 +843,9 @@ def run_sql(connection: sqlite3.Connection, sql_text: str, data: Sequence[Sequen
:param emit_signal: whether to emit a signal upon completion""" :param emit_signal: whether to emit a signal upon completion"""
try: try:
cursor = connection.cursor() cursor = connection.cursor()
if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text) # if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text)
if data is not None: if data is not None:
if ManageDBSettingsHandler.settings.show_debug_messages: print(data) # if ManageDBSettingsHandler.settings.show_debug_messages: print(data)
cursor.executemany(sql_text, data) cursor.executemany(sql_text, data)
else: else:
cursor.execute(sql_text) cursor.execute(sql_text)
@ -866,9 +866,9 @@ def run_select_sql(connection: sqlite3.Connection, sql_text: str, data: Sequence
:returns: a list of rows that return from the statement""" :returns: a list of rows that return from the statement"""
try: try:
cursor = connection.cursor() cursor = connection.cursor()
if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text) # if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text)
if data is not None: if data is not None:
if ManageDBSettingsHandler.settings.show_debug_messages: print(data) # if ManageDBSettingsHandler.settings.show_debug_messages: print(data)
cursor.execute(sql_text, data) cursor.execute(sql_text, data)
else: else:
cursor.execute(sql_text) cursor.execute(sql_text)

2
README.md

@ -78,3 +78,5 @@ type pip -v into command prompt, this should return the version of PIP that is i
- Choose Existing environment and set the location to anaconda_install_location/python.exe, OK, OK - Choose Existing environment and set the location to anaconda_install_location/python.exe, OK, OK
- Allow the IDE to complete set up then launch the program from MainDriver.py. There should be a play icon next to the line "if __name__ == "__main__":" - Allow the IDE to complete set up then launch the program from MainDriver.py. There should be a play icon next to the line "if __name__ == "__main__":"
- We Good To Go! - We Good To Go!

2
Search.py

@ -246,7 +246,7 @@ class SearchController:
results = ManageDB.run_select_sql(connection, sql_text, data) results = ManageDB.run_select_sql(connection, sql_text, data)
connection.close() connection.close()
results.insert(0, headers) results.insert(0, headers)
if self.settings.show_debug_messages: print(results) # if self.settings.show_debug_messages: print(results)
save_data_as_tsv(file_name, results) save_data_as_tsv(file_name, results)
if self.open_results_folder_checkbox.isChecked(): if self.open_results_folder_checkbox.isChecked():
open_file_or_dir(os.path.dirname(file_name)) open_file_or_dir(os.path.dirname(file_name))

48
Visual.py

@ -201,7 +201,7 @@ class VisualController:
self.names = [result[0] for result in names_results] self.names = [result[0] for result in names_results]
else: else:
self.names = [] self.names = []
if self.settings.show_debug_messages: print(names_results) # if self.settings.show_debug_messages: print(names_results)
costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter.currentText(), costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter.currentText(),
self.vendor_parameter, self.vendor_parameter,
@ -212,7 +212,7 @@ class VisualController:
self.costs_names = [result[0] for result in costs_results] self.costs_names = [result[0] for result in costs_results]
else: else:
self.costs_names = [] self.costs_names = []
if self.settings.show_debug_messages: print(costs_results) # if self.settings.show_debug_messages: print(costs_results)
connection.close() connection.close()
model = QStandardItemModel() model = QStandardItemModel()
@ -267,15 +267,15 @@ class VisualController:
if self.monthly_radio.isChecked() and message == "": if self.monthly_radio.isChecked() and message == "":
# sql query to get search results # sql query to get search results
sql_text, data = ManageDB.monthly_chart_search_sql_text(report, start_year, end_year, name, metric, vendor) sql_text, data = ManageDB.monthly_chart_search_sql_text(report, start_year, end_year, name, metric, vendor)
print(sql_text) # testing # print(sql_text) # testing
headers = tuple([field['name'] for field in ManageDB.get_monthly_chart_report_fields_list(report)]) headers = tuple([field['name'] for field in ManageDB.get_monthly_chart_report_fields_list(report)])
connection = ManageDB.create_connection(DATABASE_LOCATION) connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None: if connection is not None:
self.results = ManageDB.run_select_sql(connection, sql_text, data) self.results = ManageDB.run_select_sql(connection, sql_text, data)
print(self.results) # print(self.results)
self.results.insert(0, headers) self.results.insert(0, headers)
print(self.results) # print(self.results)
connection.close() connection.close()
else: else:
print('Error, no connection') print('Error, no connection')
@ -289,15 +289,15 @@ class VisualController:
if self.yearly_radio.isChecked() and message == "": if self.yearly_radio.isChecked() and message == "":
# sql query to get search results # sql query to get search results
sql_text, data = ManageDB.yearly_chart_search_sql_text(report, start_year, end_year, name, metric, vendor) sql_text, data = ManageDB.yearly_chart_search_sql_text(report, start_year, end_year, name, metric, vendor)
print(sql_text) # testing # print(sql_text) # testing
headers = tuple([field['name'] for field in ManageDB.get_yearly_chart_report_fields_list(report)]) headers = tuple([field['name'] for field in ManageDB.get_yearly_chart_report_fields_list(report)])
connection = ManageDB.create_connection(DATABASE_LOCATION) connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None: if connection is not None:
self.results = ManageDB.run_select_sql(connection, sql_text, data) self.results = ManageDB.run_select_sql(connection, sql_text, data)
print(self.results) # print(self.results)
self.results.insert(0, headers) self.results.insert(0, headers)
print(self.results) # print(self.results)
connection.close() connection.close()
else: else:
print('Error, no connection') print('Error, no connection')
@ -311,15 +311,15 @@ class VisualController:
if self.costRatio_radio.isChecked() and message == "": if self.costRatio_radio.isChecked() and message == "":
# sql query to get search results # sql query to get search results
sql_text, data = ManageDB.cost_chart_search_sql_text(report, start_year, end_year, name, metric, vendor) sql_text, data = ManageDB.cost_chart_search_sql_text(report, start_year, end_year, name, metric, vendor)
print(sql_text) # testing # print(sql_text) # testing
headers = tuple([field['name'] for field in ManageDB.get_cost_chart_report_fields_list(report)]) headers = tuple([field['name'] for field in ManageDB.get_cost_chart_report_fields_list(report)])
connection = ManageDB.create_connection(DATABASE_LOCATION) connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None: if connection is not None:
self.results = ManageDB.run_select_sql(connection, sql_text, data) self.results = ManageDB.run_select_sql(connection, sql_text, data)
print(self.results) # print(self.results)
self.results.insert(0, headers) self.results.insert(0, headers)
print(self.results) # print(self.results)
connection.close() connection.close()
else: else:
print('Error, no connection') print('Error, no connection')
@ -381,9 +381,9 @@ class VisualController:
data1.append(self.results[i][j]) data1.append(self.results[i][j])
self.data.append(data1) self.data.append(data1)
# testing to make sure its working good # testing to make sure its working good
print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart # print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart
print(self.data[1]) # print(self.data[1])
print(len(self.data)) # print(len(self.data))
self.chart_type() self.chart_type()
def process_yearly_data(self): def process_yearly_data(self):
@ -404,9 +404,9 @@ class VisualController:
self.data.append(data2) self.data.append(data2)
# testing to make sure its working good # testing to make sure its working good
print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart # print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart
print(self.data[1]) # print(self.data[1])
print(len(self.data)) # print(len(self.data))
self.chart_type() self.chart_type()
def process_cost_ratio_data(self): def process_cost_ratio_data(self):
@ -471,8 +471,8 @@ class VisualController:
self.legendEntry.append(self.metric.currentText()) self.legendEntry.append(self.metric.currentText())
# testing to see data in array of array # testing to see data in array of array
print(self.data[0]) # first column in excel (year) # print(self.data[0]) # first column in excel (year)
print(self.data[1]) # second column (cost per metric) # print(self.data[1]) # second column (cost per metric)
# print(self.data[2]) # third column (cost) # print(self.data[2]) # third column (cost)
# print(self.data[4]) # fourth column (total) # print(self.data[4]) # fourth column (total)
# print(len(self.data)) #testing # print(len(self.data)) #testing
@ -482,7 +482,7 @@ class VisualController:
"""Invoked when calculation type: top # is selected""" """Invoked when calculation type: top # is selected"""
m = len(self.results) m = len(self.results)
# print(self.results) # print(self.results)
print(m) # print(m)
self.temp_results = [] self.temp_results = []
self.legendEntry = [] # legend entry data self.legendEntry = [] # legend entry data
@ -491,8 +491,8 @@ class VisualController:
for i in range(1, m): for i in range(1, m):
self.temp_results.append(self.results[i]) self.temp_results.append(self.results[i])
self.temp_results = sorted(self.temp_results, key=itemgetter(4)) self.temp_results = sorted(self.temp_results, key=itemgetter(4))
print(len(self.temp_results)) # print(len(self.temp_results))
print(self.temp_results) # print(self.temp_results)
n = len(self.temp_results) n = len(self.temp_results)
# data is an array with the sorted usage figures # data is an array with the sorted usage figures
@ -509,7 +509,7 @@ class VisualController:
data = self.temp_results[i][0] data = self.temp_results[i][0]
data1.append(data) data1.append(data)
self.data.append(data1) self.data.append(data1)
print(data1) # print(data1)
# get all reporting total # get all reporting total
metri = self.temp_results[0][3] metri = self.temp_results[0][3]
@ -518,7 +518,7 @@ class VisualController:
metri = self.temp_results[i][3] metri = self.temp_results[i][3]
data2.append(metri) data2.append(metri)
self.data.append(data2) self.data.append(data2)
print(data2) # print(data2)
# get all ranking # get all ranking
rank = self.temp_results[0][4] rank = self.temp_results[0][4]

BIN
executables/Linux/Counter 5 Report Tool.zip

Binary file not shown.

BIN
executables/Windows/COUNTER 5 Report Tool.zip

Binary file not shown.

BIN
executables/macOS/Counter 5 Report Tool.zip

Binary file not shown.

BIN
images/import-report-updated.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

30
tests/test_ImportFile.py

@ -105,9 +105,9 @@ def test_on_report_type_selected(controller_v):
index_to_select = 3 index_to_select = 3
model_index = QStandardItemModel.createIndex(QStandardItemModel(), index_to_select, 0) model_index = QStandardItemModel.createIndex(QStandardItemModel(), index_to_select, 0)
controller_v.on_report_type_selected(model_index) controller_v.on_c5_report_type_selected(model_index)
assert controller_v.selected_report_type_index == index_to_select assert controller_v.selected_c5_report_type_index == index_to_select
def test_on_date_changed(controller_v): def test_on_date_changed(controller_v):
@ -119,38 +119,38 @@ def test_on_date_changed(controller_v):
def test_on_import_clicked(controller_v): def test_on_import_clicked(controller_v):
# No vendor selected # No vendor selected
controller_v.on_import_clicked() controller_v.on_c5_import_clicked()
controller_v.selected_vendor_index = 1 controller_v.selected_vendor_index = 1
# No report type selected # No report type selected
controller_v.on_import_clicked() controller_v.on_c5_import_clicked()
controller_v.selected_report_type_index = 1 controller_v.selected_c5_report_type_index = 1
vendor = controller_v.vendors[controller_v.selected_vendor_index] vendor = controller_v.vendors[controller_v.selected_vendor_index]
report_type = ALL_REPORTS[controller_v.selected_report_type_index] report_type = ALL_REPORTS[controller_v.selected_c5_report_type_index]
file_dir = f"{controller_v.settings.yearly_directory}{controller_v.date.toString('yyyy')}/{vendor.name}/" file_dir = f"{controller_v.settings.yearly_directory}{controller_v.date.toString('yyyy')}/{vendor.name}/"
file_name = f"{controller_v.date.toString('yyyy')}_{vendor.name}_{report_type}.tsv" file_name = f"{controller_v.date.toString('yyyy')}_{vendor.name}_{report_type}.tsv"
file_path = file_dir + file_name file_path = file_dir + file_name
# No file selected # No file selected
controller_v.on_import_clicked() controller_v.on_c5_import_clicked()
# Invalid file selected # Invalid file selected
controller_v.selected_file_path = "./data/invalid_file" controller_v.c5_selected_file_path = "./data/invalid_file"
controller_v.on_import_clicked() controller_v.on_c5_import_clicked()
# Valid file selected # Valid file selected
controller_v.selected_file_path = "./data/test_file_for_import.tsv" controller_v.c5_selected_file_path = "./data/test_file_for_import.tsv"
controller_v.on_import_clicked() controller_v.on_c5_import_clicked()
assert path.isfile(file_path) assert path.isfile(file_path)
def test_import_file(controller_v): def test_import_file(controller_v):
controller_v.selected_vendor_index = 1 controller_v.selected_vendor_index = 1
controller_v.selected_report_type_index = 1 controller_v.selected_c5_report_type_index = 1
vendor = controller_v.vendors[controller_v.selected_vendor_index] vendor = controller_v.vendors[controller_v.selected_vendor_index]
report_type = ALL_REPORTS[controller_v.selected_report_type_index] report_type = ALL_REPORTS[controller_v.selected_c5_report_type_index]
file_dir = f"{controller_v.settings.yearly_directory}{controller_v.date.toString('yyyy')}/{vendor.name}/" file_dir = f"{controller_v.settings.yearly_directory}{controller_v.date.toString('yyyy')}/{vendor.name}/"
file_name = f"{controller_v.date.toString('yyyy')}_{vendor.name}_{report_type}.tsv" file_name = f"{controller_v.date.toString('yyyy')}_{vendor.name}_{report_type}.tsv"
file_path = file_dir + file_name file_path = file_dir + file_name
@ -159,11 +159,11 @@ def test_import_file(controller_v):
assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.FAILED assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.FAILED
# Invalid file selected # Invalid file selected
controller_v.selected_file_path = "./data/invalid_file" controller_v.c5_selected_file_path = "./data/invalid_file"
assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.FAILED assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.FAILED
# Valid file selected # Valid file selected
controller_v.selected_file_path = "./data/test_file_for_import.tsv" controller_v.c5_selected_file_path = "./data/test_file_for_import.tsv"
assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.SUCCESSFUL assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.SUCCESSFUL
assert path.isfile(file_path) assert path.isfile(file_path)

379
ui/ImportReportTab.py

@ -2,28 +2,25 @@
# Form implementation generated from reading ui file 'ImportReportTab.ui' # Form implementation generated from reading ui file 'ImportReportTab.ui'
# #
# Created by: PyQt5 UI code generator 5.9.2 # Created by: PyQt5 UI code generator 5.12.3
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_import_report_tab(object): class Ui_import_report_tab(object):
def setupUi(self, import_report_tab): def setupUi(self, import_report_tab):
import_report_tab.setObjectName("import_report_tab") import_report_tab.setObjectName("import_report_tab")
import_report_tab.resize(1008, 530) import_report_tab.resize(1007, 467)
icon = QtGui.QIcon() icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/ui/resources/tab_icons/import_report_icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) icon.addPixmap(QtGui.QPixmap(":/ui/resources/tab_icons/import_report_icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
import_report_tab.setWindowIcon(icon) import_report_tab.setWindowIcon(icon)
self.verticalLayout = QtWidgets.QVBoxLayout(import_report_tab) self.verticalLayout = QtWidgets.QVBoxLayout(import_report_tab)
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.frame = QtWidgets.QFrame(import_report_tab) self.frame_21 = QtWidgets.QFrame(import_report_tab)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
self.frame.setObjectName("frame")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.frame_21 = QtWidgets.QFrame(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_21.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.frame_21.sizePolicy().hasHeightForWidth())
@ -31,109 +28,70 @@ class Ui_import_report_tab(object):
self.frame_21.setMinimumSize(QtCore.QSize(200, 0)) self.frame_21.setMinimumSize(QtCore.QSize(200, 0))
self.frame_21.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_21.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_21.setObjectName("frame_21") self.frame_21.setObjectName("frame_21")
self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.frame_21) self.gridLayout = QtWidgets.QGridLayout(self.frame_21)
self.verticalLayout_12.setObjectName("verticalLayout_12") self.gridLayout.setHorizontalSpacing(20)
self.gridLayout.setObjectName("gridLayout")
self.label_18 = QtWidgets.QLabel(self.frame_21) self.label_18 = QtWidgets.QLabel(self.frame_21)
self.label_18.setMinimumSize(QtCore.QSize(200, 0))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(11)
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.label_18.setFont(font) self.label_18.setFont(font)
self.label_18.setObjectName("label_18") self.label_18.setObjectName("label_18")
self.verticalLayout_12.addWidget(self.label_18) self.gridLayout.addWidget(self.label_18, 0, 0, 1, 1)
self.vendors_list_view_import = QtWidgets.QListView(self.frame_21) self.vendor_combo_box = QtWidgets.QComboBox(self.frame_21)
font = QtGui.QFont() self.vendor_combo_box.setObjectName("vendor_combo_box")
font.setFamily("Segoe UI") self.gridLayout.addWidget(self.vendor_combo_box, 1, 0, 1, 1)
font.setPointSize(11) self.label_19 = QtWidgets.QLabel(self.frame_21)
self.vendors_list_view_import.setFont(font) self.label_19.setMinimumSize(QtCore.QSize(100, 0))
self.vendors_list_view_import.setAlternatingRowColors(True)
self.vendors_list_view_import.setObjectName("vendors_list_view_import")
self.verticalLayout_12.addWidget(self.vendors_list_view_import)
self.horizontalLayout_2.addWidget(self.frame_21)
self.frame_20 = QtWidgets.QFrame(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_20.sizePolicy().hasHeightForWidth())
self.frame_20.setSizePolicy(sizePolicy)
self.frame_20.setMinimumSize(QtCore.QSize(200, 0))
self.frame_20.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_20.setObjectName("frame_20")
self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.frame_20)
self.verticalLayout_11.setObjectName("verticalLayout_11")
self.label_17 = QtWidgets.QLabel(self.frame_20)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(11)
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.label_17.setFont(font) self.label_19.setFont(font)
self.label_17.setObjectName("label_17") self.label_19.setObjectName("label_19")
self.verticalLayout_11.addWidget(self.label_17) self.gridLayout.addWidget(self.label_19, 0, 1, 1, 1)
self.report_types_list_view_import = QtWidgets.QListView(self.frame_20) self.report_year_date_edit = QtWidgets.QDateEdit(self.frame_21)
font = QtGui.QFont() self.report_year_date_edit.setObjectName("report_year_date_edit")
font.setFamily("Segoe UI") self.gridLayout.addWidget(self.report_year_date_edit, 1, 1, 1, 1)
font.setPointSize(11) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.report_types_list_view_import.setFont(font) self.gridLayout.addItem(spacerItem, 0, 2, 2, 1)
self.report_types_list_view_import.setAlternatingRowColors(True) self.verticalLayout.addWidget(self.frame_21)
self.report_types_list_view_import.setObjectName("report_types_list_view_import") self.frame = QtWidgets.QFrame(import_report_tab)
self.verticalLayout_11.addWidget(self.report_types_list_view_import) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
self.horizontalLayout_2.addWidget(self.frame_20) sizePolicy.setHorizontalStretch(0)
self.frame_22 = QtWidgets.QFrame(self.frame) sizePolicy.setVerticalStretch(0)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
sizePolicy.setHorizontalStretch(0) self.frame.setSizePolicy(sizePolicy)
sizePolicy.setVerticalStretch(0) self.frame.setObjectName("frame")
sizePolicy.setHeightForWidth(self.frame_22.sizePolicy().hasHeightForWidth()) self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.frame_22.setSizePolicy(sizePolicy) self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.frame_22.setMinimumSize(QtCore.QSize(200, 0)) self.horizontalLayout.setObjectName("horizontalLayout")
self.frame_22.setObjectName("frame_22") self.frame_17 = QtWidgets.QFrame(self.frame)
self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.frame_22)
self.verticalLayout_13.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_13.setObjectName("verticalLayout_13")
self.frame_17 = QtWidgets.QFrame(self.frame_22)
self.frame_17.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_17.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_17.setObjectName("frame_17") self.frame_17.setObjectName("frame_17")
self.verticalLayout_24 = QtWidgets.QVBoxLayout(self.frame_17) self.verticalLayout_24 = QtWidgets.QVBoxLayout(self.frame_17)
self.verticalLayout_24.setObjectName("verticalLayout_24") self.verticalLayout_24.setObjectName("verticalLayout_24")
self.label_16 = QtWidgets.QLabel(self.frame_17) self.label_2 = QtWidgets.QLabel(self.frame_17)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth())
self.label_16.setSizePolicy(sizePolicy)
font = QtGui.QFont() font = QtGui.QFont()
font.setBold(True) font.setBold(True)
font.setWeight(75) font.setWeight(75)
self.label_16.setFont(font) self.label_2.setFont(font)
self.label_16.setObjectName("label_16") self.label_2.setObjectName("label_2")
self.verticalLayout_24.addWidget(self.label_16) self.verticalLayout_24.addWidget(self.label_2)
self.frame_19 = QtWidgets.QFrame(self.frame_17) self.frame_2 = QtWidgets.QFrame(self.frame_17)
self.frame_19.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_2.setObjectName("frame_2")
self.frame_19.setObjectName("frame_19") self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_2)
self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.frame_19) self.gridLayout_2.setHorizontalSpacing(20)
self.horizontalLayout_13.setObjectName("horizontalLayout_13") self.gridLayout_2.setObjectName("gridLayout_2")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.label_17 = QtWidgets.QLabel(self.frame_2)
self.horizontalLayout_13.addItem(spacerItem) font = QtGui.QFont()
self.label_19 = QtWidgets.QLabel(self.frame_19) font.setBold(True)
self.label_19.setMinimumSize(QtCore.QSize(100, 0)) font.setWeight(75)
self.label_19.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_17.setFont(font)
self.label_19.setObjectName("label_19") self.label_17.setObjectName("label_17")
self.horizontalLayout_13.addWidget(self.label_19) self.gridLayout_2.addWidget(self.label_17, 0, 0, 1, 1)
self.report_year_date_edit = QtWidgets.QDateEdit(self.frame_19) self.label_36 = QtWidgets.QLabel(self.frame_2)
self.report_year_date_edit.setObjectName("report_year_date_edit") sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
self.horizontalLayout_13.addWidget(self.report_year_date_edit)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_13.addItem(spacerItem1)
self.verticalLayout_24.addWidget(self.frame_19)
self.verticalLayout_13.addWidget(self.frame_17)
self.frame_18 = QtWidgets.QFrame(self.frame_22)
self.frame_18.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_18.setObjectName("frame_18")
self.verticalLayout_25 = QtWidgets.QVBoxLayout(self.frame_18)
self.verticalLayout_25.setObjectName("verticalLayout_25")
self.label_36 = QtWidgets.QLabel(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_36.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.label_36.sizePolicy().hasHeightForWidth())
@ -143,66 +101,229 @@ class Ui_import_report_tab(object):
font.setWeight(75) font.setWeight(75)
self.label_36.setFont(font) self.label_36.setFont(font)
self.label_36.setObjectName("label_36") self.label_36.setObjectName("label_36")
self.verticalLayout_25.addWidget(self.label_36) self.gridLayout_2.addWidget(self.label_36, 0, 1, 1, 1)
self.frame_38 = QtWidgets.QFrame(self.frame_18) self.frame_38 = QtWidgets.QFrame(self.frame_2)
self.frame_38.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_38.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_38.setObjectName("frame_38") self.frame_38.setObjectName("frame_38")
self.horizontalLayout_15 = QtWidgets.QHBoxLayout(self.frame_38) self.horizontalLayout_15 = QtWidgets.QHBoxLayout(self.frame_38)
self.horizontalLayout_15.setObjectName("horizontalLayout_15") self.horizontalLayout_15.setObjectName("horizontalLayout_15")
self.select_file_button = QtWidgets.QPushButton(self.frame_38) self.c5_selected_file_edit = QtWidgets.QLineEdit(self.frame_38)
self.c5_selected_file_edit.setReadOnly(True)
self.c5_selected_file_edit.setObjectName("c5_selected_file_edit")
self.horizontalLayout_15.addWidget(self.c5_selected_file_edit)
self.c5_select_file_button = QtWidgets.QPushButton(self.frame_38)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.select_file_button.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.c5_select_file_button.sizePolicy().hasHeightForWidth())
self.select_file_button.setSizePolicy(sizePolicy) self.c5_select_file_button.setSizePolicy(sizePolicy)
self.select_file_button.setObjectName("select_file_button") self.c5_select_file_button.setObjectName("c5_select_file_button")
self.horizontalLayout_15.addWidget(self.select_file_button) self.horizontalLayout_15.addWidget(self.c5_select_file_button)
self.selected_file_edit = QtWidgets.QLineEdit(self.frame_38) self.gridLayout_2.addWidget(self.frame_38, 1, 1, 1, 1)
self.selected_file_edit.setReadOnly(True) self.c5_report_type_combo_box = QtWidgets.QComboBox(self.frame_2)
self.selected_file_edit.setObjectName("selected_file_edit") self.c5_report_type_combo_box.setObjectName("c5_report_type_combo_box")
self.horizontalLayout_15.addWidget(self.selected_file_edit) self.gridLayout_2.addWidget(self.c5_report_type_combo_box, 1, 0, 1, 1, QtCore.Qt.AlignTop)
self.verticalLayout_25.addWidget(self.frame_38) self.verticalLayout_24.addWidget(self.frame_2)
self.verticalLayout_13.addWidget(self.frame_18) self.frame_25 = QtWidgets.QFrame(self.frame_17)
self.frame_24 = QtWidgets.QFrame(self.frame_22) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
self.frame_24.setFrameShape(QtWidgets.QFrame.StyledPanel) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_25.sizePolicy().hasHeightForWidth())
self.frame_25.setSizePolicy(sizePolicy)
self.frame_25.setObjectName("frame_25")
self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_25)
self.gridLayout_8.setObjectName("gridLayout_8")
self.c5_import_report_button = QtWidgets.QPushButton(self.frame_25)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.c5_import_report_button.sizePolicy().hasHeightForWidth())
self.c5_import_report_button.setSizePolicy(sizePolicy)
self.c5_import_report_button.setObjectName("c5_import_report_button")
self.gridLayout_8.addWidget(self.c5_import_report_button, 0, 0, 1, 1)
self.verticalLayout_24.addWidget(self.frame_25)
spacerItem1 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding)
self.verticalLayout_24.addItem(spacerItem1)
self.horizontalLayout.addWidget(self.frame_17)
self.frame_18 = QtWidgets.QFrame(self.frame)
self.frame_18.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_18.setObjectName("frame_18")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_18)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label_3 = QtWidgets.QLabel(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
self.label_3.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.verticalLayout_3.addWidget(self.label_3)
self.frame_3 = QtWidgets.QFrame(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
self.frame_3.setSizePolicy(sizePolicy)
self.frame_3.setObjectName("frame_3")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.frame_4 = QtWidgets.QFrame(self.frame_3)
self.frame_4.setObjectName("frame_4")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame_4)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_20 = QtWidgets.QLabel(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_20.sizePolicy().hasHeightForWidth())
self.label_20.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_20.setFont(font)
self.label_20.setObjectName("label_20")
self.verticalLayout_2.addWidget(self.label_20)
self.c4_report_type_combo_box = QtWidgets.QComboBox(self.frame_4)
self.c4_report_type_combo_box.setObjectName("c4_report_type_combo_box")
self.verticalLayout_2.addWidget(self.c4_report_type_combo_box)
self.label_21 = QtWidgets.QLabel(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_21.sizePolicy().hasHeightForWidth())
self.label_21.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_21.setFont(font)
self.label_21.setObjectName("label_21")
self.verticalLayout_2.addWidget(self.label_21)
self.c4_report_type_equiv_label = QtWidgets.QLabel(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.c4_report_type_equiv_label.sizePolicy().hasHeightForWidth())
self.c4_report_type_equiv_label.setSizePolicy(sizePolicy)
self.c4_report_type_equiv_label.setObjectName("c4_report_type_equiv_label")
self.verticalLayout_2.addWidget(self.c4_report_type_equiv_label)
spacerItem2 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem2)
self.horizontalLayout_2.addWidget(self.frame_4)
self.frame_5 = QtWidgets.QFrame(self.frame_3)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth())
self.frame_5.setSizePolicy(sizePolicy)
self.frame_5.setObjectName("frame_5")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_5)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label_37 = QtWidgets.QLabel(self.frame_5)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_37.sizePolicy().hasHeightForWidth())
self.label_37.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_37.setFont(font)
self.label_37.setObjectName("label_37")
self.verticalLayout_4.addWidget(self.label_37)
self.c4_files_frame = QtWidgets.QFrame(self.frame_5)
self.c4_files_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.c4_files_frame.setObjectName("c4_files_frame")
self.horizontalLayout_16 = QtWidgets.QHBoxLayout(self.c4_files_frame)
self.horizontalLayout_16.setObjectName("horizontalLayout_16")
self.scrollArea = QtWidgets.QScrollArea(self.c4_files_frame)
self.scrollArea.setMinimumSize(QtCore.QSize(200, 100))
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents_2 = QtWidgets.QWidget()
self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 198, 18))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_2.sizePolicy().hasHeightForWidth())
self.scrollAreaWidgetContents_2.setSizePolicy(sizePolicy)
self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents_2)
self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.c4_selected_files_frame = QtWidgets.QFrame(self.scrollAreaWidgetContents_2)
self.c4_selected_files_frame.setObjectName("c4_selected_files_frame")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.c4_selected_files_frame)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.verticalLayout_6.addWidget(self.c4_selected_files_frame)
self.scrollArea.setWidget(self.scrollAreaWidgetContents_2)
self.horizontalLayout_16.addWidget(self.scrollArea)
self.c4_select_file_button = QtWidgets.QPushButton(self.c4_files_frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.c4_select_file_button.sizePolicy().hasHeightForWidth())
self.c4_select_file_button.setSizePolicy(sizePolicy)
self.c4_select_file_button.setObjectName("c4_select_file_button")
self.horizontalLayout_16.addWidget(self.c4_select_file_button)
self.verticalLayout_4.addWidget(self.c4_files_frame)
self.horizontalLayout_2.addWidget(self.frame_5, 0, QtCore.Qt.AlignTop)
self.verticalLayout_3.addWidget(self.frame_3)
self.frame_24 = QtWidgets.QFrame(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_24.sizePolicy().hasHeightForWidth())
self.frame_24.setSizePolicy(sizePolicy)
self.frame_24.setObjectName("frame_24") self.frame_24.setObjectName("frame_24")
self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_24) self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_24)
self.gridLayout_7.setObjectName("gridLayout_7") self.gridLayout_7.setObjectName("gridLayout_7")
self.import_report_button = QtWidgets.QPushButton(self.frame_24) self.c4_import_report_button = QtWidgets.QPushButton(self.frame_24)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.import_report_button.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.c4_import_report_button.sizePolicy().hasHeightForWidth())
self.import_report_button.setSizePolicy(sizePolicy) self.c4_import_report_button.setSizePolicy(sizePolicy)
self.import_report_button.setMaximumSize(QtCore.QSize(180, 16777215)) self.c4_import_report_button.setObjectName("c4_import_report_button")
self.import_report_button.setObjectName("import_report_button") self.gridLayout_7.addWidget(self.c4_import_report_button, 0, 0, 1, 1)
self.gridLayout_7.addWidget(self.import_report_button, 0, 0, 1, 1) self.verticalLayout_3.addWidget(self.frame_24)
self.verticalLayout_13.addWidget(self.frame_24) spacerItem3 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.horizontalLayout_2.addWidget(self.frame_22) self.verticalLayout_3.addItem(spacerItem3)
self.horizontalLayout.addWidget(self.frame_18)
self.verticalLayout.addWidget(self.frame) self.verticalLayout.addWidget(self.frame)
self.label = QtWidgets.QLabel(import_report_tab) self.label = QtWidgets.QLabel(import_report_tab)
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label.setObjectName("label") self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label) self.verticalLayout.addWidget(self.label)
spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem4)
self.retranslateUi(import_report_tab) self.retranslateUi(import_report_tab)
QtCore.QMetaObject.connectSlotsByName(import_report_tab) QtCore.QMetaObject.connectSlotsByName(import_report_tab)
import_report_tab.setTabOrder(self.vendors_list_view_import, self.report_types_list_view_import) import_report_tab.setTabOrder(self.c5_selected_file_edit, self.c4_import_report_button)
import_report_tab.setTabOrder(self.report_types_list_view_import, self.report_year_date_edit)
import_report_tab.setTabOrder(self.report_year_date_edit, self.selected_file_edit)
import_report_tab.setTabOrder(self.selected_file_edit, self.import_report_button)
def retranslateUi(self, import_report_tab): def retranslateUi(self, import_report_tab):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
import_report_tab.setWindowTitle(_translate("import_report_tab", "Import Report")) import_report_tab.setWindowTitle(_translate("import_report_tab", "Import Report"))
self.label_18.setText(_translate("import_report_tab", "Select Vendor")) self.label_18.setText(_translate("import_report_tab", "Select Vendor"))
self.label_17.setText(_translate("import_report_tab", "Select Report Type"))
self.label_16.setText(_translate("import_report_tab", "Date"))
self.label_19.setText(_translate("import_report_tab", "Report Year")) self.label_19.setText(_translate("import_report_tab", "Report Year"))
self.report_year_date_edit.setDisplayFormat(_translate("import_report_tab", "yyyy")) self.report_year_date_edit.setDisplayFormat(_translate("import_report_tab", "yyyy"))
self.label_36.setText(_translate("import_report_tab", "Target Report File")) self.label_2.setText(_translate("import_report_tab", "COUNTER 5"))
self.select_file_button.setText(_translate("import_report_tab", "Select File")) self.label_17.setText(_translate("import_report_tab", "Select Report Type"))
self.import_report_button.setText(_translate("import_report_tab", "Import Selected Report")) self.label_36.setText(_translate("import_report_tab", "Source Report File"))
self.c5_select_file_button.setText(_translate("import_report_tab", "Select File"))
self.c5_import_report_button.setText(_translate("import_report_tab", "Import Selected Report"))
self.label_3.setText(_translate("import_report_tab", "COUNTER 4 (Converts to COUNTER 5)"))
self.label_20.setText(_translate("import_report_tab", "Counter 4 Report Type"))
self.label_21.setText(_translate("import_report_tab", "Counter 5 Equivalent(s)"))
self.c4_report_type_equiv_label.setText(_translate("import_report_tab", "TextLabel"))
self.label_37.setText(_translate("import_report_tab", "Source Report File(s)"))
self.c4_select_file_button.setText(_translate("import_report_tab", "Select File(s)"))
self.c4_import_report_button.setText(_translate("import_report_tab", "Import Selected Report(s)"))
self.label.setText(_translate("import_report_tab", "Note: Only yearly reports (all available data for one calender year) should be imported. Imported reports are added to the search database.")) self.label.setText(_translate("import_report_tab", "Note: Only yearly reports (all available data for one calender year) should be imported. Imported reports are added to the search database."))
import Resources_rc import Resources_rc

444
ui/ImportReportTab.ui

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1008</width> <width>1007</width>
<height>530</height> <height>467</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -18,16 +18,10 @@
<normaloff>:/ui/resources/tab_icons/import_report_icon.png</normaloff>:/ui/resources/tab_icons/import_report_icon.png</iconset> <normaloff>:/ui/resources/tab_icons/import_report_icon.png</normaloff>:/ui/resources/tab_icons/import_report_icon.png</iconset>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QFrame" name="frame_21"> <widget class="QFrame" name="frame_21">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -41,13 +35,20 @@
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_12"> <layout class="QGridLayout" name="gridLayout">
<item> <property name="horizontalSpacing">
<number>20</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_18"> <widget class="QLabel" name="label_18">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="font"> <property name="font">
<font> <font>
<family>Segoe UI</family>
<pointsize>11</pointsize>
<weight>75</weight> <weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
@ -57,46 +58,101 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="1" column="0">
<widget class="QListView" name="vendors_list_view_import"> <widget class="QComboBox" name="vendor_combo_box"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_19">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="font"> <property name="font">
<font> <font>
<family>Segoe UI</family> <weight>75</weight>
<pointsize>11</pointsize> <bold>true</bold>
</font> </font>
</property> </property>
<property name="alternatingRowColors"> <property name="text">
<bool>true</bool> <string>Report Year</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDateEdit" name="report_year_date_edit">
<property name="displayFormat">
<string>yyyy</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2" rowspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="frame_20"> <widget class="QFrame" name="frame">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <layout class="QHBoxLayout" name="horizontalLayout">
<size> <property name="leftMargin">
<width>200</width> <number>0</number>
<height>0</height> </property>
</size> <property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property> </property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_17">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_11"> <layout class="QVBoxLayout" name="verticalLayout_24">
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>COUNTER 5</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QFrame" name="frame_2">
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>20</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_17"> <widget class="QLabel" name="label_17">
<property name="font"> <property name="font">
<font> <font>
<family>Segoe UI</family>
<pointsize>11</pointsize>
<weight>75</weight> <weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
@ -106,37 +162,138 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="1">
<widget class="QListView" name="report_types_list_view_import"> <widget class="QLabel" name="label_36">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font"> <property name="font">
<font> <font>
<family>Segoe UI</family> <weight>75</weight>
<pointsize>11</pointsize> <bold>true</bold>
</font> </font>
</property> </property>
<property name="alternatingRowColors"> <property name="text">
<string>Source Report File</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QFrame" name="frame_38">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<item>
<widget class="QLineEdit" name="c5_selected_file_edit">
<property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="c5_select_file_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select File</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignTop">
<widget class="QComboBox" name="c5_report_type_combo_box"/>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="frame_22"> <widget class="QFrame" name="frame_25">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<widget class="QPushButton" name="c5_import_report_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Import Selected Report</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size> <size>
<width>200</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_13"> </spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_18">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>COUNTER 4 (Converts to COUNTER 5)</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -150,13 +307,10 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QFrame" name="frame_17"> <widget class="QFrame" name="frame_4">
<property name="frameShape"> <layout class="QVBoxLayout" name="verticalLayout_2">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_24">
<item> <item>
<widget class="QLabel" name="label_16"> <widget class="QLabel" name="label_20">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -170,61 +324,54 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Date</string> <string>Counter 4 Report Type</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="frame_19"> <widget class="QComboBox" name="c4_report_type_combo_box"/>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_19"> <widget class="QLabel" name="label_21">
<property name="minimumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<width>100</width> <horstretch>0</horstretch>
<height>0</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property> </property>
<property name="text"> <property name="font">
<string>Report Year</string> <font>
<weight>75</weight>
<bold>true</bold>
</font>
</property> </property>
<property name="alignment"> <property name="text">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <string>Counter 5 Equivalent(s)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QDateEdit" name="report_year_date_edit"> <widget class="QLabel" name="c4_report_type_equiv_label">
<property name="displayFormat"> <property name="sizePolicy">
<string>yyyy</string> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2"> <spacer name="verticalSpacer_4">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>0</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -232,19 +379,19 @@
</layout> </layout>
</widget> </widget>
</item> </item>
</layout> <item alignment="Qt::AlignTop">
</widget> <widget class="QFrame" name="frame_5">
</item> <property name="sizePolicy">
<item> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<widget class="QFrame" name="frame_18"> <horstretch>0</horstretch>
<property name="frameShape"> <verstretch>0</verstretch>
<enum>QFrame::StyledPanel</enum> </sizepolicy>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_25"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
<widget class="QLabel" name="label_36"> <widget class="QLabel" name="label_37">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -256,34 +403,81 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Target Report File</string> <string>Source Report File(s)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="frame_38"> <widget class="QFrame" name="c4_files_frame">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_15"> <layout class="QHBoxLayout" name="horizontalLayout_16">
<item> <item>
<widget class="QPushButton" name="select_file_button"> <widget class="QScrollArea" name="scrollArea">
<property name="minimumSize">
<size>
<width>200</width>
<height>100</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>198</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <layout class="QVBoxLayout" name="verticalLayout_6">
<string>Select File</string> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property> </property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="c4_selected_files_frame">
<layout class="QVBoxLayout" name="verticalLayout_5"/>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="selected_file_edit"> <widget class="QPushButton" name="c4_select_file_button">
<property name="readOnly"> <property name="sizePolicy">
<bool>true</bool> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="text">
<string>Select File(s)</string>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -294,32 +488,42 @@
</item> </item>
<item> <item>
<widget class="QFrame" name="frame_24"> <widget class="QFrame" name="frame_24">
<property name="frameShape"> <property name="sizePolicy">
<enum>QFrame::StyledPanel</enum> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<layout class="QGridLayout" name="gridLayout_7"> <layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QPushButton" name="import_report_button"> <widget class="QPushButton" name="c4_import_report_button">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="maximumSize">
<size>
<width>180</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>Import Selected Report</string> <string>Import Selected Report(s)</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -336,14 +540,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
<tabstops> <tabstops>
<tabstop>vendors_list_view_import</tabstop> <tabstop>c5_selected_file_edit</tabstop>
<tabstop>report_types_list_view_import</tabstop> <tabstop>c4_import_report_button</tabstop>
<tabstop>report_year_date_edit</tabstop>
<tabstop>selected_file_edit</tabstop>
<tabstop>import_report_button</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../Resources.qrc"/> <include location="../Resources.qrc"/>

160
ui/VisualTab.py

@ -2,38 +2,25 @@
# Form implementation generated from reading ui file 'VisualTab.ui' # Form implementation generated from reading ui file 'VisualTab.ui'
# #
# Created by: PyQt5 UI code generator 5.14.1 # Created by: PyQt5 UI code generator 5.9.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_visual_tab(object): class Ui_visual_tab(object):
def setupUi(self, visual_tab): def setupUi(self, visual_tab):
visual_tab.setObjectName("visual_tab") visual_tab.setObjectName("visual_tab")
visual_tab.resize(1177, 690) visual_tab.resize(692, 488)
icon = QtGui.QIcon() icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/ui/resources/tab_icons/visual_icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) icon.addPixmap(QtGui.QPixmap(":/ui/resources/tab_icons/visual_icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
visual_tab.setWindowIcon(icon) visual_tab.setWindowIcon(icon)
self.verticalLayout = QtWidgets.QVBoxLayout(visual_tab) self.verticalLayout = QtWidgets.QVBoxLayout(visual_tab)
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.search_parameters_frame_2 = QtWidgets.QFrame(visual_tab) self.search_initial_parameters_frame_2 = QtWidgets.QFrame(visual_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.search_parameters_frame_2.sizePolicy().hasHeightForWidth())
self.search_parameters_frame_2.setSizePolicy(sizePolicy)
self.search_parameters_frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.search_parameters_frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.search_parameters_frame_2.setObjectName("search_parameters_frame_2")
self.verticalLayout_22 = QtWidgets.QVBoxLayout(self.search_parameters_frame_2)
self.verticalLayout_22.setObjectName("verticalLayout_22")
self.search_initial_parameters_frame_2 = QtWidgets.QFrame(self.search_parameters_frame_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.search_initial_parameters_frame_2.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.search_initial_parameters_frame_2.sizePolicy().hasHeightForWidth())
self.search_initial_parameters_frame_2.setSizePolicy(sizePolicy) self.search_initial_parameters_frame_2.setSizePolicy(sizePolicy)
self.search_initial_parameters_frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) self.search_initial_parameters_frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
@ -74,15 +61,8 @@ class Ui_visual_tab(object):
self.gridLayout_6.addItem(spacerItem, 1, 1, 1, 1) self.gridLayout_6.addItem(spacerItem, 1, 1, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum) spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_6.addItem(spacerItem1, 1, 3, 1, 1) self.gridLayout_6.addItem(spacerItem1, 1, 3, 1, 1)
self.verticalLayout_22.addWidget(self.search_initial_parameters_frame_2) self.verticalLayout.addWidget(self.search_initial_parameters_frame_2)
self.verticalLayout.addWidget(self.search_parameters_frame_2) self.frame_15 = QtWidgets.QFrame(visual_tab)
self.frame_14 = QtWidgets.QFrame(visual_tab)
self.frame_14.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_14.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_14.setObjectName("frame_14")
self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.frame_14)
self.horizontalLayout_14.setObjectName("horizontalLayout_14")
self.frame_15 = QtWidgets.QFrame(self.frame_14)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -91,44 +71,8 @@ class Ui_visual_tab(object):
self.frame_15.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_15.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_15.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_15.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_15.setObjectName("frame_15") self.frame_15.setObjectName("frame_15")
self.gridLayout_13 = QtWidgets.QGridLayout(self.frame_15) self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame_15)
self.gridLayout_13.setObjectName("gridLayout_13") self.verticalLayout_2.setObjectName("verticalLayout_2")
self.frame_2 = QtWidgets.QFrame(self.frame_15)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
self.frame_2.setSizePolicy(sizePolicy)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.visual_name_label = QtWidgets.QLabel(self.frame_2)
self.visual_name_label.setEnabled(True)
self.visual_name_label.setGeometry(QtCore.QRect(50, 80, 97, 21))
self.visual_name_label.setObjectName("visual_name_label")
self.visual_metric_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_metric_parameter_label.setGeometry(QtCore.QRect(50, 130, 213, 20))
self.visual_metric_parameter_label.setObjectName("visual_metric_parameter_label")
self.metric_Type_comboBox = QtWidgets.QComboBox(self.frame_2)
self.metric_Type_comboBox.setGeometry(QtCore.QRect(140, 130, 921, 26))
self.metric_Type_comboBox.setObjectName("metric_Type_comboBox")
self.visual_vendor_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_vendor_parameter_label.setGeometry(QtCore.QRect(50, 30, 61, 20))
self.visual_vendor_parameter_label.setObjectName("visual_vendor_parameter_label")
self.visual_vendor_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
self.visual_vendor_parameter_combobox.setGeometry(QtCore.QRect(140, 30, 921, 26))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.visual_vendor_parameter_combobox.sizePolicy().hasHeightForWidth())
self.visual_vendor_parameter_combobox.setSizePolicy(sizePolicy)
self.visual_vendor_parameter_combobox.setObjectName("visual_vendor_parameter_combobox")
self.visual_name_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
self.visual_name_parameter_combobox.setEnabled(True)
self.visual_name_parameter_combobox.setGeometry(QtCore.QRect(140, 80, 921, 28))
self.visual_name_parameter_combobox.setEditable(True)
self.visual_name_parameter_combobox.setObjectName("visual_name_parameter_combobox")
self.gridLayout_13.addWidget(self.frame_2, 5, 0, 1, 3)
self.frame = QtWidgets.QFrame(self.frame_15) self.frame = QtWidgets.QFrame(self.frame_15)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -138,9 +82,10 @@ class Ui_visual_tab(object):
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame") self.frame.setObjectName("frame")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout.setObjectName("horizontalLayout")
self.frame_18 = QtWidgets.QFrame(self.frame) self.frame_18 = QtWidgets.QFrame(self.frame)
self.frame_18.setEnabled(True) self.frame_18.setEnabled(True)
self.frame_18.setGeometry(QtCore.QRect(10, 10, 136, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -172,8 +117,8 @@ class Ui_visual_tab(object):
self.radioButton_4 = QtWidgets.QRadioButton(self.frame_18) self.radioButton_4 = QtWidgets.QRadioButton(self.frame_18)
self.radioButton_4.setObjectName("radioButton_4") self.radioButton_4.setObjectName("radioButton_4")
self.verticalLayout_28.addWidget(self.radioButton_4) self.verticalLayout_28.addWidget(self.radioButton_4)
self.horizontalLayout.addWidget(self.frame_18)
self.frame_options = QtWidgets.QFrame(self.frame) self.frame_options = QtWidgets.QFrame(self.frame)
self.frame_options.setGeometry(QtCore.QRect(150, 10, 141, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -182,8 +127,9 @@ class Ui_visual_tab(object):
self.frame_options.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_options.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_options.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_options.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_options.setObjectName("frame_options") self.frame_options.setObjectName("frame_options")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_options)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label_46 = QtWidgets.QLabel(self.frame_options) self.label_46 = QtWidgets.QLabel(self.frame_options)
self.label_46.setGeometry(QtCore.QRect(10, 10, 121, 21))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -194,21 +140,22 @@ class Ui_visual_tab(object):
self.label_46.setFont(font) self.label_46.setFont(font)
self.label_46.setTextFormat(QtCore.Qt.AutoText) self.label_46.setTextFormat(QtCore.Qt.AutoText)
self.label_46.setObjectName("label_46") self.label_46.setObjectName("label_46")
self.verticalLayout_3.addWidget(self.label_46)
self.monthly_radioButton = QtWidgets.QRadioButton(self.frame_options) self.monthly_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.monthly_radioButton.setGeometry(QtCore.QRect(10, 40, 112, 20))
self.monthly_radioButton.setObjectName("monthly_radioButton") self.monthly_radioButton.setObjectName("monthly_radioButton")
self.verticalLayout_3.addWidget(self.monthly_radioButton)
self.yearly_radioButton = QtWidgets.QRadioButton(self.frame_options) self.yearly_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.yearly_radioButton.setGeometry(QtCore.QRect(10, 70, 112, 20))
self.yearly_radioButton.setObjectName("yearly_radioButton") self.yearly_radioButton.setObjectName("yearly_radioButton")
self.verticalLayout_3.addWidget(self.yearly_radioButton)
self.topnum_radioButton = QtWidgets.QRadioButton(self.frame_options) self.topnum_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.topnum_radioButton.setGeometry(QtCore.QRect(10, 100, 112, 20))
self.topnum_radioButton.setObjectName("topnum_radioButton") self.topnum_radioButton.setObjectName("topnum_radioButton")
self.verticalLayout_3.addWidget(self.topnum_radioButton)
self.costratio_radioButton = QtWidgets.QRadioButton(self.frame_options) self.costratio_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.costratio_radioButton.setGeometry(QtCore.QRect(10, 130, 112, 20))
self.costratio_radioButton.setObjectName("costratio_radioButton") self.costratio_radioButton.setObjectName("costratio_radioButton")
self.verticalLayout_3.addWidget(self.costratio_radioButton)
self.horizontalLayout.addWidget(self.frame_options)
self.option_frame = QtWidgets.QFrame(self.frame) self.option_frame = QtWidgets.QFrame(self.frame)
self.option_frame.setEnabled(True) self.option_frame.setEnabled(True)
self.option_frame.setGeometry(QtCore.QRect(293, 10, 151, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -217,8 +164,9 @@ class Ui_visual_tab(object):
self.option_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.option_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.option_frame.setFrameShadow(QtWidgets.QFrame.Raised) self.option_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.option_frame.setObjectName("option_frame") self.option_frame.setObjectName("option_frame")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.option_frame)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.edit_cost_ratio_frame = QtWidgets.QFrame(self.option_frame) self.edit_cost_ratio_frame = QtWidgets.QFrame(self.option_frame)
self.edit_cost_ratio_frame.setGeometry(QtCore.QRect(10, 10, 131, 81))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -227,8 +175,9 @@ class Ui_visual_tab(object):
self.edit_cost_ratio_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.edit_cost_ratio_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.edit_cost_ratio_frame.setFrameShadow(QtWidgets.QFrame.Raised) self.edit_cost_ratio_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.edit_cost_ratio_frame.setObjectName("edit_cost_ratio_frame") self.edit_cost_ratio_frame.setObjectName("edit_cost_ratio_frame")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.edit_cost_ratio_frame)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label_47 = QtWidgets.QLabel(self.edit_cost_ratio_frame) self.label_47 = QtWidgets.QLabel(self.edit_cost_ratio_frame)
self.label_47.setGeometry(QtCore.QRect(10, 10, 183, 15))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -239,11 +188,12 @@ class Ui_visual_tab(object):
self.label_47.setFont(font) self.label_47.setFont(font)
self.label_47.setTextFormat(QtCore.Qt.AutoText) self.label_47.setTextFormat(QtCore.Qt.AutoText)
self.label_47.setObjectName("label_47") self.label_47.setObjectName("label_47")
self.verticalLayout_4.addWidget(self.label_47)
self.cost_ratio_option_combobox = QtWidgets.QComboBox(self.edit_cost_ratio_frame) self.cost_ratio_option_combobox = QtWidgets.QComboBox(self.edit_cost_ratio_frame)
self.cost_ratio_option_combobox.setGeometry(QtCore.QRect(0, 30, 121, 26))
self.cost_ratio_option_combobox.setObjectName("cost_ratio_option_combobox") self.cost_ratio_option_combobox.setObjectName("cost_ratio_option_combobox")
self.verticalLayout_4.addWidget(self.cost_ratio_option_combobox)
self.verticalLayout_6.addWidget(self.edit_cost_ratio_frame)
self.edit_top_num_frame = QtWidgets.QFrame(self.option_frame) self.edit_top_num_frame = QtWidgets.QFrame(self.option_frame)
self.edit_top_num_frame.setGeometry(QtCore.QRect(10, 90, 131, 61))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -252,8 +202,9 @@ class Ui_visual_tab(object):
self.edit_top_num_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.edit_top_num_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.edit_top_num_frame.setFrameShadow(QtWidgets.QFrame.Raised) self.edit_top_num_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.edit_top_num_frame.setObjectName("edit_top_num_frame") self.edit_top_num_frame.setObjectName("edit_top_num_frame")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.edit_top_num_frame)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.label_48 = QtWidgets.QLabel(self.edit_top_num_frame) self.label_48 = QtWidgets.QLabel(self.edit_top_num_frame)
self.label_48.setGeometry(QtCore.QRect(10, 10, 183, 15))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -264,12 +215,14 @@ class Ui_visual_tab(object):
self.label_48.setFont(font) self.label_48.setFont(font)
self.label_48.setTextFormat(QtCore.Qt.AutoText) self.label_48.setTextFormat(QtCore.Qt.AutoText)
self.label_48.setObjectName("label_48") self.label_48.setObjectName("label_48")
self.verticalLayout_5.addWidget(self.label_48)
self.top_num_spinbox = QtWidgets.QSpinBox(self.edit_top_num_frame) self.top_num_spinbox = QtWidgets.QSpinBox(self.edit_top_num_frame)
self.top_num_spinbox.setGeometry(QtCore.QRect(10, 30, 101, 24))
self.top_num_spinbox.setMaximum(999) self.top_num_spinbox.setMaximum(999)
self.top_num_spinbox.setObjectName("top_num_spinbox") self.top_num_spinbox.setObjectName("top_num_spinbox")
self.verticalLayout_5.addWidget(self.top_num_spinbox)
self.verticalLayout_6.addWidget(self.edit_top_num_frame)
self.horizontalLayout.addWidget(self.option_frame)
self.frame_16 = QtWidgets.QFrame(self.frame) self.frame_16 = QtWidgets.QFrame(self.frame)
self.frame_16.setGeometry(QtCore.QRect(460, 10, 601, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
@ -298,9 +251,47 @@ class Ui_visual_tab(object):
self.label_36 = QtWidgets.QLabel(self.frame_16) self.label_36 = QtWidgets.QLabel(self.frame_16)
self.label_36.setObjectName("label_36") self.label_36.setObjectName("label_36")
self.gridLayout_14.addWidget(self.label_36, 2, 0, 1, 1) self.gridLayout_14.addWidget(self.label_36, 2, 0, 1, 1)
self.gridLayout_13.addWidget(self.frame, 0, 0, 1, 3) self.horizontalLayout.addWidget(self.frame_16)
self.horizontalLayout_14.addWidget(self.frame_15) self.verticalLayout_2.addWidget(self.frame)
self.verticalLayout.addWidget(self.frame_14) self.frame_2 = QtWidgets.QFrame(self.frame_15)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
self.frame_2.setSizePolicy(sizePolicy)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.gridLayout = QtWidgets.QGridLayout(self.frame_2)
self.gridLayout.setObjectName("gridLayout")
self.visual_vendor_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_vendor_parameter_label.setObjectName("visual_vendor_parameter_label")
self.gridLayout.addWidget(self.visual_vendor_parameter_label, 0, 0, 1, 1)
self.visual_vendor_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.visual_vendor_parameter_combobox.sizePolicy().hasHeightForWidth())
self.visual_vendor_parameter_combobox.setSizePolicy(sizePolicy)
self.visual_vendor_parameter_combobox.setObjectName("visual_vendor_parameter_combobox")
self.gridLayout.addWidget(self.visual_vendor_parameter_combobox, 0, 1, 1, 1)
self.visual_name_label = QtWidgets.QLabel(self.frame_2)
self.visual_name_label.setEnabled(True)
self.visual_name_label.setObjectName("visual_name_label")
self.gridLayout.addWidget(self.visual_name_label, 1, 0, 1, 1)
self.visual_name_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
self.visual_name_parameter_combobox.setEnabled(True)
self.visual_name_parameter_combobox.setEditable(True)
self.visual_name_parameter_combobox.setObjectName("visual_name_parameter_combobox")
self.gridLayout.addWidget(self.visual_name_parameter_combobox, 1, 1, 1, 1)
self.visual_metric_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_metric_parameter_label.setObjectName("visual_metric_parameter_label")
self.gridLayout.addWidget(self.visual_metric_parameter_label, 2, 0, 1, 1)
self.metric_Type_comboBox = QtWidgets.QComboBox(self.frame_2)
self.metric_Type_comboBox.setObjectName("metric_Type_comboBox")
self.gridLayout.addWidget(self.metric_Type_comboBox, 2, 1, 1, 1)
self.verticalLayout_2.addWidget(self.frame_2)
self.verticalLayout.addWidget(self.frame_15)
self.search_control_frame_2 = QtWidgets.QFrame(visual_tab) self.search_control_frame_2 = QtWidgets.QFrame(visual_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -351,9 +342,6 @@ class Ui_visual_tab(object):
self.search_start_year_parameter_dateedit_2.setDisplayFormat(_translate("visual_tab", "yyyy")) self.search_start_year_parameter_dateedit_2.setDisplayFormat(_translate("visual_tab", "yyyy"))
self.search_start_year_parameter_label_2.setText(_translate("visual_tab", "Start Year")) self.search_start_year_parameter_label_2.setText(_translate("visual_tab", "Start Year"))
self.search_end_year_parameter_dateedit_2.setDisplayFormat(_translate("visual_tab", "yyyy")) self.search_end_year_parameter_dateedit_2.setDisplayFormat(_translate("visual_tab", "yyyy"))
self.visual_name_label.setText(_translate("visual_tab", "Database"))
self.visual_metric_parameter_label.setText(_translate("visual_tab", "Metric Type "))
self.visual_vendor_parameter_label.setText(_translate("visual_tab", "Vendor"))
self.label_45.setText(_translate("visual_tab", "Select Chart Type")) self.label_45.setText(_translate("visual_tab", "Select Chart Type"))
self.radioButton_3.setText(_translate("visual_tab", "Vertical Bar")) self.radioButton_3.setText(_translate("visual_tab", "Vertical Bar"))
self.radioButton.setText(_translate("visual_tab", "Horizontal Bar")) self.radioButton.setText(_translate("visual_tab", "Horizontal Bar"))
@ -368,7 +356,11 @@ class Ui_visual_tab(object):
self.label_44.setText(_translate("visual_tab", "Vertical Axis Title")) self.label_44.setText(_translate("visual_tab", "Vertical Axis Title"))
self.label_43.setText(_translate("visual_tab", "Horizontal Axis Title")) self.label_43.setText(_translate("visual_tab", "Horizontal Axis Title"))
self.label_36.setText(_translate("visual_tab", "Chart Title")) self.label_36.setText(_translate("visual_tab", "Chart Title"))
self.visual_vendor_parameter_label.setText(_translate("visual_tab", "Vendor"))
self.visual_name_label.setText(_translate("visual_tab", "Database"))
self.visual_metric_parameter_label.setText(_translate("visual_tab", "Metric Type "))
self.open_folder_checkBox.setText(_translate("visual_tab", "Open Folder")) self.open_folder_checkBox.setText(_translate("visual_tab", "Open Folder"))
self.create_chart_button.setText(_translate("visual_tab", "Create Chart")) self.create_chart_button.setText(_translate("visual_tab", "Create Chart"))
self.open_file_checkBox.setText(_translate("visual_tab", "Open File")) self.open_file_checkBox.setText(_translate("visual_tab", "Open File"))
import Resources_rc import Resources_rc

362
ui/VisualTab.ui

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1177</width> <width>692</width>
<height>690</height> <height>488</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -18,25 +18,10 @@
<normaloff>:/ui/resources/tab_icons/visual_icon.png</normaloff>:/ui/resources/tab_icons/visual_icon.png</iconset> <normaloff>:/ui/resources/tab_icons/visual_icon.png</normaloff>:/ui/resources/tab_icons/visual_icon.png</iconset>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="search_parameters_frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
<item> <item>
<widget class="QFrame" name="search_initial_parameters_frame_2"> <widget class="QFrame" name="search_initial_parameters_frame_2">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -137,18 +122,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_14">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item> <item>
<widget class="QFrame" name="frame_15"> <widget class="QFrame" name="frame_15">
<property name="sizePolicy"> <property name="sizePolicy">
@ -163,108 +136,8 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout_13"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item row="5" column="0" colspan="3"> <item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="visual_name_label">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>50</x>
<y>80</y>
<width>97</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Database</string>
</property>
</widget>
<widget class="QLabel" name="visual_metric_parameter_label">
<property name="geometry">
<rect>
<x>50</x>
<y>130</y>
<width>213</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Metric Type </string>
</property>
</widget>
<widget class="QComboBox" name="metric_Type_comboBox">
<property name="geometry">
<rect>
<x>140</x>
<y>130</y>
<width>921</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="visual_vendor_parameter_label">
<property name="geometry">
<rect>
<x>50</x>
<y>30</y>
<width>61</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Vendor</string>
</property>
</widget>
<widget class="QComboBox" name="visual_vendor_parameter_combobox">
<property name="geometry">
<rect>
<x>140</x>
<y>30</y>
<width>921</width>
<height>26</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QComboBox" name="visual_name_parameter_combobox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>140</x>
<y>80</y>
<width>921</width>
<height>28</height>
</rect>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QFrame" name="frame"> <widget class="QFrame" name="frame">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -278,18 +151,12 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QFrame" name="frame_18"> <widget class="QFrame" name="frame_18">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>136</width>
<height>161</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -347,15 +214,9 @@
</item> </item>
</layout> </layout>
</widget> </widget>
</item>
<item>
<widget class="QFrame" name="frame_options"> <widget class="QFrame" name="frame_options">
<property name="geometry">
<rect>
<x>150</x>
<y>10</y>
<width>141</width>
<height>161</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -368,15 +229,9 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_46"> <widget class="QLabel" name="label_46">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>121</width>
<height>21</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -395,71 +250,43 @@
<enum>Qt::AutoText</enum> <enum>Qt::AutoText</enum>
</property> </property>
</widget> </widget>
</item>
<item>
<widget class="QRadioButton" name="monthly_radioButton"> <widget class="QRadioButton" name="monthly_radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>112</width>
<height>20</height>
</rect>
</property>
<property name="text"> <property name="text">
<string>Monthly</string> <string>Monthly</string>
</property> </property>
</widget> </widget>
</item>
<item>
<widget class="QRadioButton" name="yearly_radioButton"> <widget class="QRadioButton" name="yearly_radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>112</width>
<height>20</height>
</rect>
</property>
<property name="text"> <property name="text">
<string>Yearly</string> <string>Yearly</string>
</property> </property>
</widget> </widget>
</item>
<item>
<widget class="QRadioButton" name="topnum_radioButton"> <widget class="QRadioButton" name="topnum_radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>112</width>
<height>20</height>
</rect>
</property>
<property name="text"> <property name="text">
<string>Top #</string> <string>Top #</string>
</property> </property>
</widget> </widget>
</item>
<item>
<widget class="QRadioButton" name="costratio_radioButton"> <widget class="QRadioButton" name="costratio_radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>112</width>
<height>20</height>
</rect>
</property>
<property name="text"> <property name="text">
<string>Cost Ratio</string> <string>Cost Ratio</string>
</property> </property>
</widget> </widget>
</item>
</layout>
</widget> </widget>
</item>
<item>
<widget class="QFrame" name="option_frame"> <widget class="QFrame" name="option_frame">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="geometry">
<rect>
<x>293</x>
<y>10</y>
<width>151</width>
<height>161</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -472,15 +299,9 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QFrame" name="edit_cost_ratio_frame"> <widget class="QFrame" name="edit_cost_ratio_frame">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>131</width>
<height>81</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -493,15 +314,9 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_47"> <widget class="QLabel" name="label_47">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>183</width>
<height>15</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -520,26 +335,15 @@
<enum>Qt::AutoText</enum> <enum>Qt::AutoText</enum>
</property> </property>
</widget> </widget>
<widget class="QComboBox" name="cost_ratio_option_combobox"> </item>
<property name="geometry"> <item>
<rect> <widget class="QComboBox" name="cost_ratio_option_combobox"/>
<x>0</x> </item>
<y>30</y> </layout>
<width>121</width>
<height>26</height>
</rect>
</property>
</widget>
</widget> </widget>
</item>
<item>
<widget class="QFrame" name="edit_top_num_frame"> <widget class="QFrame" name="edit_top_num_frame">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>131</width>
<height>61</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -552,15 +356,9 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_48"> <widget class="QLabel" name="label_48">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>183</width>
<height>15</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -579,30 +377,22 @@
<enum>Qt::AutoText</enum> <enum>Qt::AutoText</enum>
</property> </property>
</widget> </widget>
</item>
<item>
<widget class="QSpinBox" name="top_num_spinbox"> <widget class="QSpinBox" name="top_num_spinbox">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>101</width>
<height>24</height>
</rect>
</property>
<property name="maximum"> <property name="maximum">
<number>999</number> <number>999</number>
</property> </property>
</widget> </widget>
</item>
</layout>
</widget> </widget>
</item>
</layout>
</widget> </widget>
</item>
<item>
<widget class="QFrame" name="frame_16"> <widget class="QFrame" name="frame_16">
<property name="geometry">
<rect>
<x>460</x>
<y>10</y>
<width>601</width>
<height>161</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -648,8 +438,72 @@
</item> </item>
</layout> </layout>
</widget> </widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="visual_vendor_parameter_label">
<property name="text">
<string>Vendor</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="visual_vendor_parameter_combobox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="visual_name_label">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Database</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="visual_name_parameter_combobox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="visual_metric_parameter_label">
<property name="text">
<string>Metric Type </string>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1">
<widget class="QComboBox" name="metric_Type_comboBox"/>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

1
vendor-lists/template-vendor-lists

@ -0,0 +1 @@
Two files provided here, each designed to be starting points for populating your vendors data. One includes only vendors known to be coounter 5 compliant, the other also includes vendors thought to be still only counter 4 compliant (for use with the Import Report function).

115
vendor-lists/vendors-template-R5-only.tsv

@ -0,0 +1,115 @@
name base_url customer_id requestor_id api_key platform is_non_sushi description companies
DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
Academy of Management https://journals.aom.org/reports REQUIRED False
American Chemical Society https://pubs.acs.org/reports REQUIRED False
Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
American Heart Association https://www.ahajournals.org/reports REQUIRED False
American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
Brepols Online https://www.brepolsonline.net/reports REQUIRED False
Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to Jan 2018
Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
FASEB https://www.fasebj.org/reports REQUIRED False
Future Medicine https://www.futuremedicine.com/reports REQUIRED False
Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
Guilford Press https://guilfordjournals.com/reports REQUIRED False
Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
Health Affairs https://www.healthaffairs.org/reports REQUIRED False
HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False "Requester ID, Customer ID and Api_Key are required. API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by ""|"", and then the portal password. For example,
API key: user@highwire.org|Us3rPW
Requester ID: user/email account registered with HighWire
Customer ID: user/email account registered with HighWire"
ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
Inderscience https://inderscienceonline.com/reports REQUIRED False
INFORMS https://pubsonline.informs.org/reports REQUIRED False
Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
Karger https://counter.karger.com/reports REQUIRED False
Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
Microbiology Society True C5 but not sushi yet as of March 2020
MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
Royal Society https://royalsocietypublishing.org/reports REQUIRED False
Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
UCLA Journals https://uclajournals.org/reports REQUIRED False
University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
World Bank https://elibrary.worldbank.org/reports REQUIRED False
World Scientific https://www.worldscientific.com/reports REQUIRED False
1 name base_url customer_id requestor_id api_key platform is_non_sushi description companies
2 DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
3 Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
4 Academy of Management https://journals.aom.org/reports REQUIRED False
5 American Chemical Society https://pubs.acs.org/reports REQUIRED False
6 Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
7 Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
8 Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
9 Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
10 Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
11 Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
12 American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
13 American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
14 American Heart Association https://www.ahajournals.org/reports REQUIRED False
15 American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
16 American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
17 American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
18 American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
19 American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
20 American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
21 American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
22 American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
23 American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
24 American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
25 American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
26 American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
27 American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
28 American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
29 American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
30 American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
31 Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
32 AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
33 APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
34 Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
35 BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
36 BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
37 Brepols Online https://www.brepolsonline.net/reports REQUIRED False
38 Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
39 British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
40 Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
41 Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
42 Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
43 CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
44 CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
45 DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
46 Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
47 Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
48 EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to Jan 2018
49 Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
50 Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
51 Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
52 Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
53 Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
54 FASEB https://www.fasebj.org/reports REQUIRED False
55 Future Medicine https://www.futuremedicine.com/reports REQUIRED False
56 Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
57 GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
58 Guilford Press https://guilfordjournals.com/reports REQUIRED False
59 Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
60 Health Affairs https://www.healthaffairs.org/reports REQUIRED False
61 HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False Requester ID, Customer ID and Api_Key are required. API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by "|", and then the portal password. For example, API key: user@highwire.org|Us3rPW Requester ID: user/email account registered with HighWire Customer ID: user/email account registered with HighWire
62 ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
63 IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
64 IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
65 Inderscience https://inderscienceonline.com/reports REQUIRED False
66 INFORMS https://pubsonline.informs.org/reports REQUIRED False
67 Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
68 Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
69 Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
70 Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
71 JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
72 Karger https://counter.karger.com/reports REQUIRED False
73 Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
74 Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
75 Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
76 MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
77 McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
78 MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
79 Microbiology Society True C5 but not sushi yet as of March 2020
80 MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
81 Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
82 NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
83 Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
84 NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
85 OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
86 Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
87 Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
88 Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
89 Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
90 Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
91 Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
92 Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
93 ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
94 ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
95 Royal Society https://royalsocietypublishing.org/reports REQUIRED False
96 Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
97 RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
98 SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
99 SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
100 Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
101 SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
102 Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
103 Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
104 Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
105 Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
106 UCLA Journals https://uclajournals.org/reports REQUIRED False
107 University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
108 University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
109 Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
110 Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
111 World Bank https://elibrary.worldbank.org/reports REQUIRED False
112 World Scientific https://www.worldscientific.com/reports REQUIRED False

183
vendor-lists/vendors-template-with-r4-vendors.tsv

@ -0,0 +1,183 @@
name base_url customer_id requestor_id api_key platform is_non_sushi description companies
AACCI (American Association of Cereal Chemists International) True BR2, JR5, JR1GOA, JR1, PR1, BR3
AAIDD (American Association of Intellectual and Developmental Disabilities) True JR5, JR1GOA, JR1, PR1, BR3
ABC-CLIO True Counter 4 only for import conversion; DB1
Academy of Management https://journals.aom.org/reports REQUIRED False
Accessible Archives True
ACM Digital Library (Association for Computing Machinery) True
American Chemical Society https://pubs.acs.org/reports REQUIRED False
ACSESS Digital Library (American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America (ASA, CSSA & SSSA)) True
Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
AIAA (American Institute of Aeronautics and Astronautics) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, JR1a, PR1, BR3
Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
American Heart Association https://www.ahajournals.org/reports REQUIRED False
American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
American Mental Health Counselors Association True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
American Podiatric Medical Association True Counter 4 only for import conversion; JR1, JR2, JR1GOA, JR5, BR3, PR1
American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
American Society of Tropical Medicine and Hygiene True
American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
AMSUS (The Society of Federal Health Professionals) True Counter 4 only for import conversion; JR5, JR1, PR1
Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
APA PsycNET True
APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
APS (American Phytopathological Society) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
ASA (American Statistical Association) True Counter 4 only for import conversion; JR1, DB1
ASM (American Society for Microbiology) True Counter 4 only for import conversion; BR2, JR1GOA, JR1, PR1, BR3
Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
BioMed Central True Counter 4 only for import conversion; JR5, JR1GOA, JR1
BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
Bone & Joint Publishing True
Brepols Online https://www.brepolsonline.net/reports REQUIRED False
Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
Britannica True
British Institute of Radiology True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
Canadian Science Publishing True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
CFA Publications True Counter 4 only for import conversion; JR5, JR1, PR1
Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
Corrosion (The Journal of Science & Engineering) True Counter 4 only for import conversion; JR5, JR1GOA, JR1
CRCnetBase (CRC netBase) True Counter 4 only for import conversion; BR2, PR1, BR3
CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to 2018
Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
EDP Sciences (Astronomy and Astrophysics) True
Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
EMS (European Mathematical Society) True Counter 4 only for import conversion; JR1:R3
Endocrine Society Journals True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, JR1a, BR3
Families in Society True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
FASEB https://www.fasebj.org/reports REQUIRED False
Future Medicine https://www.futuremedicine.com/reports REQUIRED False
Future Science True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
Guilford Press https://guilfordjournals.com/reports REQUIRED False
Hanser True Counter 4 only for import conversion; BR2, JR5, JR1, PR1, BR3
Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
Health Affairs https://www.healthaffairs.org/reports REQUIRED False
HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False "API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by ""|"", and then the portal password. For example,
API key: user@highwire.org|Us3rPW
Requester ID: user/email account registered with HighWire
Customer ID: user/email account registered with HighWire"
Hogrefe True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Human Kinetics True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
Idunn True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
IET (Institution of Engineering and Technology) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, PR1, BR3
IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
IMF (International Monetary Fund) True Counter 4 only for import conversion; DB1
INA (Irish Newspaper Archives) True
Inderscience https://inderscienceonline.com/reports REQUIRED False
Informit True Counter 4 only for import conversion; BR2, JR5, JR1, BR1
INFORMS https://pubsonline.informs.org/reports REQUIRED False
Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
IOS Press - CAB Journals & eBooks True
IOS Press (formerly MetaPress) True Counter 4 only for import conversion; BR2, JR1, BR1, DB1, PR1, BR3
John Benjamins True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Journal of Clinical Psychiatry True
Journal of Coastal research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Journal of Graduate Medical Education True Counter 4 only for import conversion; JR1
Journal of Marketing Research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
Journal of Oral Implantology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
Journal of Parasitology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Journal of Periodontology Online True Counter 4 only for import conversion; JR5, JR1, PR1
Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
Journal of the Physical Society of Japan True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
Karger https://counter.karger.com/reports REQUIRED False
Kluwer Law International True
Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
Microbiology Society True Counter 4 only for import conversion; C5 but not sushi yet as of March 2020
Military Medicine True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
MLA (Modern Language Association) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
OSA InfoBase (Optics InfoBase) True
Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
Physicians Postgraduate Press True
Practical Action Publishing True Counter 4 only for import conversion; JR1, PR1, JR2, BR2, BR3
Professional School Counseling True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
Psychiatry Online True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, JR1a, PR1, BR3
Radiation Research True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
RCN (Royal College of Nursing) True
Royal College of Surgeons of England True Counter 4 only for import conversion; JR1, PR1
Royal Society https://royalsocietypublishing.org/reports REQUIRED False
Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
Science Societies True
Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
SEG (Society of Exploration Geophysicists) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
SFAA (Society for Applied Anthropology) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
SPIE (Society of Photo-Optical Instrumentation Engineers) True
Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
The Cleft Palate - Craniofacial Journal True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Thieme Planta Medica True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Transportation Research Board True Counter 4 only for import conversion; JR5, JR1, PR1, BR3
UCLA Journals https://uclajournals.org/reports REQUIRED False
University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
University of Texas Press True Counter 4 only for import conversion; JR1
University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
UNWTO (United Nations World Tourism Organization) True Counter 4 only for import conversion; BR2, JR5, JR1, PR1
Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
Wageningen Academic Publishers True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
World Bank https://elibrary.worldbank.org/reports REQUIRED False
World Scientific https://www.worldscientific.com/reports REQUIRED False
1 name base_url customer_id requestor_id api_key platform is_non_sushi description companies
2 AACCI (American Association of Cereal Chemists International) True BR2, JR5, JR1GOA, JR1, PR1, BR3
3 AAIDD (American Association of Intellectual and Developmental Disabilities) True JR5, JR1GOA, JR1, PR1, BR3
4 ABC-CLIO True Counter 4 only for import conversion; DB1
5 Academy of Management https://journals.aom.org/reports REQUIRED False
6 Accessible Archives True
7 ACM Digital Library (Association for Computing Machinery) True
8 American Chemical Society https://pubs.acs.org/reports REQUIRED False
9 ACSESS Digital Library (American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America (ASA, CSSA & SSSA)) True
10 Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
11 AIAA (American Institute of Aeronautics and Astronautics) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, JR1a, PR1, BR3
12 Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
13 Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
14 Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
15 Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
16 Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
17 American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
18 American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
19 American Heart Association https://www.ahajournals.org/reports REQUIRED False
20 American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
21 American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
22 American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
23 American Mental Health Counselors Association True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
24 American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
25 American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
26 American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
27 American Podiatric Medical Association True Counter 4 only for import conversion; JR1, JR2, JR1GOA, JR5, BR3, PR1
28 American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
29 American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
30 American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
31 American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
32 American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
33 American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
34 American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
35 American Society of Tropical Medicine and Hygiene True
36 American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
37 American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
38 American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
39 AMSUS (The Society of Federal Health Professionals) True Counter 4 only for import conversion; JR5, JR1, PR1
40 Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
41 AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
42 APA PsycNET True
43 APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
44 APS (American Phytopathological Society) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
45 ASA (American Statistical Association) True Counter 4 only for import conversion; JR1, DB1
46 ASM (American Society for Microbiology) True Counter 4 only for import conversion; BR2, JR1GOA, JR1, PR1, BR3
47 Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
48 BioMed Central True Counter 4 only for import conversion; JR5, JR1GOA, JR1
49 BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
50 BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
51 Bone & Joint Publishing True
52 Brepols Online https://www.brepolsonline.net/reports REQUIRED False
53 Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
54 Britannica True
55 British Institute of Radiology True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
56 British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
57 Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
58 Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
59 Canadian Science Publishing True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
60 CFA Publications True Counter 4 only for import conversion; JR5, JR1, PR1
61 Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
62 Corrosion (The Journal of Science & Engineering) True Counter 4 only for import conversion; JR5, JR1GOA, JR1
63 CRCnetBase (CRC netBase) True Counter 4 only for import conversion; BR2, PR1, BR3
64 CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
65 CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
66 DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
67 DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
68 Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
69 Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
70 EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to 2018
71 Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
72 EDP Sciences (Astronomy and Astrophysics) True
73 Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
74 Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
75 Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
76 Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
77 Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
78 EMS (European Mathematical Society) True Counter 4 only for import conversion; JR1:R3
79 Endocrine Society Journals True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, JR1a, BR3
80 Families in Society True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
81 FASEB https://www.fasebj.org/reports REQUIRED False
82 Future Medicine https://www.futuremedicine.com/reports REQUIRED False
83 Future Science True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
84 Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
85 GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
86 Guilford Press https://guilfordjournals.com/reports REQUIRED False
87 Hanser True Counter 4 only for import conversion; BR2, JR5, JR1, PR1, BR3
88 Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
89 Health Affairs https://www.healthaffairs.org/reports REQUIRED False
90 HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by "|", and then the portal password. For example, API key: user@highwire.org|Us3rPW Requester ID: user/email account registered with HighWire Customer ID: user/email account registered with HighWire
91 Hogrefe True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
92 Human Kinetics True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
93 ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
94 Idunn True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
95 IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
96 IET (Institution of Engineering and Technology) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, PR1, BR3
97 IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
98 IMF (International Monetary Fund) True Counter 4 only for import conversion; DB1
99 INA (Irish Newspaper Archives) True
100 Inderscience https://inderscienceonline.com/reports REQUIRED False
101 Informit True Counter 4 only for import conversion; BR2, JR5, JR1, BR1
102 INFORMS https://pubsonline.informs.org/reports REQUIRED False
103 Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
104 IOS Press - CAB Journals & eBooks True
105 IOS Press (formerly MetaPress) True Counter 4 only for import conversion; BR2, JR1, BR1, DB1, PR1, BR3
106 John Benjamins True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
107 Journal of Clinical Psychiatry True
108 Journal of Coastal research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
109 Journal of Graduate Medical Education True Counter 4 only for import conversion; JR1
110 Journal of Marketing Research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
111 Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
112 Journal of Oral Implantology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
113 Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
114 Journal of Parasitology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
115 Journal of Periodontology Online True Counter 4 only for import conversion; JR5, JR1, PR1
116 Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
117 Journal of the Physical Society of Japan True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
118 JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
119 Karger https://counter.karger.com/reports REQUIRED False
120 Kluwer Law International True
121 Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
122 Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
123 Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
124 MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
125 McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
126 MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
127 Microbiology Society True Counter 4 only for import conversion; C5 but not sushi yet as of March 2020
128 Military Medicine True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
129 MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
130 MLA (Modern Language Association) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
131 Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
132 NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
133 Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
134 NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
135 OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
136 OSA InfoBase (Optics InfoBase) True
137 Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
138 Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
139 Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
140 Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
141 Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
142 Physicians Postgraduate Press True
143 Practical Action Publishing True Counter 4 only for import conversion; JR1, PR1, JR2, BR2, BR3
144 Professional School Counseling True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
145 Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
146 Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
147 ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
148 ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
149 Psychiatry Online True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, JR1a, PR1, BR3
150 Radiation Research True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
151 RCN (Royal College of Nursing) True
152 Royal College of Surgeons of England True Counter 4 only for import conversion; JR1, PR1
153 Royal Society https://royalsocietypublishing.org/reports REQUIRED False
154 Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
155 RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
156 SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
157 SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
158 Science Societies True
159 Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
160 SEG (Society of Exploration Geophysicists) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
161 SFAA (Society for Applied Anthropology) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
162 SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
163 Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
164 SPIE (Society of Photo-Optical Instrumentation Engineers) True
165 Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
166 Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
167 Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
168 The Cleft Palate - Craniofacial Journal True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
169 Thieme Planta Medica True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
170 Transportation Research Board True Counter 4 only for import conversion; JR5, JR1, PR1, BR3
171 UCLA Journals https://uclajournals.org/reports REQUIRED False
172 University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
173 University of Texas Press True Counter 4 only for import conversion; JR1
174 University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
175 UNWTO (United Nations World Tourism Organization) True Counter 4 only for import conversion; BR2, JR5, JR1, PR1
176 Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
177 Wageningen Academic Publishers True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
178 Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
179 World Bank https://elibrary.worldbank.org/reports REQUIRED False
180 World Scientific https://www.worldscientific.com/reports REQUIRED False
Loading…
Cancel
Save