sale margin report export excel print
This commit is contained in:
parent
0aeb0132cc
commit
4b90321123
|
|
@ -1 +1,2 @@
|
||||||
|
from . import controllers
|
||||||
from . import models
|
from . import models
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
from . import sale_margin_excel
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import xlsxwriter
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
class SaleMarginController(http.Controller):
|
||||||
|
|
||||||
|
@http.route('/sale_margin/report_excel', type='http', auth='user', methods=['POST'], csrf=False)
|
||||||
|
def report_excel(self, **post):
|
||||||
|
try:
|
||||||
|
# Safely get JSON data from the POST body
|
||||||
|
data = json.loads(request.httprequest.data) or {}
|
||||||
|
col_model = data.get('colModel')
|
||||||
|
grid_data = data.get('gridData')
|
||||||
|
|
||||||
|
if not col_model or not grid_data:
|
||||||
|
return request.make_response('Missing data', [('Content-Type', 'text/plain')])
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# 1️⃣ Create Excel in memory
|
||||||
|
# ---------------------------------------------
|
||||||
|
output = io.BytesIO()
|
||||||
|
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
|
||||||
|
worksheet = workbook.add_worksheet('Sale Margin Report')
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# 2️⃣ Define Excel formats
|
||||||
|
# ---------------------------------------------
|
||||||
|
title_fmt = workbook.add_format({
|
||||||
|
'bold': True, 'font_size': 16, 'font_color': 'white',
|
||||||
|
'align': 'center', 'valign': 'vcenter',
|
||||||
|
'bg_color': '#4F81BD', 'border': 1
|
||||||
|
})
|
||||||
|
header_fmt = workbook.add_format({
|
||||||
|
'bold': True, 'font_size': 11, 'font_color': 'white',
|
||||||
|
'align': 'center', 'valign': 'vcenter',
|
||||||
|
'bg_color': '#366092', 'border': 1
|
||||||
|
})
|
||||||
|
text_fmt = workbook.add_format({
|
||||||
|
'font_size': 10, 'align': 'left', 'valign': 'vcenter', 'border': 1
|
||||||
|
})
|
||||||
|
float_fmt = workbook.add_format({
|
||||||
|
'font_size': 10, 'align': 'right', 'valign': 'vcenter',
|
||||||
|
'border': 1, 'num_format': '#,##0.00'
|
||||||
|
})
|
||||||
|
group_fmt = workbook.add_format({
|
||||||
|
'bold': True, 'font_size': 11, 'align': 'left',
|
||||||
|
'bg_color': '#DCE6F1', 'border': 1
|
||||||
|
})
|
||||||
|
subtotal_fmt = workbook.add_format({
|
||||||
|
'bold': True, 'font_size': 10, 'align': 'right',
|
||||||
|
'bg_color': '#EAF1DD', 'border': 1, 'num_format': '#,##0.00'
|
||||||
|
})
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# 3️⃣ Title and headers
|
||||||
|
# ---------------------------------------------
|
||||||
|
visible_cols = [c for c in col_model if not c.get('hidden')]
|
||||||
|
visible_cols.pop(-1)
|
||||||
|
last_col = len(visible_cols) - 1
|
||||||
|
|
||||||
|
worksheet.merge_range(0, 0, 0, last_col, 'SALE MARGIN REPORT', title_fmt)
|
||||||
|
|
||||||
|
for col_idx, col in enumerate(visible_cols):
|
||||||
|
worksheet.write(1, col_idx, col.get('title', col.get('dataIndx', '')), header_fmt)
|
||||||
|
worksheet.set_column(col_idx, col_idx, 15)
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# 4️⃣ Group data by "tag"
|
||||||
|
# ---------------------------------------------
|
||||||
|
group_field = 'tags' # <-- adjust if your grouping field has a different key name
|
||||||
|
grouped = {}
|
||||||
|
for row in grid_data:
|
||||||
|
group_key = row.get(group_field, 'Ungrouped')
|
||||||
|
grouped.setdefault(group_key, []).append(row)
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# 5️⃣ Write grouped data + subtotal per group
|
||||||
|
# ---------------------------------------------
|
||||||
|
row_pos = 2
|
||||||
|
for group_name, rows in grouped.items():
|
||||||
|
# Group header
|
||||||
|
worksheet.merge_range(row_pos, 0, row_pos, last_col, f'Group: {group_name}', group_fmt)
|
||||||
|
row_pos += 1
|
||||||
|
|
||||||
|
# Track totals per numeric column
|
||||||
|
group_sums = [0.0] * len(visible_cols)
|
||||||
|
|
||||||
|
# Track margin_percent separately
|
||||||
|
margin_sum = 0
|
||||||
|
margin_count = 0
|
||||||
|
margin_idx = None
|
||||||
|
|
||||||
|
# Find index of margin_percent column
|
||||||
|
for idx, col in enumerate(visible_cols):
|
||||||
|
if col.get('dataIndx') == 'margin_percent':
|
||||||
|
margin_idx = idx
|
||||||
|
break
|
||||||
|
|
||||||
|
# Write group rows
|
||||||
|
for row_data in rows:
|
||||||
|
for col_idx, col in enumerate(visible_cols):
|
||||||
|
key = col.get('dataIndx')
|
||||||
|
val = row_data.get(key, '')
|
||||||
|
|
||||||
|
if isinstance(val, (int, float)):
|
||||||
|
if key == 'margin_percent':
|
||||||
|
margin_sum += val
|
||||||
|
margin_count += 1
|
||||||
|
worksheet.write_number(row_pos, col_idx, val, float_fmt)
|
||||||
|
else:
|
||||||
|
worksheet.write_number(row_pos, col_idx, val, float_fmt)
|
||||||
|
group_sums[col_idx] += val
|
||||||
|
else:
|
||||||
|
worksheet.write(row_pos, col_idx, str(val), text_fmt)
|
||||||
|
row_pos += 1
|
||||||
|
|
||||||
|
# Subtotal line
|
||||||
|
worksheet.write(row_pos, 0, f'{group_name} Total', subtotal_fmt)
|
||||||
|
for col_idx, total in enumerate(group_sums):
|
||||||
|
if col_idx > 0 and total != 0:
|
||||||
|
worksheet.write_number(row_pos, col_idx, total, subtotal_fmt)
|
||||||
|
|
||||||
|
# Write margin_percent average
|
||||||
|
if margin_idx is not None and margin_count > 0:
|
||||||
|
margin_avg = margin_sum / margin_count
|
||||||
|
worksheet.write_number(row_pos, margin_idx, margin_avg, subtotal_fmt)
|
||||||
|
|
||||||
|
row_pos += 2 # leave a blank line after subtotal
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Finalize and return file
|
||||||
|
# ---------------------------------------------
|
||||||
|
workbook.close()
|
||||||
|
output.seek(0)
|
||||||
|
filecontent = output.read()
|
||||||
|
|
||||||
|
headers = [
|
||||||
|
('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
|
||||||
|
('Content-Disposition', 'attachment; filename="Sale_Margin_Report.xlsx"'),
|
||||||
|
]
|
||||||
|
return request.make_response(filecontent, headers=headers)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return request.make_response(f"Error: {str(e)}", [('Content-Type', 'text/plain')])
|
||||||
|
|
@ -2,6 +2,7 @@ from odoo import models, fields, api, _
|
||||||
from odoo.exceptions import UserError, ValidationError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
import pytz
|
||||||
|
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
|
|
@ -12,8 +13,22 @@ class SamashtiDashboard(models.AbstractModel):
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def get_stock_moves_data(self, from_date,to_date):
|
def get_stock_moves_data(self, from_date,to_date):
|
||||||
fromDate = "'"+str(from_date)+" 00:00:00'"
|
from_date_obj = datetime.strptime(from_date, '%Y-%m-%d').date()
|
||||||
toDate = "'"+str(to_date)+" 23:59:59'"
|
to_date_obj = datetime.strptime(to_date, '%Y-%m-%d').date()
|
||||||
|
|
||||||
|
# Get user's timezone
|
||||||
|
user_tz = self.env.user.tz or 'UTC'
|
||||||
|
local_tz = pytz.timezone(user_tz)
|
||||||
|
|
||||||
|
# Convert local datetime to UTC
|
||||||
|
from_local = local_tz.localize(datetime.combine(from_date_obj, time.min))
|
||||||
|
to_local = local_tz.localize(datetime.combine(to_date_obj, time.max))
|
||||||
|
from_utc = from_local.astimezone(pytz.UTC)
|
||||||
|
to_utc = to_local.astimezone(pytz.UTC)
|
||||||
|
|
||||||
|
# Convert to string in Odoo datetime format
|
||||||
|
fromDate = "'"+str(fields.Datetime.to_string(from_utc))+"'"
|
||||||
|
toDate = "'"+str(fields.Datetime.to_string(to_utc))+"'"
|
||||||
|
|
||||||
sql = f"""
|
sql = f"""
|
||||||
SELECT
|
SELECT
|
||||||
|
|
@ -126,97 +141,86 @@ class SamashtiDashboard(models.AbstractModel):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def get_sale_margin_data(self,from_date,to_date):
|
def get_sale_margin_data(self, from_date, to_date):
|
||||||
fromDate = "'"+str(from_date)+" 00:00:00'"
|
# Get user's timezone
|
||||||
toDate = "'"+str(to_date)+" 23:59:59'"
|
from_date_obj = datetime.strptime(from_date, '%Y-%m-%d').date()
|
||||||
datas = []
|
to_date_obj = datetime.strptime(to_date, '%Y-%m-%d').date()
|
||||||
|
|
||||||
|
# Get user's timezone
|
||||||
|
user_tz = self.env.user.tz or 'UTC'
|
||||||
|
local_tz = pytz.timezone(user_tz)
|
||||||
|
|
||||||
|
# Convert local datetime to UTC
|
||||||
|
from_local = local_tz.localize(datetime.combine(from_date_obj, time.min))
|
||||||
|
to_local = local_tz.localize(datetime.combine(to_date_obj, time.max))
|
||||||
|
from_utc = from_local.astimezone(pytz.UTC)
|
||||||
|
to_utc = to_local.astimezone(pytz.UTC)
|
||||||
|
|
||||||
|
# Convert to string in Odoo datetime format
|
||||||
|
from_datetime = fields.Datetime.to_string(from_utc)
|
||||||
|
to_datetime = fields.Datetime.to_string(to_utc)
|
||||||
|
# Search for posted invoices within the date range
|
||||||
|
invoice_ids = self.env['account.move'].search([
|
||||||
|
('state', '=', 'posted'),
|
||||||
|
('invoice_date', '>=', from_datetime),
|
||||||
|
('invoice_date', '<=', to_datetime)
|
||||||
|
])
|
||||||
|
# Read sale orders linked to those invoices
|
||||||
sale_orders = self.env['sale.order'].search_read(
|
sale_orders = self.env['sale.order'].search_read(
|
||||||
[
|
[
|
||||||
('state', '=', 'sale'),
|
('state', '=', 'sale'),
|
||||||
('date_order', '>=', fromDate),
|
('invoice_ids', 'in', invoice_ids.ids)
|
||||||
('date_order', '<=', toDate)
|
|
||||||
],
|
],
|
||||||
['id', 'name', 'amount_untaxed', 'partner_id', 'total_production_cost','date_order']
|
[
|
||||||
|
'id', 'name', 'amount_untaxed', 'partner_id',
|
||||||
|
'total_production_cost', 'date_order', 'order_line'
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
for r in sale_orders:
|
datas = []
|
||||||
cost = r['total_production_cost']
|
|
||||||
sale_price = r['amount_untaxed']
|
for order_data in sale_orders:
|
||||||
|
order = self.env['sale.order'].browse(order_data['id'])
|
||||||
|
|
||||||
|
cost = order_data['total_production_cost'] or 0.0
|
||||||
|
sale_price = order_data['amount_untaxed'] or 0.0
|
||||||
margin = sale_price - cost
|
margin = sale_price - cost
|
||||||
margin_percent = (margin / sale_price * 100) if sale_price else 0.0
|
margin_percent = (margin / sale_price * 100) if sale_price else 0.0
|
||||||
customer = r['partner_id'][-1]
|
|
||||||
quantity = sum(self.env['sale.order'].browse(r['id']).order_line.mapped('product_uom_qty'))
|
customer = order_data['partner_id'][-1] if order_data['partner_id'] else "Unknown"
|
||||||
weight = str(sum(self.env['sale.order'].browse(r['id']).order_line.mapped('bag_weight')))+" kg"
|
quantity = sum(order.order_line.mapped('product_uom_qty'))
|
||||||
date = self.env['sale.order'].browse(r['id']).invoice_ids.invoice_date
|
weight = f"{sum(order.order_line.mapped('bag_weight'))} kg"
|
||||||
invoice = self.env['sale.order'].browse(r['id']).invoice_ids.name
|
|
||||||
|
# Combine product tags
|
||||||
|
product_tags = ', '.join(
|
||||||
|
tag.name for tag in order.order_line.mapped('product_id.all_product_tag_ids')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Combine invoice names and dates
|
||||||
|
if order.invoice_ids:
|
||||||
|
invoice = ', '.join(inv.name for inv in order.invoice_ids)
|
||||||
|
date = ', '.join(str(inv.invoice_date) for inv in order.invoice_ids if inv.invoice_date)
|
||||||
|
else:
|
||||||
|
invoice = "N/A"
|
||||||
|
date = "No invoices"
|
||||||
|
|
||||||
datas.append({
|
datas.append({
|
||||||
'sale_order': r['name'],
|
'sale_order': order_data['name'],
|
||||||
'id':r['id'],
|
'id': order_data['id'],
|
||||||
'weight':weight,
|
'weight': weight,
|
||||||
'invoice':invoice,
|
'tags': product_tags,
|
||||||
'customer':customer,
|
'invoice': invoice,
|
||||||
'quantity':quantity,
|
'customer': customer,
|
||||||
|
'quantity': quantity,
|
||||||
'cost': cost,
|
'cost': cost,
|
||||||
'date':date,
|
'date': date,
|
||||||
'sale_price': sale_price,
|
'sale_price': sale_price,
|
||||||
'margin': margin,
|
'margin': margin,
|
||||||
'margin_percent':margin_percent
|
'margin_percent': margin_percent,
|
||||||
})
|
})
|
||||||
|
|
||||||
return datas
|
return datas
|
||||||
|
|
||||||
where_caluse = f" AND so.date_order BETWEEN {fromDate} AND {toDate}"
|
|
||||||
sql = """
|
|
||||||
SELECT
|
|
||||||
so.name AS sale_order,
|
|
||||||
COALESCE(pp.default_code, '') AS product_code,
|
|
||||||
'[' || (COALESCE(pp.default_code, '') || '] ' || jsonb_extract_path_text(pt.name, rp.lang)) AS product_name,
|
|
||||||
pc.complete_name AS category,
|
|
||||||
sl.product_uom_qty AS quantity,
|
|
||||||
COALESCE(sl.unit_prod_cost, 1) AS unit_cost,
|
|
||||||
COALESCE(sl.price_unit, 1) AS unit_sale_price,
|
|
||||||
ABS(COALESCE(sl.unit_prod_cost, 1) - COALESCE(sl.price_unit, 1)) AS margin,
|
|
||||||
sl.product_uom_qty * COALESCE(sl.unit_prod_cost, 1) AS total_cost,
|
|
||||||
sl.product_uom_qty * COALESCE(sl.price_unit, 1) AS total_sale_price,
|
|
||||||
ABS((sl.product_uom_qty * COALESCE(sl.unit_prod_cost, 1))
|
|
||||||
- (sl.product_uom_qty * COALESCE(sl.price_unit, 1))) AS total_margin
|
|
||||||
FROM sale_order_line sl
|
|
||||||
JOIN sale_order so
|
|
||||||
ON so.id = sl.order_id
|
|
||||||
JOIN product_product pp
|
|
||||||
ON pp.id = sl.product_id
|
|
||||||
JOIN product_template pt
|
|
||||||
ON pt.id = pp.product_tmpl_id
|
|
||||||
LEFT JOIN product_category pc
|
|
||||||
ON pc.id = pt.categ_id
|
|
||||||
JOIN res_company rc
|
|
||||||
ON rc.id = sl.company_id
|
|
||||||
JOIN res_partner rp
|
|
||||||
ON rp.id = rc.partner_id
|
|
||||||
WHERE sl.state = 'sale'
|
|
||||||
|
|
||||||
"""
|
|
||||||
if where_caluse:
|
|
||||||
sql += where_caluse
|
|
||||||
self.env.cr.execute(sql)
|
|
||||||
data = self.env.cr.dictfetchall()
|
|
||||||
if data:
|
|
||||||
return data
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def _get_production_cost(self, sale_order_id):
|
|
||||||
sale_order = self.env['sale.order'].browse(sale_order_id)
|
|
||||||
cost = 0.0
|
|
||||||
for line in sale_order.order_line.filtered(lambda l: l.product_id.type == 'consu'):
|
|
||||||
line_cost = line.purchase_price or 0
|
|
||||||
cost += line_cost * line.product_uom_qty
|
|
||||||
for line in sale_order.order_line.filtered(lambda l: l.product_id.type == 'service' and l.price_total > 0):
|
|
||||||
cost += line.price_total
|
|
||||||
|
|
||||||
return cost
|
|
||||||
|
|
||||||
def action_view_sale_orders(self, id):
|
def action_view_sale_orders(self, id):
|
||||||
result = self.env['ir.actions.act_window']._for_xml_id('sale.action_orders')
|
result = self.env['ir.actions.act_window']._for_xml_id('sale.action_orders')
|
||||||
result['views'] = [(self.env.ref('sale.view_order_form', False).id, 'form')]
|
result['views'] = [(self.env.ref('sale.view_order_form', False).id, 'form')]
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,46 @@ export class SamashtiDashboard extends Component {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async export_Excel() {
|
||||||
|
try {
|
||||||
|
if ($(this.gridSaleContainer.el).length > 0) {
|
||||||
|
const grid = $(this.gridSaleContainer.el).pqGrid('instance');
|
||||||
|
const colModel = grid.option('colModel');
|
||||||
|
const dataModel = grid.option('dataModel');
|
||||||
|
const gridData = dataModel.data || dataModel;
|
||||||
|
|
||||||
|
const response = await fetch('/sale_margin/report_excel', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
colModel: colModel,
|
||||||
|
gridData: gridData,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = await response.blob();
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'Sale_Margin_Report.xlsx';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Export failed:', error);
|
||||||
|
alert('Export failed: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- Define grid columns
|
// --- Define grid columns
|
||||||
async getColumns() {
|
async getColumns() {
|
||||||
return [
|
return [
|
||||||
|
|
@ -176,9 +216,10 @@ export class SamashtiDashboard extends Component {
|
||||||
async getSaleColumns(){
|
async getSaleColumns(){
|
||||||
return[
|
return[
|
||||||
{ title: "Sale Order", dataIndx: "sale_order", width: 100,filter: { type: 'textbox', condition: 'contain', listeners: ['keyup'] } },
|
{ title: "Sale Order", dataIndx: "sale_order", width: 100,filter: { type: 'textbox', condition: 'contain', listeners: ['keyup'] } },
|
||||||
{ title: "Invoice", dataIndx: "invoice", width: 100,filter: { type: 'textbox', condition: 'contain', listeners: ['keyup'] } },
|
|
||||||
{ title: "Customer", dataIndx: "customer", width: 280,filter: { type: 'textbox', condition: 'contain', listeners: ['keyup'] } },
|
|
||||||
{ title: "Date", dataIndx: "date", width: 150 },
|
{ title: "Date", dataIndx: "date", width: 150 },
|
||||||
|
{ title: "Invoice", dataIndx: "invoice", width: 180,filter: { type: 'textbox', condition: 'contain', listeners: ['keyup'] } },
|
||||||
|
{ title: "Customer", dataIndx: "customer", width: 280,filter: { type: 'textbox', condition: 'contain', listeners: ['keyup'] } },
|
||||||
|
{ title: "Tags", dataIndx:"tags", width:100, },
|
||||||
{ title: "Quantity", dataIndx: "quantity", width: 120, dataType: "float", format: "#,###.00",summary: { type: "sum" },align: "right" },
|
{ title: "Quantity", dataIndx: "quantity", width: 120, dataType: "float", format: "#,###.00",summary: { type: "sum" },align: "right" },
|
||||||
{ title: "Weight", dataIndx: "weight", width: 150 },
|
{ title: "Weight", dataIndx: "weight", width: 150 },
|
||||||
{ title: "Production Cost", dataIndx: "cost", width: 120, dataType: "float", format: "#,###.00",summary: { type: "sum" },align: "right" },
|
{ title: "Production Cost", dataIndx: "cost", width: 120, dataType: "float", format: "#,###.00",summary: { type: "sum" },align: "right" },
|
||||||
|
|
@ -307,15 +348,9 @@ export class SamashtiDashboard extends Component {
|
||||||
colModel: columns,
|
colModel: columns,
|
||||||
toolbar: {
|
toolbar: {
|
||||||
items: [
|
items: [
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
label: '<span style="color: #555; font-size: 13px;">Format:</span>',
|
|
||||||
attr: 'id="export_format" style="margin-left: 10px; margin-right: 20px; padding: 5px 10px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa; color: #333; font-size: 13px; min-width: 110px;"',
|
|
||||||
options: [{ xlsx: '📊 Excel', csv: '📝 CSV', htm: '🌐 HTML', json: '🔤 JSON'}]
|
|
||||||
},
|
|
||||||
{ type: "button", label: "Export", icon: "ui-icon-arrowthickstop-1-s",
|
{ type: "button", label: "Export", icon: "ui-icon-arrowthickstop-1-s",
|
||||||
attr: 'style="padding: 8px 16px; border: 1px solid #3498db; border-radius: 6px; background: linear-gradient(135deg, #3498db, #2980b9); color: white; font-weight: 600; font-size: 13px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(52, 152, 219, 0.3);"',
|
attr: 'style="padding: 8px 16px; border: 1px solid #3498db; border-radius: 6px; background: linear-gradient(135deg, #3498db, #2980b9); color: white; font-weight: 600; font-size: 13px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(52, 152, 219, 0.3);"',
|
||||||
listener: () => this.exportSaleGrid() },
|
listener: () => this.export_Excel() },
|
||||||
|
|
||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
|
|
@ -347,6 +382,7 @@ export class SamashtiDashboard extends Component {
|
||||||
// Then set groupModel using groupOption
|
// Then set groupModel using groupOption
|
||||||
const groupModel = {
|
const groupModel = {
|
||||||
on: true,
|
on: true,
|
||||||
|
dataIndx: ['tags'],
|
||||||
checkbox: true,
|
checkbox: true,
|
||||||
checkboxHead: true,
|
checkboxHead: true,
|
||||||
header:true,
|
header:true,
|
||||||
|
|
@ -424,64 +460,6 @@ export class SamashtiDashboard extends Component {
|
||||||
alert('Unsupported format: ' + format_ex);
|
alert('Unsupported format: ' + format_ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exportSaleGrid() {
|
|
||||||
const format_ex = $("#export_format").val();
|
|
||||||
const grid = $(this.gridSaleContainer.el);
|
|
||||||
|
|
||||||
console.log("Starting export with format:", format_ex);
|
|
||||||
|
|
||||||
// Different handling for different formats
|
|
||||||
switch(format_ex) {
|
|
||||||
case 'xlsx':
|
|
||||||
const blobXlsx = grid.pqGrid("exportData", {
|
|
||||||
format: 'xlsx',
|
|
||||||
render: true
|
|
||||||
});
|
|
||||||
saveAs(blobXlsx, "SaleMarginData.xlsx");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'csv':
|
|
||||||
const blobCsv = grid.pqGrid("exportData", {
|
|
||||||
format: 'csv',
|
|
||||||
render: true
|
|
||||||
});
|
|
||||||
// CSV often returns as string
|
|
||||||
if (typeof blobCsv === 'string') {
|
|
||||||
saveAs(new Blob([blobCsv], { type: 'text/csv' }), "StockData.csv");
|
|
||||||
} else {
|
|
||||||
saveAs(blobCsv, "SaleMarginData.csv");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'htm':
|
|
||||||
case 'html':
|
|
||||||
const blobHtml = grid.pqGrid("exportData", {
|
|
||||||
format: 'htm',
|
|
||||||
render: true
|
|
||||||
});
|
|
||||||
if (typeof blobHtml === 'string') {
|
|
||||||
saveAs(new Blob([blobHtml], { type: 'text/html' }), "StockData.html");
|
|
||||||
} else {
|
|
||||||
saveAs(blobHtml, "SaleMarginData.html");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'json':
|
|
||||||
const blobJson = grid.pqGrid("exportData", {
|
|
||||||
format: 'json',
|
|
||||||
render: true
|
|
||||||
});
|
|
||||||
if (typeof blobJson === 'string') {
|
|
||||||
saveAs(new Blob([blobJson], { type: 'application/json' }), "StockData.json");
|
|
||||||
} else {
|
|
||||||
saveAs(blobJson, "SaleMargin.json");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
alert('Unsupported format: ' + format_ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue