added new button for export using old popcorn format

This commit is contained in:
Abdul Aziz Amrullah 2026-06-10 16:17:41 +07:00
parent 2ab531b5b5
commit 8cf0a6c037
2 changed files with 66 additions and 37 deletions

View File

@ -20,6 +20,12 @@ class PosExportBcWizard(models.TransientModel):
end_date = fields.Date(string="End Date", required=True, default=fields.Date.context_today) end_date = fields.Date(string="End Date", required=True, default=fields.Date.context_today)
def action_export_bc(self): def action_export_bc(self):
return self._generate_export(old_format=False)
def action_export_old_popcorn(self):
return self._generate_export(old_format=True)
def _generate_export(self, old_format=False):
self.ensure_one() self.ensure_one()
if not xlsxwriter: if not xlsxwriter:
raise UserError(_("The Python library 'xlsxwriter' is required. Please install it.")) raise UserError(_("The Python library 'xlsxwriter' is required. Please install it."))
@ -44,15 +50,21 @@ class PosExportBcWizard(models.TransientModel):
date_time_format = workbook.add_format({'num_format': 'dd-mm-yyyy hh:mm:ss'}) date_time_format = workbook.add_format({'num_format': 'dd-mm-yyyy hh:mm:ss'})
number_format = workbook.add_format({'num_format': '#,##0.00'}) number_format = workbook.add_format({'num_format': '#,##0.00'})
headers = [ if old_format:
"No", "Date", "Outlet", "Table/Customer", "Invoice", "Category", "SKU", "Product", "Quantity", headers = [
"Price Type", "Price", "Price Cut", "Subtotal", "Discount", "Tax", "Service", "Takeaway Charge", "No", "Date", "Outlet", "Table/Customer", "Invoice", "Category", "SKU", "Product", "Quantity",
"Packaging Fee", "Rounding", "Charge", "Paid", "Pax", "Paid At", "Return", "Refund", "Payment", "Price Type", "Price", "Price Cut", "Subtotal", "Discount", "Tax", "Service", "Rounding",
"Note", "Dinein", "User", "Promo", "Order from", "Nama Penerima", "Alamat Penerima", "Link Maps" "Charge", "Paid", "Pax", "Return", "Refund", "Payment", "Note", "Dinein", "User"
] ]
else:
headers = [
"No", "Date", "Outlet", "Table/Customer", "Invoice", "Category", "SKU", "Product", "Quantity",
"Price Type", "Price", "Price Cut", "Subtotal", "Discount", "Tax", "Service", "Takeaway Charge",
"Packaging Fee", "Rounding", "Charge", "Paid", "Pax", "Paid At", "Return", "Refund", "Payment",
"Note", "Dinein", "User", "Promo", "Order from", "Nama Penerima", "Alamat Penerima", "Link Maps"
]
# Datetime timezone conversion # Datetime timezone conversion
# We need these in UTC for the domain search
user_tz_str = self.env.user.tz or 'UTC' user_tz_str = self.env.user.tz or 'UTC'
user_tz = pytz.timezone(user_tz_str) user_tz = pytz.timezone(user_tz_str)
@ -66,8 +78,8 @@ class PosExportBcWizard(models.TransientModel):
sheet = workbook.add_worksheet(sheet_name) sheet = workbook.add_worksheet(sheet_name)
# Title # Title
sheet.merge_range('A1:AF1', 'MIE MAPAN', title_format) sheet.merge_range('A1:Z1' if old_format else 'A1:AF1', 'MIE MAPAN', title_format)
sheet.merge_range('A2:AF2', 'INVOICES', subtitle_format) sheet.merge_range('A2:Z2' if old_format else 'A2:AF2', 'INVOICES', subtitle_format)
# Period # Period
start_dt_str = start_datetime.strftime('%d-%m-%Y 00:00') start_dt_str = start_datetime.strftime('%d-%m-%Y 00:00')
@ -101,9 +113,6 @@ class PosExportBcWizard(models.TransientModel):
discount_order = sum(abs(l.price_subtotal) for l in order.lines if l.price_unit < 0) discount_order = sum(abs(l.price_subtotal) for l in order.lines if l.price_unit < 0)
tax = order.amount_tax tax = order.amount_tax
charge = order.amount_total charge = order.amount_total
# In Odoo, payment amount can be negative for change.
# To get the total amount tendered before change, we sum only the positive payments.
# The change/return is typically stored in order.amount_return
paid = sum(p.amount for p in order.payment_ids if p.amount > 0) paid = sum(p.amount for p in order.payment_ids if p.amount > 0)
if paid == 0: if paid == 0:
continue continue
@ -112,8 +121,6 @@ class PosExportBcWizard(models.TransientModel):
payment_methods = ', '.join(order.payment_ids.mapped('payment_method_id.name')) payment_methods = ', '.join(order.payment_ids.mapped('payment_method_id.name'))
note = order.note if 'note' in order._fields else '' note = order.note if 'note' in order._fields else ''
# dinein = 'dinein' if table else 'takeaway'
# preset = order.preset_id.name
if 'table_id' in order._fields and order.table_id: if 'table_id' in order._fields and order.table_id:
dinein = "dinein" dinein = "dinein"
else: else:
@ -153,26 +160,38 @@ class PosExportBcWizard(models.TransientModel):
sheet.write(row_num, 13, discount_order, number_format) sheet.write(row_num, 13, discount_order, number_format)
sheet.write(row_num, 14, tax, number_format) sheet.write(row_num, 14, tax, number_format)
sheet.write(row_num, 15, 0, number_format) # Service sheet.write(row_num, 15, 0, number_format) # Service
sheet.write(row_num, 16, 0, number_format) # Takeaway Charge if old_format:
sheet.write(row_num, 17, 0, number_format) # Packaging Fee sheet.write(row_num, 16, 0, number_format) # Rounding
sheet.write(row_num, 18, 0, number_format) # Rounding sheet.write(row_num, 17, charge, number_format)
sheet.write(row_num, 19, charge, number_format) sheet.write(row_num, 18, paid, number_format)
sheet.write(row_num, 20, paid, number_format) sheet.write(row_num, 19, pax)
sheet.write(row_num, 21, pax) sheet.write(row_num, 20, return_amt, number_format)
if local_date: sheet.write(row_num, 21, 0, number_format) # Refund
date_str = local_date.strftime('%d-%m-%Y %H:%M:%S') sheet.write(row_num, 22, payment_methods)
sheet.write_string(row_num, 22, date_str) sheet.write(row_num, 23, note)
sheet.write(row_num, 23, return_amt, number_format) sheet.write(row_num, 24, dinein)
sheet.write(row_num, 24, 0, number_format) # Refund sheet.write(row_num, 25, user)
sheet.write(row_num, 25, payment_methods) else:
sheet.write(row_num, 26, note) sheet.write(row_num, 16, 0, number_format) # Takeaway Charge
sheet.write(row_num, 27, dinein) sheet.write(row_num, 17, 0, number_format) # Packaging Fee
sheet.write(row_num, 28, user) sheet.write(row_num, 18, 0, number_format) # Rounding
sheet.write(row_num, 29, "") # Promo sheet.write(row_num, 19, charge, number_format)
sheet.write(row_num, 30, "cashier") # Order from sheet.write(row_num, 20, paid, number_format)
sheet.write(row_num, 31, "") sheet.write(row_num, 21, pax)
sheet.write(row_num, 32, "") if local_date:
sheet.write(row_num, 33, "") date_str = local_date.strftime('%d-%m-%Y %H:%M:%S')
sheet.write_string(row_num, 22, date_str)
sheet.write(row_num, 23, return_amt, number_format)
sheet.write(row_num, 24, 0, number_format) # Refund
sheet.write(row_num, 25, payment_methods)
sheet.write(row_num, 26, note)
sheet.write(row_num, 27, dinein)
sheet.write(row_num, 28, user)
sheet.write(row_num, 29, "") # Promo
sheet.write(row_num, 30, "cashier") # Order from
sheet.write(row_num, 31, "")
sheet.write(row_num, 32, "")
sheet.write(row_num, 33, "")
is_first_line = False is_first_line = False
@ -188,11 +207,20 @@ class PosExportBcWizard(models.TransientModel):
company = self.env.company company = self.env.company
company_ident = (company.company_registry or company.name or '').upper().replace(' ', '') company_ident = (company.company_registry or company.name or '').upper().replace(' ', '')
company_ident = company_ident[:14] # Limit to ensure total name is <= 40 characters
# Max length logic
# For old_format: len("POS__YYMMDD_to_YYMMDD_OLD.xlsx") = 30 chars -> leaves 10 chars for company_ident
# For new_format: len("POS__YYMMDD_to_YYMMDD.xlsx") = 26 chars -> leaves 14 chars for company_ident
company_len = 10 if old_format else 14
company_ident = company_ident[:company_len]
start_str = self.start_date.strftime('%y%m%d') start_str = self.start_date.strftime('%y%m%d')
end_str = self.end_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}.xlsx"
if old_format:
file_name = f"POS_{company_ident}_{start_str}_to_{end_str}_OLD.xlsx"
else:
file_name = f"POS_{company_ident}_{start_str}_to_{end_str}.xlsx"
# Save as an ir.attachment and return action to download # Save as an ir.attachment and return action to download
attachment = self.env['ir.attachment'].create({ attachment = self.env['ir.attachment'].create({

View File

@ -18,6 +18,7 @@
</sheet> </sheet>
<footer> <footer>
<button name="action_export_bc" string="Export to BC Format" type="object" class="btn-primary" data-hotkey="q"/> <button name="action_export_bc" string="Export to BC Format" type="object" class="btn-primary" data-hotkey="q"/>
<button name="action_export_old_popcorn" string="Export to Old Popcorn Format" type="object" class="btn-secondary"/>
<button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z"/> <button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z"/>
</footer> </footer>
</form> </form>