from odoo import http from odoo.http import request import io import xlsxwriter class MaterialBackupExportController(http.Controller): @http.route('/supplier/form', auth='public') def index(self, **kw): return "Hello, world" @http.route(['/download/material/backup//'], type='http', auth='user') def download_backup_by_year(self, year, item_type, **kwargs): # Safely map table names table_map = { 'material': (f'"sos_material_{year}"', f'"sos_material_transaction_history_{year}"'), 'sfg': (f'"sos_sfg_{year}"', f'"sos_sfg_transaction_history_{year}"'), 'fg': (f'"sos_fg_{year}"', f'"sos_fg_transaction_history_{year}"'), } if item_type not in table_map: return request.not_found() material_table, transaction_table = table_map[item_type] cr = request.env.cr if item_type == 'material': part_no_col = 'part_no' elif item_type == 'sfg': part_no_col = 'sfg_code' elif item_type == 'fg': part_no_col = 'fg_code' else: return request.not_found() try: cr.execute(f""" SELECT id, {part_no_col}, name, opening_bal_qty, inhand_stock_qty FROM {material_table} """) materials = cr.fetchall() except Exception as e: return request.make_response( f"Error accessing table {material_table}: {str(e)}", status=500 ) material_dict = { row[0]: { 'part_no': row[1], 'name': row[2], 'opening': row[3], 'inhand_qty': row[4], 'in': 0, 'out': 0 } for row in materials } try: cr.execute(f""" SELECT ref_id, action, SUM(quantity) FROM {transaction_table} GROUP BY ref_id, action """) transactions = cr.fetchall() except Exception as e: return request.make_response( f"Error accessing transaction table {transaction_table}: {str(e)}", status=500 ) for ref_id, action, qty in transactions: if ref_id in material_dict: material_dict[ref_id][action] = qty # Generate Excel output = io.BytesIO() workbook = xlsxwriter.Workbook(output) sheet = workbook.add_worksheet("Stock List") headers = ['Part No', 'Name', 'Opening Qty', 'Inhand Qty', 'Total IN Qty', 'Total OUT Qty'] for col, header in enumerate(headers): sheet.write(0, col, header) for row, mat in enumerate(material_dict.values(), start=1): sheet.write(row, 0, mat['part_no']) sheet.write(row, 1, mat['name']) sheet.write(row, 2, mat['opening'] or 0) sheet.write(row, 3, mat['inhand_qty'] or 0) sheet.write(row, 4, mat.get('in', 0)) sheet.write(row, 5, mat.get('out', 0)) workbook.close() output.seek(0) return request.make_response( output.read(), headers=[ ('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'), ('Content-Disposition', f'attachment; filename=Backup_{item_type}_{year}.xlsx') ] )