From 31597b2a60a2cad86a39fec0425f30afa8c7143e Mon Sep 17 00:00:00 2001 From: Abdul Aziz Amrullah Date: Thu, 21 May 2026 14:08:59 +0700 Subject: [PATCH] improvements to table numbers --- README.md | 57 +++++++++++++++++++++++----------- __manifest__.py | 7 +++++ wizard/pos_export_bc_wizard.py | 5 +-- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 0e00fd0..792a324 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,49 @@ # POS Export BC Format -This is a custom Odoo 19 module that allows users to export Point of Sale (POS) orders and sales data into a structured Excel format named "MIE MAPAN INVOICES". +This is a custom Odoo 19 module designed specifically to export Point of Sale (POS) orders and sales data into a highly structured Excel layout required for "MIE MAPAN INVOICES". This module focuses on ensuring accurate accounting aggregations, proper chronological date handling, and layout consistency for reporting purposes. -## Features -- **Custom Excel Generation:** Generates a visually matching Excel file with specific columns and aggregated row formatting. -- **Order-Level Row Grouping:** In the Excel file, aggregate data such as *Total*, *Tax*, *Paid*, *Return*, and *Subtotal* are populated only on the first row of each order to visually indicate grouping. -- **Multiple Sheets:** Generates two sheets dynamically: - - **Invoice**: For orders with a positive total amount. - - **Refund**: For orders with a negative total amount. -- **Custom SKU Integration:** Specifically fetches the custom field `x_studio_popcorn_sku` created via Odoo Studio as the primary product SKU identifier. -- **Date Formatting Consistency:** Exports datetime fields like "Date" and "Paid At" directly as raw strings (e.g. `11-03-2026 15:30:00`) to prevent spreadsheet applications from aggressively auto-formatting dates unexpectedly. +## Key Features + +1. **Custom Row-Aggregated Excel Generation** + - Traditional exports list line items uniformly. This module groups the sales data by order. Order-level aggregates (such as *Total Charge*, *Subtotal*, *Tax*, *Paid Amount*, *Return*) are printed exclusively on the first row of each order's line items. + - Subsequent line items for the same order only show item-specific details like *Product Name*, *SKU*, *Quantity*, and *Unit Price*, keeping the spreadsheet clean and highly readable. + +2. **Automated "Invoice" and "Refund" Splitting** + - The module automatically detects standard positive orders and negative return orders. + - It separates them dynamically into two distinct sheets within the same workbook: **"Invoice"** (for orders with a total >= 0) and **"Refund"** (for orders with a total < 0). + +3. **Custom "Dinein" vs "Takeaway" Logic** + - Automatically determines if an order is for Dine-in or Takeaway based on the assigned POS table number. + - If the assigned table number is `<= 60`, the system explicitly records it as `"dinein"`. + - If the table number is `>= 61` (or if no table is assigned), the system automatically records it as `"takeaway"`. + - Strips the display name to cleanly export just the actual integer Table Number. + +4. **Integration with Odoo Studio Custom Fields** + - Specifically configured to pull SKU values from a custom Odoo Studio product field (`x_studio_popcorn_sku`), seamlessly bridging standard Point of Sale code with codeless customizations. + +5. **Precise Formatting and Value Handling** + - Outputs datetime data (such as "Date" and "Paid At") as strict text strings (format: `DD-MM-YYYY HH:MM:SS`) to bypass Excel's aggressive, and often erroneous, timezone/date auto-formatting. + - Correctly calculates the amount paid by only summing positive payment tenders and using standard POS change allocations for exact accounting matches. ## Requirements -This module requires the Python `xlsxwriter` package to format and generate memory-based Excel files. + +The module performs in-memory Excel generation rather than writing physical files, requiring the `xlsxwriter` library. + +Install it via your environment's package manager: ```sh pip install xlsxwriter ``` -## Usage -1. Make sure you have installed the module from the Odoo Apps menu. -2. Navigate to **Point of Sale** -> **Reporting** -> **Export BC Format**. -3. A wizard will pop up asking for the **Start Date** and **End Date**. -4. Select the desired period and click **Export**. -5. Your browser will download the generated `.xlsx` file. +## How to Use -## Technical Details -This module creates a TransientModel `pos.export.bc.wizard`. Upon clicking export, `action_export_bc()` queries `pos.order` based on the dates provided and reconstructs the data into an `io.BytesIO` buffer, which is temporarily saved as an `ir.attachment` and served back to the user via a `/web/content/...` download URL act window. +1. **Install Module:** Navigate to the Odoo **Apps** menu and install `POS Export BC Format`. +2. **Open the Tool:** Go to the backend **Point of Sale** application. Click on **Reporting** in the top menu and select **Export BC Format**. +3. **Select Period:** A wizard window will prompt you for a **Start Date** and **End Date**. +4. **Generate:** Click the **Export to BC Format** button. +5. **Download:** A dynamically generated `.xlsx` file will automatically download to your browser. + +## Technical Structure + +- **Models / Wizards**: Leverages an Odoo `TransientModel` (`pos.export.bc.wizard`) to prompt users for date ranges. +- **Generation Logic**: The python script aggregates `pos.order` models matching the domain, then systematically writes rows into an `io.BytesIO` stream using the `xlsxwriter.Workbook`. +- **Delivery**: The memory stream is temporarily saved to `ir.attachment` and served via a standard Odoo HTTP controller url act window (`/web/content/?download=true`). diff --git a/__manifest__.py b/__manifest__.py index dab82d1..f3469ff 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -7,6 +7,13 @@ 'description': """ This module adds a wizard in the POS backend to export POS Orders into a specific BC Excel format ("MIE MAPAN INVOICES"). + + Key Features: + - Order-level row aggregation for totals, taxes, and payments. + - Splits data dynamically into 'Invoice' (positive) and 'Refund' (negative) sheets. + - Calculates 'Dinein' and 'Takeaway' explicitly based on table numbers. + - Integrates with Odoo Studio custom field 'x_studio_popcorn_sku' for product mapping. + - Text-based date formatting to prevent spreadsheet auto-format issues. """, 'depends': ['point_of_sale'], 'data': [ diff --git a/wizard/pos_export_bc_wizard.py b/wizard/pos_export_bc_wizard.py index b2fd0e8..84376f1 100644 --- a/wizard/pos_export_bc_wizard.py +++ b/wizard/pos_export_bc_wizard.py @@ -88,7 +88,7 @@ class PosExportBcWizard(models.TransientModel): 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 = order.table_id.display_name if 'table_id' in order._fields and order.table_id else '' + table = str(order.table_id.table_number) if 'table_id' in order._fields and order.table_id else '' customer = order.partner_id.name or '' table_customer = table or customer invoice = order.pos_reference or order.name @@ -108,7 +108,8 @@ class PosExportBcWizard(models.TransientModel): note = order.note if 'note' in order._fields else '' # dinein = 'dinein' if table else 'takeaway' # preset = order.preset_id.name - if table <= 60: + table_number = order.table_id.table_number if 'table_id' in order._fields and order.table_id else 999 + if table_number < 61: dinein = "dinein" else: dinein = "takeaway"