first commit

This commit is contained in:
Suherdy Yacob 2026-05-12 16:34:03 +07:00
commit 6cc7e121b6
10 changed files with 161 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
__pycache__/
*.py[cod]
*$py.class
.DS_Store
.vscode/
.idea/

23
README.md Normal file
View 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
View File

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

17
__manifest__.py Normal file
View 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
View File

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

10
models/pos_config.py Normal file
View 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')

View 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)

View 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);
}
},
});

View 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 };
}
}
});

View 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>