first commit

This commit is contained in:
Suherdy Yacob 2026-05-13 14:47:50 +07:00
commit 11eb0b8deb
9 changed files with 291 additions and 0 deletions

117
.gitignore vendored Normal file
View File

@ -0,0 +1,117 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# Odoo specific
*.log
*.conf
/data/
# OS specific
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# IDEs
.idea/
.vscode/
*.swp
*.swo

19
README.md Normal file
View File

@ -0,0 +1,19 @@
# POS Receipt Print Default Settings
This module allows you to set the default number of copies and paper size for POS receipts.
## Features
1. **Default Number of Copies**: Configure how many times the receipt should be printed.
2. **Default Paper Size**: Suggest the paper size to the browser print dialog using `@page` CSS rules.
- Supported sizes: 57mm (ISO 57), 58mm, 80mm, 80x210mm, 80x297mm, 112mm, A4.
## How it works
- The module adds configuration fields in **Point of Sale > Configuration > Settings**.
- It patches the `PosStore.printReceipt` method in Javascript to:
- Inject dynamic CSS that overrides the `@page` size.
- Execute a loop to trigger the print function multiple times if more than 1 copy is requested.
## Requirements
- Odoo 19
- Standard browser printing (works best in Chrome/Edge for `@page` support).
- For silent printing (no dialog), the browser must be started in kiosk mode (e.g., `--kiosk-printing` for Chrome).

1
__init__.py Normal file
View File

@ -0,0 +1 @@
from . import models

23
__manifest__.py Normal file
View File

@ -0,0 +1,23 @@
{
'name': 'POS Receipt Print Default Settings',
'version': '1.0',
'category': 'Sales/Point of Sale',
'summary': 'Set default number of copies and paper size for POS receipts',
'description': """
This module allows you to configure the default number of copies and paper size
for receipt printing in the Point of Sale.
It auto-fills the paper size selection via CSS @page and handles multiple copies.
""",
'author': 'Suherdy Yacob',
'depends': ['point_of_sale'],
'data': [
'views/pos_config_views.xml',
],
'assets': {
'point_of_sale._assets_pos': [
'pos_receipt_print_default/static/src/app/**/*',
],
},
'installable': True,
'license': 'LGPL-3',
}

2
models/__init__.py Normal file
View File

@ -0,0 +1,2 @@
from . import pos_config
from . import res_config_settings

21
models/pos_config.py Normal file
View File

@ -0,0 +1,21 @@
from odoo import fields, models, api
class PosConfig(models.Model):
_inherit = 'pos.config'
receipt_print_copies = fields.Integer(string='Default Number of Copies', default=1, help="Default number of copies to print for receipts.")
receipt_paper_size = fields.Selection([
('57mm', '57mm (ISO 57)'),
('58mm', '58mm'),
('80mm', '80mm'),
('80x210mm', '80 x 210 mm'),
('80x297mm', '80 x 297 mm'),
('112mm', '112mm'),
('A4', 'A4'),
], string='Default Paper Size', default='57mm', help="Default paper size for browser print dialog.")
@api.model
def _load_pos_data_fields(self, config):
fields = super()._load_pos_data_fields(config)
fields += ['receipt_print_copies', 'receipt_paper_size']
return fields

View File

@ -0,0 +1,7 @@
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
pos_receipt_print_copies = fields.Integer(related='pos_config_id.receipt_print_copies', readonly=False)
pos_receipt_paper_size = fields.Selection(related='pos_config_id.receipt_paper_size', readonly=False)

View File

@ -0,0 +1,77 @@
/** @odoo-module **/
import { PosStore } from "@point_of_sale/app/services/pos_store";
import { patch } from "@web/core/utils/patch";
patch(PosStore.prototype, {
async printReceipt(params = {}) {
const copies = this.config.receipt_print_copies || 1;
const paperSize = this.config.receipt_paper_size || '57mm';
// Inject CSS for paper size to guide browser print dialog
this._injectReceiptPaperSizeCSS(paperSize);
let result;
// Print multiple copies
for (let i = 0; i < copies; i++) {
result = await super.printReceipt(params);
}
return result;
},
/**
* Injects dynamic CSS with @page rules to suggest paper size to the browser.
* Most modern browsers (Chrome/Edge) use @page { size: ... } to auto-select
* the paper size in the print dialog.
*/
_injectReceiptPaperSizeCSS(size) {
let style = document.getElementById('pos_receipt_print_style');
if (!style) {
style = document.createElement('style');
style.id = 'pos_receipt_print_style';
document.head.appendChild(style);
}
let width = '57mm';
let pageSize = '57mm auto';
if (size === '58mm') {
width = '58mm';
pageSize = '58mm auto';
} else if (size === '80mm') {
width = '80mm';
pageSize = '80mm auto';
} else if (size === '80x210mm') {
width = '80mm';
pageSize = '80mm 210mm';
} else if (size === '80x297mm') {
width = '80mm';
pageSize = '80mm 297mm';
} else if (size === '112mm') {
width = '112mm';
pageSize = '112mm auto';
} else if (size === 'A4') {
width = '210mm';
pageSize = 'A4';
}
style.innerHTML = `
@media print {
@page {
size: ${pageSize};
margin: 0;
}
.pos-receipt {
width: ${width} !important;
margin: 0 auto !important;
padding: 5px !important;
box-sizing: border-box !important;
}
/* Hide other elements if any */
body {
margin: 0 !important;
}
}
`;
}
});

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.pos_receipt_print_default</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="point_of_sale.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//block[@id='pos_bills_and_receipts_section']" position="inside">
<setting string="Receipt Print Defaults" help="Set default printing behavior for receipts.">
<div class="content-group">
<div class="row">
<label for="pos_receipt_print_copies" class="col-lg-4 o_light_label" string="Number of Copies"/>
<field name="pos_receipt_print_copies" class="col-lg-2"/>
</div>
<div class="row mt-2">
<label for="pos_receipt_paper_size" class="col-lg-4 o_light_label" string="Paper Size"/>
<field name="pos_receipt_paper_size" class="col-lg-4"/>
</div>
</div>
</setting>
</xpath>
</field>
</record>
</odoo>