Initial commit: Vendor Sales Report Magento 2 module

This commit is contained in:
shopkeeperdev
2025-11-03 17:20:07 -05:00
commit fc2838d68a
25 changed files with 1839 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
<!--@subject {{var subject}} @-->
<!--@vars
{"var subject":"Email Subject"}
@-->
{{template config_path="design/email/header_template"}}
<table>
<tr class="email-intro">
<td>
<p class="greeting">Hello,</p>
<p>
Please find attached the monthly vendor sales report for {{var month}} {{var year}}.
</p>
<p>
This report contains all completed orders for the specified period.
</p>
</td>
</tr>
</table>
{{template config_path="design/email/footer_template"}}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="Shopkeeper_VendorSalesReport::css/vendor-report.css"/>
</head>
<update handle="styles"/>
<body>
<referenceContainer name="content">
<block class="Shopkeeper\VendorSalesReport\Block\Adminhtml\Report" name="vendorsalesreport.report" template="Shopkeeper_VendorSalesReport::report/view.phtml"/>
</referenceContainer>
</body>
</page>

View File

@@ -0,0 +1,299 @@
<?php
/**
* @var $block \Shopkeeper\VendorSalesReport\Block\Adminhtml\Report
*/
?>
<style>
/* Fix icon display - more aggressive targeting */
.item-vendorsalesreport > a:before,
#menu-magento-reports-report .item-vendorsalesreport > a:before,
a[href*="vendorsalesreport"]:before {
content: '' !important;
display: none !important;
width: 0 !important;
height: 0 !important;
}
/* Fix date range layout - align fields properly */
.date-range-wrapper {
display: flex;
gap: 20px;
align-items: flex-end;
}
.date-range-wrapper .admin__field {
flex: 0 0 250px;
margin-right: 20px;
}
.date-range-wrapper .admin__field-label {
margin-bottom: 5px;
}
.date-range-wrapper .field-date {
margin-bottom: 0;
}
/* Report grid styling */
#report_grid {
width: 100%;
border-collapse: collapse;
}
#report_grid th,
#report_grid td {
padding: 10px 8px;
text-align: left;
border: 1px solid #ccc;
}
#report_grid th {
background-color: #333;
color: #fff;
font-weight: 600;
border-color: #666;
}
#report_grid tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
#report_grid tbody tr:hover {
background-color: #f0f0f0;
}
.admin__page-section-title-note {
margin-left: 10px;
font-size: 0.9em;
color: #666;
}
</style>
<div class="admin__page-section">
<div class="admin__page-section-title">
<span class="title"><?= $block->escapeHtml(__('Vendor Sales Report Generator')) ?></span>
</div>
<div class="admin__page-section-content">
<div class="admin__fieldset">
<div class="admin__field">
<div class="admin__field-label">
<label><?= $block->escapeHtml(__('Date Range')) ?></label>
</div>
<div class="admin__field-control">
<div class="date-range-wrapper">
<div class="admin__field _required field-date">
<div class="admin__field-label">
<label>
<span><?= $block->escapeHtml(__('From')) ?></span>
</label>
</div>
<div class="admin__field-control">
<input type="text"
id="start_date"
name="start_date"
class="admin__control-text"
value="<?= $block->escapeHtmlAttr($block->getDefaultStartDate()) ?>"
data-mage-init='{"calendar": {"dateFormat": "yy-mm-dd"}}'/>
</div>
</div>
<div class="admin__field _required field-date">
<div class="admin__field-label">
<label>
<span><?= $block->escapeHtml(__('To')) ?></span>
</label>
</div>
<div class="admin__field-control">
<input type="text"
id="end_date"
name="end_date"
class="admin__control-text"
value="<?= $block->escapeHtmlAttr($block->getDefaultEndDate()) ?>"
data-mage-init='{"calendar": {"dateFormat": "yy-mm-dd"}}'/>
</div>
</div>
</div>
</div>
</div>
<div class="admin__field">
<div class="admin__field-label">
<label><?= $block->escapeHtml(__('Order Status Filter')) ?></label>
</div>
<div class="admin__field-control">
<div class="admin__field-note">
<span><?= $block->escapeHtml(__('Currently configured to include: %1', implode(', ', $block->getOrderStatuses()))) ?></span>
<br/>
<span><?= $block->escapeHtml(__('To change this, go to: Stores > Configuration > Shopkeeper > Vendor Sales Report')) ?></span>
</div>
</div>
</div>
<div class="admin__field">
<div class="admin__field-control">
<button id="preview_report"
type="button"
class="action-default scalable primary"
style="margin-right: 10px;">
<span><?= $block->escapeHtml(__('Preview Report')) ?></span>
</button>
<button id="export_report"
type="button"
class="action-default scalable">
<span><?= $block->escapeHtml(__('Export CSV')) ?></span>
</button>
</div>
</div>
</div>
</div>
</div>
<div id="report_preview" class="admin__page-section" style="display: none; margin-top: 20px;">
<div class="admin__page-section-title">
<span class="title"><?= $block->escapeHtml(__('Report Preview')) ?></span>
<span id="record_count" class="admin__page-section-title-note"></span>
</div>
<div class="admin__page-section-content">
<div class="admin__data-grid-wrap">
<table class="data-grid" id="report_grid">
<thead>
<tr>
<th><?= $block->escapeHtml(__('Date')) ?></th>
<th><?= $block->escapeHtml(__('Vendor Product #')) ?></th>
<th><?= $block->escapeHtml(__('Description')) ?></th>
<th><?= $block->escapeHtml(__('Dealer Product #')) ?></th>
<th><?= $block->escapeHtml(__('Country')) ?></th>
<th><?= $block->escapeHtml(__('City')) ?></th>
<th><?= $block->escapeHtml(__('State')) ?></th>
<th><?= $block->escapeHtml(__('Zip Code')) ?></th>
<th><?= $block->escapeHtml(__('Quantity')) ?></th>
<th><?= $block->escapeHtml(__('Cost')) ?></th>
<th><?= $block->escapeHtml(__('Order Status')) ?></th>
</tr>
</thead>
<tbody id="report_tbody">
</tbody>
</table>
</div>
</div>
</div>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"vendorReportApp": {
"component": "Shopkeeper_VendorSalesReport/js/report"
}
}
}
}
}
</script>
<script>
require(['jquery', 'Magento_Ui/js/modal/alert', 'loader'], function($, alert) {
$(document).ready(function() {
var gridUrl = '<?= $block->escapeJs($block->escapeUrl($block->getGridUrl())) ?>';
var exportUrl = '<?= $block->escapeJs($block->escapeUrl($block->getExportUrl())) ?>';
$('#preview_report').on('click', function() {
var startDate = $('#start_date').val();
var endDate = $('#end_date').val();
if (!startDate || !endDate) {
alert({
content: '<?= $block->escapeJs(__('Please select a date range.')) ?>'
});
return;
}
$('body').trigger('processStart');
$.ajax({
url: gridUrl,
type: 'POST',
data: {
start_date: startDate,
end_date: endDate,
form_key: FORM_KEY
},
dataType: 'json',
success: function(response) {
$('body').trigger('processStop');
if (response.success) {
var tbody = $('#report_tbody');
tbody.empty();
if (response.data.length === 0) {
tbody.append('<tr><td colspan="11" style="text-align: center;"><?= $block->escapeJs(__('No data found for the selected date range.')) ?></td></tr>');
$('#record_count').text('');
} else {
$.each(response.data, function(index, row) {
var tr = $('<tr>');
tr.append($('<td>').text(row.Date));
tr.append($('<td>').text(row['Vendor Product number']));
tr.append($('<td>').text(row.Description));
tr.append($('<td>').text(row['Dealer product number']));
tr.append($('<td>').text(row.Country));
tr.append($('<td>').text(row.City));
tr.append($('<td>').text(row.State));
tr.append($('<td>').text(row['Zip code']));
tr.append($('<td>').text(row.Quantity));
tr.append($('<td>').text('$' + parseFloat(row.Cost).toFixed(2)));
tr.append($('<td>').text(row['Order Status']));
tbody.append(tr);
});
$('#record_count').text('(' + response.total + ' records)');
}
$('#report_preview').show();
} else {
alert({
content: response.message || '<?= $block->escapeJs(__('An error occurred while loading the report.')) ?>'
});
}
},
error: function() {
$('body').trigger('processStop');
alert({
content: '<?= $block->escapeJs(__('An error occurred while loading the report.')) ?>'
});
}
});
});
$('#export_report').on('click', function() {
var startDate = $('#start_date').val();
var endDate = $('#end_date').val();
if (!startDate || !endDate) {
alert({
content: '<?= $block->escapeJs(__('Please select a date range.')) ?>'
});
return;
}
var form = $('<form>', {
'method': 'POST',
'action': exportUrl
});
form.append($('<input>', {
'type': 'hidden',
'name': 'start_date',
'value': startDate
}));
form.append($('<input>', {
'type': 'hidden',
'name': 'end_date',
'value': endDate
}));
form.append($('<input>', {
'type': 'hidden',
'name': 'form_key',
'value': FORM_KEY
}));
$('body').append(form);
form.submit();
form.remove();
});
});
});
</script>

View File

@@ -0,0 +1,15 @@
/* Vendor Sales Report Menu - Remove icon */
.item-vendorsalesreport > a:before {
display: none !important;
}
/* Additional targeting for stubborn icons */
#menu-magento-reports-report .item-vendorsalesreport > a:before,
.admin__menu .item-vendorsalesreport > a:before {
content: none !important;
display: none !important;
width: 0 !important;
height: 0 !important;
margin: 0 !important;
padding: 0 !important;
}