improvements to table numbers

This commit is contained in:
Abdul Aziz Amrullah 2026-05-21 14:08:59 +07:00
parent c940c694c6
commit 31597b2a60
3 changed files with 49 additions and 20 deletions

View File

@ -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/<id>?download=true`).

View File

@ -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': [

View File

@ -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"