first commit
This commit is contained in:
commit
6cc7e121b6
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
.DS_Store
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# POS iMin Extended
|
||||||
|
|
||||||
|
This module extends the standard `pos_imin` functionality for Odoo 19 POS, allowing for direct printing to iMin built-in printers with customizable parameters.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Bypass Printer Dialog**: Uses the iMin JS SDK to print directly, avoiding the browser's print dialog.
|
||||||
|
- **Customizable Copies**: Set the number of copies to be printed for each receipt in POS settings.
|
||||||
|
- **Paper Size Support**: Choose between 80mm and 58mm paper sizes in the configuration.
|
||||||
|
- **Automatic Cutting**: Supports automatic paper cutting between copies (on supported iMin hardware).
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
1. Install the module.
|
||||||
|
2. Go to **Point of Sale > Configuration > Settings**.
|
||||||
|
3. Under the **iMin Printer** section:
|
||||||
|
- Set the **Print Copies**.
|
||||||
|
- Select the **Paper Size**.
|
||||||
|
4. To fully automate the process (no manual clicks after payment), enable **Automatic Receipt Printing** in the POS settings.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- `pos_imin`: This module patches the core iMin integration.
|
||||||
1
__init__.py
Normal file
1
__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
17
__manifest__.py
Normal file
17
__manifest__.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
'name': 'POS iMin Extended',
|
||||||
|
'version': '1.0',
|
||||||
|
'category': 'Sales/Point of Sale',
|
||||||
|
'summary': 'Extended configuration for iMin printers',
|
||||||
|
'depends': ['pos_imin'],
|
||||||
|
'data': [
|
||||||
|
'views/res_config_settings_views.xml',
|
||||||
|
],
|
||||||
|
'assets': {
|
||||||
|
'point_of_sale._assets_pos': [
|
||||||
|
'pos_imin_extended/static/src/app/**/*',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'installable': True,
|
||||||
|
'license': 'LGPL-3',
|
||||||
|
}
|
||||||
1
models/__init__.py
Normal file
1
models/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import pos_config, res_config_settings
|
||||||
10
models/pos_config.py
Normal file
10
models/pos_config.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
class PosConfig(models.Model):
|
||||||
|
_inherit = 'pos.config'
|
||||||
|
|
||||||
|
imin_print_copies = fields.Integer(string='iMin Print Copies', default=1)
|
||||||
|
imin_paper_size = fields.Selection([
|
||||||
|
('0', '80mm'),
|
||||||
|
('1', '58mm')
|
||||||
|
], string='iMin Paper Size', default='0')
|
||||||
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_imin_print_copies = fields.Integer(related='pos_config_id.imin_print_copies', readonly=False)
|
||||||
|
pos_imin_paper_size = fields.Selection(related='pos_config_id.imin_paper_size', readonly=False)
|
||||||
25
static/src/app/services/pos_store_patch.js
Normal file
25
static/src/app/services/pos_store_patch.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/** @odoo-module */
|
||||||
|
|
||||||
|
import { patch } from "@web/core/utils/patch";
|
||||||
|
import { PosStore } from "@point_of_sale/app/services/pos_store";
|
||||||
|
import { IminPrinterAdapter } from "@pos_imin/app/utils/imin_printer";
|
||||||
|
|
||||||
|
patch(PosStore.prototype, {
|
||||||
|
async detectIminPrinter() {
|
||||||
|
// We override this to pass 'pos' to the adapter
|
||||||
|
try {
|
||||||
|
const iminPrinterAdapter = new IminPrinterAdapter({
|
||||||
|
fallbackPrinter: this.hardwareProxy.printer,
|
||||||
|
pos: this, // Pass the pos store instance
|
||||||
|
});
|
||||||
|
const isAvailable = await iminPrinterAdapter.isAvailable();
|
||||||
|
if (isAvailable) {
|
||||||
|
this.iminPrinterAdapter = iminPrinterAdapter;
|
||||||
|
this.hardwareProxy.printer = this.iminPrinterAdapter;
|
||||||
|
await this.iminPrinterAdapter.connect();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Unable to detect Imin printer:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
47
static/src/app/utils/imin_printer_patch.js
Normal file
47
static/src/app/utils/imin_printer_patch.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/** @odoo-module */
|
||||||
|
|
||||||
|
import { patch } from "@web/core/utils/patch";
|
||||||
|
import { IminPrinterAdapter } from "@pos_imin/app/utils/imin_printer";
|
||||||
|
|
||||||
|
patch(IminPrinterAdapter.prototype, {
|
||||||
|
setup({ fallbackPrinter, pos } = {}) {
|
||||||
|
super.setup(...arguments);
|
||||||
|
this.pos = pos;
|
||||||
|
},
|
||||||
|
|
||||||
|
async sendPrintingJob(img) {
|
||||||
|
try {
|
||||||
|
const status = await this.printerStatus();
|
||||||
|
if (status.value !== 0) {
|
||||||
|
return { result: false, errorCode: status.value, canRetry: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = this.pos?.config;
|
||||||
|
const paperSize = config?.imin_paper_size || '0';
|
||||||
|
const copies = config?.imin_print_copies || 1;
|
||||||
|
|
||||||
|
// Set paper size
|
||||||
|
await this.iminPrinter.setPaperSize(parseInt(paperSize));
|
||||||
|
|
||||||
|
for (let i = 0; i < copies; i++) {
|
||||||
|
await this.iminPrinter.printSingleBitmap(img);
|
||||||
|
|
||||||
|
// Add some feed lines
|
||||||
|
this.iminPrinter.printAndLineFeed();
|
||||||
|
this.iminPrinter.printAndLineFeed();
|
||||||
|
this.iminPrinter.printAndLineFeed();
|
||||||
|
|
||||||
|
// If the printer has a cutter, we can use it
|
||||||
|
// Based on documentation, partialCutPaper() is recommended
|
||||||
|
if (typeof this.iminPrinter.partialCutPaper === 'function') {
|
||||||
|
this.iminPrinter.partialCutPaper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { result: true };
|
||||||
|
} catch (error) {
|
||||||
|
console.error("IminPrinterAdapter: Printing job failed", error);
|
||||||
|
return { result: false, errorCode: error.message, canRetry: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
24
views/res_config_settings_views.xml
Normal file
24
views/res_config_settings_views.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="res_config_settings_view_form_inherit_pos_imin_extended" model="ir.ui.view">
|
||||||
|
<field name="name">res.config.settings.view.form.inherit.pos.imin.extended</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="//setting[@id='pos_other_devices']" position="after">
|
||||||
|
<setting id="pos_imin_settings" string="iMin Printer" help="Configure built-in iMin printer parameters" invisible="not pos_other_devices">
|
||||||
|
<div class="content-group">
|
||||||
|
<div class="row mt16">
|
||||||
|
<label string="Print Copies" for="pos_imin_print_copies" class="col-lg-3 o_light_label"/>
|
||||||
|
<field name="pos_imin_print_copies"/>
|
||||||
|
</div>
|
||||||
|
<div class="row mt16">
|
||||||
|
<label string="Paper Size" for="pos_imin_paper_size" class="col-lg-3 o_light_label"/>
|
||||||
|
<field name="pos_imin_paper_size"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</setting>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in New Issue
Block a user