103 lines
3.7 KiB
Python
103 lines
3.7 KiB
Python
import base64
|
|
import io
|
|
import logging
|
|
|
|
try:
|
|
import xlsxwriter
|
|
except ImportError:
|
|
xlsxwriter = None
|
|
|
|
from odoo import models, _
|
|
from odoo.exceptions import UserError
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
class PurchaseOrder(models.Model):
|
|
_inherit = 'purchase.order'
|
|
|
|
def action_export_bc(self):
|
|
self.ensure_one()
|
|
if not xlsxwriter:
|
|
raise UserError(_("The Python library 'xlsxwriter' is required. Please install it."))
|
|
|
|
output = io.BytesIO()
|
|
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
|
|
|
|
header_format = workbook.add_format({
|
|
'bold': True, 'align': 'center', 'valign': 'vcenter', 'border': 1
|
|
})
|
|
|
|
headers = ["Type", "Item No.", "Description", "Qty", "Satuan"]
|
|
|
|
lines_by_category = {}
|
|
for line in self.order_line:
|
|
# Handle display_type like line_section or line_note which shouldn't be exported as items
|
|
if line.display_type in ('line_section', 'line_note'):
|
|
continue
|
|
|
|
categ_name = line.product_id.categ_id.name or 'Uncategorized'
|
|
# Sheet names in Excel cannot exceed 31 characters
|
|
categ_name = str(categ_name)[:31]
|
|
|
|
# Excel sheet names cannot contain certain characters like :, \\, /, ?, *, [, ]
|
|
invalid_chars = [':', '\\', '/', '?', '*', '[', ']']
|
|
for char in invalid_chars:
|
|
categ_name = categ_name.replace(char, ' ')
|
|
|
|
if categ_name not in lines_by_category:
|
|
lines_by_category[categ_name] = []
|
|
lines_by_category[categ_name].append(line)
|
|
|
|
if not lines_by_category:
|
|
raise UserError(_("There are no order lines to export."))
|
|
|
|
for categ_name, lines in lines_by_category.items():
|
|
sheet = workbook.add_worksheet(categ_name)
|
|
for col_num, header in enumerate(headers):
|
|
sheet.write(0, col_num, header, header_format)
|
|
|
|
row_num = 1
|
|
for line in lines:
|
|
item_type = "Item"
|
|
|
|
# Check custom field x_studio_bc_item_id on product
|
|
if 'x_studio_bc_item_id' in line.product_id._fields and line.product_id.x_studio_bc_item_id:
|
|
item_no = line.product_id.x_studio_bc_item_id
|
|
else:
|
|
item_no = ''
|
|
|
|
description = line.product_id.name or line.name or ''
|
|
qty = line.product_qty
|
|
|
|
# Determine packaging or unit
|
|
if 'product_packaging_id' in line._fields and line.product_packaging_id:
|
|
satuan = line.product_packaging_id.name
|
|
else:
|
|
satuan = line.product_uom_id.name or ''
|
|
|
|
sheet.write(row_num, 0, item_type)
|
|
sheet.write(row_num, 1, item_no)
|
|
sheet.write(row_num, 2, description)
|
|
sheet.write(row_num, 3, qty)
|
|
sheet.write(row_num, 4, satuan)
|
|
|
|
row_num += 1
|
|
|
|
workbook.close()
|
|
output.seek(0)
|
|
|
|
attachment_name = f"PO_Export_BC_{self.name.replace('/', '_')}.xlsx"
|
|
|
|
attachment = self.env['ir.attachment'].create({
|
|
'name': attachment_name,
|
|
'type': 'binary',
|
|
'datas': base64.b64encode(output.read()),
|
|
'mimetype': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
})
|
|
|
|
return {
|
|
'type': 'ir.actions.act_url',
|
|
'url': f'/web/content/{attachment.id}?download=true',
|
|
'target': 'self',
|
|
}
|