first commit
This commit is contained in:
commit
11eb0b8deb
117
.gitignore
vendored
Normal file
117
.gitignore
vendored
Normal 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
19
README.md
Normal 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
1
__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from . import models
|
||||
23
__manifest__.py
Normal file
23
__manifest__.py
Normal 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
2
models/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from . import pos_config
|
||||
from . import res_config_settings
|
||||
21
models/pos_config.py
Normal file
21
models/pos_config.py
Normal 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
|
||||
7
models/res_config_settings.py
Normal file
7
models/res_config_settings.py
Normal 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)
|
||||
77
static/src/app/services/pos_store_patch.js
Normal file
77
static/src/app/services/pos_store_patch.js
Normal 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;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
});
|
||||
24
views/pos_config_views.xml
Normal file
24
views/pos_config_views.xml
Normal 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>
|
||||
Loading…
Reference in New Issue
Block a user