diff --git a/wizard/pos_export_bc_wizard.py b/wizard/pos_export_bc_wizard.py index c226587..7e9e26a 100644 --- a/wizard/pos_export_bc_wizard.py +++ b/wizard/pos_export_bc_wizard.py @@ -12,11 +12,6 @@ try: except ImportError: xlsxwriter = None -try: - import xlwt -except ImportError: - xlwt = None - class PosExportBcWizard(models.TransientModel): _name = 'pos.export.bc.wizard' _description = 'POS Export BC Format Wizard' @@ -28,7 +23,7 @@ class PosExportBcWizard(models.TransientModel): return self._generate_export(old_format=False) def action_export_old_popcorn(self): - return self._generate_export_xls() + return self._generate_export(old_format=True) def _generate_export(self, old_format=False): self.ensure_one() @@ -253,182 +248,3 @@ class PosExportBcWizard(models.TransientModel): 'url': f'/web/content/{attachment.id}?download=true', 'target': 'self', } - - def _generate_export_xls(self): - self.ensure_one() - if not xlwt: - raise UserError(_("The Python library 'xlwt' is required. Please install it with 'pip install xlwt'.")) - - if self.start_date > self.end_date: - raise UserError(_("Start Date must be earlier or equal to End Date.")) - - output = io.BytesIO() - workbook = xlwt.Workbook(encoding='utf-8') - - # Define formats for xlwt - header_format = xlwt.easyxf('font: bold on; align: horiz center, vert center;') - title_format = xlwt.easyxf('font: bold on, color red, height 280; align: horiz center, vert center;') # height is in twips (14 * 20) - subtitle_format = xlwt.easyxf('font: bold on, color black, height 240; align: horiz center, vert center;') # 12 * 20 - date_time_format = xlwt.easyxf(num_format_str='DD-MM-YYYY HH:MM:SS') - number_format = xlwt.easyxf(num_format_str='#,##0.00') - - headers = [ - "No", "Date", "Outlet", "Table/Customer", "Invoice", "Category", "SKU", "Product", "Quantity", - "Price Type", "Price", "Price Cut", "Subtotal", "Discount", "Tax", "Service", "Rounding", - "Charge", "Paid", "Pax", "Return", "Refund", "Payment", "Note", "Dinein", "User" - ] - - # Datetime timezone conversion - user_tz_str = self.env.user.tz or 'UTC' - user_tz = pytz.timezone(user_tz_str) - - start_datetime = datetime.combine(self.start_date, datetime.min.time()) - end_datetime = datetime.combine(self.end_date, datetime.max.time()) - - start_utc = user_tz.localize(start_datetime).astimezone(pytz.UTC).replace(tzinfo=None) - end_utc = user_tz.localize(end_datetime).astimezone(pytz.UTC).replace(tzinfo=None) - - def write_sheet(sheet_name, domain): - sheet = workbook.add_sheet(sheet_name) - - # Title - sheet.write_merge(0, 0, 0, 25, 'MIE MAPAN', title_format) - sheet.write_merge(1, 1, 0, 25, 'INVOICES', subtitle_format) - - # Period - start_dt_str = start_datetime.strftime('%d-%m-%Y 00:00') - end_dt_str = end_datetime.strftime('%d-%m-%Y 23:59') - sheet.write(2, 0, 'Period') - sheet.write(2, 1, ':') - sheet.write(2, 2, f"{start_dt_str} - {end_dt_str}") - - # Headers - for col_num, header in enumerate(headers): - sheet.write(4, col_num, header, header_format) - - row_num = 5 - orders = self.env['pos.order'].search(domain, order='date_order asc') - - order_no = 1 - for order in orders: - if 'refund_orders_count' in order._fields and order.refund_orders_count > 0: - continue - - local_date = order.date_order.replace(tzinfo=pytz.UTC).astimezone(user_tz) if order.date_order else False - - outlet = order.config_id.name or '' - table = str(order.table_id.table_number) if 'table_id' in order._fields and order.table_id else '' - customer = order.partner_id.name or '' - floating_order_name = order.floating_order_name if 'floating_order_name' in order._fields and order.floating_order_name else '' - table_customer = table or floating_order_name or customer - invoice = order.pos_reference or order.name - - subtotal = sum(l.price_subtotal for l in order.lines) - discount_order = sum(abs(l.price_subtotal) for l in order.lines if l.price_unit < 0) - tax = order.amount_tax - charge = order.amount_total - paid = sum(p.amount for p in order.payment_ids if p.amount > 0) - pax = order.customer_count if 'customer_count' in order._fields else 1 - return_amt = order.amount_return if 'amount_return' in order._fields else (paid - charge if paid > charge else 0) - - payment_methods = ', '.join(order.payment_ids.mapped('payment_method_id.name')) - note = order.note if 'note' in order._fields else '' - if 'table_id' in order._fields and order.table_id: - dinein = "dinein" - else: - dinein = "takeaway" - user = order.user_id.name or '' - - is_first_line = True - for line in order.lines: - if line.price_unit < 0: - continue - - if not is_first_line: - sheet.write(row_num, 0, "") - sheet.write(row_num, 1, "") - sheet.write(row_num, 2, "") - sheet.write(row_num, 3, "") - sheet.write(row_num, 4, "") - else: - sheet.write(row_num, 0, order_no) - if local_date: - date_str = local_date.strftime('%d-%m-%Y %H:%M:%S') - sheet.write(row_num, 1, date_str) - else: - sheet.write(row_num, 1, "") - - sheet.write(row_num, 2, outlet) - sheet.write(row_num, 3, table_customer) - sheet.write(row_num, 4, invoice) - - category = line.product_id.pos_categ_ids[0].name if line.product_id.pos_categ_ids else '' - sku = line.product_id.x_studio_bc_item_id if 'x_studio_bc_item_id' in line.product_id._fields and line.product_id.x_studio_bc_item_id else '' - product_name = line.product_id.name or '' - qty = line.qty - - price_type = order.pricelist_id.name or 'DEFAULT' - price = line.price_unit - price_cut = (line.price_unit * line.discount / 100) if line.discount else 0.0 - - sheet.write(row_num, 5, category) - sheet.write(row_num, 6, sku) - sheet.write(row_num, 7, product_name) - sheet.write(row_num, 8, qty) - sheet.write(row_num, 9, price_type) - sheet.write(row_num, 10, price, number_format) - sheet.write(row_num, 11, price_cut, number_format) - - if is_first_line: - sheet.write(row_num, 12, subtotal, number_format) - sheet.write(row_num, 13, discount_order, number_format) - sheet.write(row_num, 14, tax, number_format) - sheet.write(row_num, 15, 0, number_format) # Service - sheet.write(row_num, 16, 0, number_format) # Rounding - sheet.write(row_num, 17, charge, number_format) - sheet.write(row_num, 18, paid, number_format) - sheet.write(row_num, 19, pax) - sheet.write(row_num, 20, return_amt, number_format) - sheet.write(row_num, 21, 0, number_format) # Refund - sheet.write(row_num, 22, payment_methods) - sheet.write(row_num, 23, note) - sheet.write(row_num, 24, dinein) - sheet.write(row_num, 25, user) - - is_first_line = False - - row_num += 1 - order_no += 1 - - domain_base = [('date_order', '>=', start_utc), ('date_order', '<=', end_utc)] - write_sheet('Invoice', domain_base + [('amount_total', '>=', 0)]) - write_sheet('Refund', domain_base + [('amount_total', '<', 0)]) - - workbook.save(output) - output.seek(0) - - company = self.env.company - company_ident = (company.company_registry or company.name or '').upper().replace(' ', '') - - # Max length logic - company_len = 10 - company_ident = company_ident[:company_len] - - start_str = self.start_date.strftime('%y%m%d') - end_str = self.end_date.strftime('%y%m%d') - - file_name = f"POS_{company_ident}_{start_str}_to_{end_str}_OLD.xls" - - # Save as an ir.attachment and return action to download - attachment = self.env['ir.attachment'].create({ - 'name': file_name, - 'type': 'binary', - 'datas': base64.b64encode(output.read()), - 'mimetype': 'application/vnd.ms-excel' - }) - - return { - 'type': 'ir.actions.act_url', - 'url': f'/web/content/{attachment.id}?download=true', - 'target': 'self', - }