Přejít na obsah
Odoo Menu
  • Přihlásit se
  • Vyzkoušejte zdarma
  • Aplikace
    Finance
    • Účetnictví
    • Fakturace
    • Výdaje
    • Spreadsheet (BI)
    • Dokumenty
    • Podpisy
    Prodej
    • CRM
    • Prodej
    • POS Obchod
    • POS Restaurace
    • Předplatné
    • Pronájem
    Webové stránky
    • Webové stránky
    • E-shop
    • Blog
    • Fórum
    • Živý chat
    • eLearning
    Dodavatelský řetězec
    • Sklad
    • Výroba
    • PLM
    • Nákup
    • Údržba
    • Kvalita
    Lidské zdroje
    • Zaměstnanci
    • Nábor
    • Volno
    • Hodnocení zaměstnanců
    • Doporučení
    • Vozový park
    Marketing
    • Marketing sociálních sítí
    • Emailový marketing
    • SMS Marketing
    • Události
    • Marketingová automatizace
    • Dotazníky
    Služby
    • Projekt
    • Časové výkazy
    • Práce v terénu
    • Helpdesk
    • Plánování
    • Schůzky
    Produktivita
    • Diskuze
    • Schvalování
    • IoT
    • VoIP
    • Znalosti
    • WhatsApp
    Aplikace třetích stran Odoo Studio Odoo cloudová platforma
  • Branže
    Maloobchod
    • Knihkupectví
    • Obchod s oblečením
    • Obchod s nábytkem
    • Potraviny
    • Obchod s hardwarem
    • Hračkářství
    Jídlo a pohostinství
    • Bar a Pub
    • Restaurace
    • Fast Food
    • Penzion
    • Distributor nápojů
    • Hotel
    Nemovitost
    • Realitní kancelář
    • Architektonická firma
    • Stavba
    • Správa nemovitostí
    • Zahradnictví
    • Asociace vlastníků nemovitosti
    Poradenství
    • Účetní firma
    • Odoo Partner
    • Marketingová agentura
    • Právník
    • Akvizice talentů
    • Audit a certifikace
    Výroba
    • Textil
    • Kov
    • Nábytek
    • Jídlo
    • Pivovar
    • Korporátní dárky
    Zdraví a fitness
    • Sportovní klub
    • Prodejna brýli
    • Fitness Centrum
    • Wellness praktikové
    • Lékárna
    • Kadeřnictví
    Transakce
    • Údržbář
    • Podpora IT & hardware
    • Systémy solární energie
    • Výrobce obuvi
    • Úklidové služby
    • Služby HVAC
    Ostatní
    • Nezisková organizace
    • Agentura pro životní prostředí
    • Pronájem billboardů
    • Fotografování
    • Leasing jízdních kol
    • Prodejce softwaru
    Procházet všechna odvětví
  • Komunita
    Edukační program
    • Tutoriály
    • Dokumentace
    • Certifikace
    • Vzdělávání
    • Blog
    • Podcast
    Podpora vzdělávání
    • Vzdělávací program
    • Scale Up! Hra na firmu
    • Navštivte Odoo
    Získat software
    • Stáhnout
    • Porovnejte edice
    • Verze
    Spolupráce
    • Github
    • Fórum
    • Události
    • Překlady
    • Stát se partnerem
    • Služby pro partnery
    • Registrujte svou účetní firmu
    Získat služby
    • Najít partnera
    • Najít účetní
    • Setkejte se s poradcem
    • Implementační služby
    • Zákaznické reference
    • Podpora
    • Upgrady
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +1 (650) 691-3277
    Dohodnout demo
  • Ceník
  • Pomoc

Odoo is the world's easiest all-in-one management software.
It includes hundreds of business apps:

  • CRM
  • e-Commerce
  • Účetnictví
  • Sklad
  • PoS
  • Projekty
  • MRP
All apps
You need to be registered to interact with the community.
All Posts Lidé Odznaky
Štítky (View all)
odoo accounting v14 pos v15
O tomto fóru
You need to be registered to interact with the community.
All Posts Lidé Odznaky
Štítky (View all)
odoo accounting v14 pos v15
O tomto fóru
Pomoc

inheritance of PosModel in POS models.js file

Odebírat

Get notified when there's activity on this post

This question has been flagged
posinheritancejs
5 Odpovědi
33977 Zobrazení
Avatar
Harold

I made a template to facilitate POS inheritance, easy to use with the command scaffold. You can find it here https://github.com/haroldtamo/Odoo-Pos-Inheritance-Template

Sorry, I don't have enough karma to post it as answer, so i posted it here. The original question begin here :

Hi,

I want to override the PosModel in model.js (begin on line 17) by adding a new field in the fetch of products (product.product class) like this :

return self.fetch(
                        'product.product', 
                        ['name', 'field_to_add','list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code',
                         'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description'],
                        [['sale_ok','=',true],['available_in_pos','=',true]],
                        {pricelist: self.get('shop').pricelist_id[0]} // context for price
                    );

Unfortunately, i think i use a wrong method for inheritance : in fact, i copy all the class PosModel and i add my field in a new addons so, when the POS session is loaded, products are loaded twice : first when odoo call the original class and second when it call mine. The consequence is that the loading of the pos session is very slow. So i want to know the right method to override or inherit that class (PosModel)

Here is my code for inheritance (sorry i don't see the [CODE] tag ) (look the part in bold) :

function openerp_pos_price_control_models(instance, module){ var module = instance.point_of_sale; var QWeb = instance.web.qweb; _t = instance.web._t; var round_di = instance.web.round_decimals; var round_pr = instance.web.round_precision; module.PosModel = Backbone.Model.extend({ initialize: function(session, attributes) { Backbone.Model.prototype.initialize.call(this, attributes); var self = this; this.session = session; this.ready = $.Deferred(); // used to notify the GUI that the PosModel has loaded all resources this.flush_mutex = new $.Mutex(); // used to make sure the orders are sent to the server once at time this.barcode_reader = new module.BarcodeReader({'pos': this}); // used to read barcodes this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy this.db = new module.PosLS(); // a database used to store the products and categories this.db.clear('products','categories'); this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode // default attributes values. If null, it will be loaded below. this.set({ 'nbr_pending_operations': 0, 'currency': {symbol: '$', position: 'after'}, 'shop': null, 'company': null, 'user': null, // the user that loaded the pos 'user_list': null, // list of all users 'partner_list': null, // list of all partners with an ean 'cashier': null, // the logged cashier, if different from user 'orders': new module.OrderCollection(), //this is the product list as seen by the product list widgets, it will change based on the category filters 'products': new module.ProductCollection(), 'cashRegisters': null, 'bank_statements': null, 'taxes': null, 'pos_session': null, 'pos_config': null, 'units': null, 'units_by_id': null, 'pricelist': null, 'selectedOrder': null, }); this.get('orders').bind('remove', function(){ self.on_removed_order(); }); // We fetch the backend data on the server asynchronously. this is done only when the pos user interface is launched, // Any change on this data made on the server is thus not reflected on the point of sale until it is relaunched. // when all the data has loaded, we compute some stuff, and declare the Pos ready to be used. $.when(this.load_server_data()) .done(function(){ //self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging self.ready.resolve(); }).fail(function(){ //we failed to load some backend data, or the backend was badly configured. //the error messages will be displayed in PosWidget self.ready.reject(); }); }, // helper function to load data from the server fetch: function(model, fields, domain, ctx){ return new instance.web.Model(model).query(fields).filter(domain).context(ctx).all() }, // loads all the needed data on the sever. returns a deferred indicating when all the data has loaded. load_server_data: function(){ var self = this; var loaded = self.fetch('res.users',['name','company_id'],[['id','=',this.session.uid]]) .then(function(users){ self.set('user',users[0]); return self.fetch('res.company', [ 'currency_id', 'email', 'website', 'company_registry', 'vat', 'name', 'phone', 'partner_id', ], [['id','=',users[0].company_id[0]]]); }).then(function(companies){ self.set('company',companies[0]); return self.fetch('res.partner',['contact_address'],[['id','=',companies[0].partner_id[0]]]); }).then(function(company_partners){ self.get('company').contact_address = company_partners[0].contact_address; return self.fetch('product.uom', null, null); }).then(function(units){ self.set('units',units); var units_by_id = {}; for(var i = 0, len = units.length; i < len; i++){ units_by_id[units[i].id] = units[i]; } self.set('units_by_id',units_by_id); return self.fetch('product.packaging', null, null); }).then(function(packagings){ self.set('product.packaging',packagings); return self.fetch('res.users', ['name','ean13'], [['ean13', '!=', false]]); }).then(function(users){ self.set('user_list',users); return self.fetch('res.partner', ['name','ean13'], [['ean13', '!=', false]]); }).then(function(partners){ self.set('partner_list',partners); return self.fetch('account.tax', ['amount', 'price_include', 'type']); }).then(function(taxes){ self.set('taxes', taxes); return self.fetch( 'pos.session', ['id', 'journal_ids','name','user_id','config_id','start_at','stop_at'], [['state', '=', 'opened'], ['user_id', '=', self.session.uid]] ); }).then(function(sessions){ self.set('pos_session', sessions[0]); return self.fetch( 'pos.config', ['name','journal_ids','shop_id','journal_id', 'iface_self_checkout', 'iface_led', 'iface_cashdrawer', 'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard', 'iface_print_via_proxy','iface_cashdrawer','state','sequence_id','session_ids'], [['id','=', self.get('pos_session').config_id[0]]] ); }).then(function(configs){ var pos_config = configs[0]; self.set('pos_config', pos_config); self.iface_electronic_scale = !!pos_config.iface_electronic_scale; self.iface_print_via_proxy = !!pos_config.iface_print_via_proxy; self.iface_vkeyboard = !!pos_config.iface_vkeyboard; self.iface_self_checkout = !!pos_config.iface_self_checkout; self.iface_cashdrawer = !!pos_config.iface_cashdrawer; return self.fetch('sale.shop',[],[['id','=',pos_config.shop_id[0]]]); }).then(function(shops){ self.set('shop',shops[0]); return self.fetch('product.pricelist',['currency_id'],[['id','=',self.get('shop').pricelist_id[0]]]); }).then(function(pricelists){ self.set('pricelist',pricelists[0]); return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('pricelist').currency_id[0]]]); }).then(function(currencies){ self.set('currency',currencies[0]); return self.fetch('product.packaging',['ean','product_id']); }).then(function(packagings){ self.db.add_packagings(packagings); return self.fetch('pos.category', ['id','name','parent_id','child_id','image']) }).then(function(categories){ self.db.add_categories(categories); return self.fetch( 'product.product', ['name', 'min_sale_price', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description'], [['sale_ok','=',true],['available_in_pos','=',true]], {pricelist: self.get('shop').pricelist_id[0]} // context for price ); }).then(function(products){ self.db.add_products(products); return self.fetch( 'account.bank.statement', ['account_id','currency','journal_id','state','name','user_id','pos_session_id'], [['state','=','open'],['pos_session_id', '=', self.get('pos_session').id]] ); }).then(function(bank_statements){ var journals = new Array(); _.each(bank_statements,function(statement) { journals.push(statement.journal_id[0]) }); self.set('bank_statements', bank_statements); return self.fetch('account.journal', undefined, [['id','in', journals]]); }).then(function(journals){ self.set('journals',journals); // associate the bank statements with their journals. var bank_statements = self.get('bank_statements'); for(var i = 0, ilen = bank_statements.length; i < ilen; i++){ for(var j = 0, jlen = journals.length; j < jlen; j++){ if(bank_statements[i].journal_id[0] === journals[j].id){ bank_statements[i].journal = journals[j]; bank_statements[i].self_checkout_payment_method = journals[j].self_checkout_payment_method; } } } self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))}); }); return loaded; }, // logs the usefull posmodel data to the console for debug purposes log_loaded_data: function(){ console.log('PosModel data has been loaded:'); console.log('PosModel: units:',this.get('units')); console.log('PosModel: bank_statements:',this.get('bank_statements')); console.log('PosModel: journals:',this.get('journals')); console.log('PosModel: taxes:',this.get('taxes')); console.log('PosModel: pos_session:',this.get('pos_session')); console.log('PosModel: pos_config:',this.get('pos_config')); console.log('PosModel: cashRegisters:',this.get('cashRegisters')); console.log('PosModel: shop:',this.get('shop')); console.log('PosModel: company:',this.get('company')); console.log('PosModel: currency:',this.get('currency')); console.log('PosModel: user_list:',this.get('user_list')); console.log('PosModel: user:',this.get('user')); console.log('PosModel.session:',this.session); console.log('PosModel end of data log.'); }, // this is called when an order is removed from the order collection. It ensures that there is always an existing // order and a valid selected order on_removed_order: function(removed_order){ if( this.get('orders').isEmpty()){ this.add_new_order(); }else{ this.set({ selectedOrder: this.get('orders').last() }); } }, // saves the order locally and try to send it to the backend. 'record' is a bizzarely defined JSON version of the Order push_order: function(record) { this.db.add_order(record); this.flush(); }, //creates a new empty order and sets it as the current order add_new_order: function(){ var order = new module.Order({pos:this}); this.get('orders').add(order); this.set('selectedOrder', order); }, // attemps to send all pending orders ( stored in the pos_db ) to the server, // and remove the successfully sent ones from the db once // it has been confirmed that they have been sent correctly. flush: function() { //TODO make the mutex work //this makes sure only one _int_flush is called at the same time /* return this.flush_mutex.exec(_.bind(function() { return this._flush(0); }, this)); */ this._flush(0); }, // attempts to send an order of index 'index' in the list of order to send. The index // is used to skip orders that failed. do not call this method outside the mutex provided // by flush() _flush: function(index){ var self = this; var orders = this.db.get_orders(); self.set('nbr_pending_operations',orders.length); var order = orders[index]; if(!order){ return; } //try to push an order to the server // shadow : true is to prevent a spinner to appear in case of timeout (new instance.web.Model('pos.order')).call('create_from_ui',[[order]],undefined,{ shadow:true }) .fail(function(unused, event){ //don't show error popup if it fails event.preventDefault(); console.error('Failed to send order:',order); self._flush(index+1); }) .done(function(){ //remove from db if success self.db.remove_order(order.id); self._flush(index); }); }, scan_product: function(parsed_ean){ var self = this; var product = this.db.get_product_by_ean13(parsed_ean.base_ean); var selectedOrder = this.get('selectedOrder'); if(!product){ return false; } if(parsed_ean.type === 'price'){ selectedOrder.addProduct(new module.Product(product), {price:parsed_ean.value}); }else if(parsed_ean.type === 'weight'){ selectedOrder.addProduct(new module.Product(product), {quantity:parsed_ean.value, merge:false}); }else{ selectedOrder.addProduct(new module.Product(product)); } return true; }, }); }

thanks!

2
Avatar
Zrušit
Avatar
Lithin T
Nejlepší odpověď

Here is the easy way to inherit PosModel to load new fields quick and fast

function pos_product_avialble(instance,module){ //where module=instance.point_of_sale
var models = module.PosModel.prototype.models;
for(var i=0; i<models.length; i++){
var model=models[i];
if(model.model === 'product.product'){
model.fields.push('new_field1','new_field2');
}
}
}

5
Avatar
Zrušit
Avatar
Ivan Elizaryev
Nejlepší odpověď

I think, right way is extend load_server_data function and then update product list by adding new fields:

function pos_product_available(instance, module){

    var PosModelSuper = module.PosModel
    module.PosModel = module.PosModel.extend({
        load_server_data: function(){
            var self = this;
            var loaded = PosModelSuper.prototype.load_server_data.call(this);

            loaded = loaded.then(function(){
                return self.fetch(
                    'product.product',
                    ['qty_available'], //new field
                    [['sale_ok','=',true],['available_in_pos','=',true]],
                    {}
                );

            }).then(function(products){
                $.each(products, function(){
                    $.extend(self.db.get_product_by_id(this.id) || {}, this)
                });
                return $.when()
            })
            return loaded;
        },
    })
}

(function(){
    var _super = window.openerp.point_of_sale;
    window.openerp.point_of_sale = function(instance){
        _super(instance);
        var module = instance.point_of_sale;

        pos_product_available(instance, module);

    }
})()

 

From here: https://github.com/yelizariev/pos-addons/blob/8.0/pos_product_available/static/src/js/pos.js

3
Avatar
Zrušit
Harold
Autor

Thanks for your answer

Nirav Jani

Is it working properly ?

Avatar
EasyPME
Nejlepší odpověď

Lithin T 's answer works

In Odoo v9 it is : 

odoo.define('pos_product_available', function (require) {

"use strict";

var module = require('point_of_sale.models');

var models = module.PosModel.prototype.models;

for(var i=0; i<models.length; i++){

var model=models[i];

if(model.model === 'product.product'){

model.fields.push('new_field1','new_field2');

}

}

});

0
Avatar
Zrušit
Peter Alabaster

This works in Odoo 10 too. Thanks

Enjoying the discussion? Don't just read, join in!

Create an account today to enjoy exclusive features and engage with our awesome community!

Přihlásit se
Related Posts Odpovědi Zobrazení Aktivita
Issue Migrating bus_service Notification Handling from Odoo 17 to Odoo 18 (OWL-based POS)
pos js
Avatar
0
dub 25
2708
How i can modify JS method in POS? Vyřešeno
pos js
Avatar
1
zář 23
8295
How to override js function in POS Orderline object? Vyřešeno
pos js
Avatar
Avatar
2
úno 18
11538
inherit js file odoo 9
inheritance js
Avatar
Avatar
2
čvc 17
5273
pos error js instance.web.cordova
pos js
Avatar
0
čvn 17
4634
Komunita
  • Tutoriály
  • Dokumentace
  • Fórum
Open Source
  • Stáhnout
  • Github
  • Runbot
  • Překlady
Služby
  • Odoo.sh hostování
  • Podpora
  • Upgrade
  • Nestandardní vývoj
  • Edukační program
  • Najít účetní
  • Najít partnera
  • Stát se partnerem
O nás
  • Naše společnost
  • Podklady značky
  • Kontakujte nás
  • Práce
  • Události
  • Podcast
  • Blog
  • Zákazníci
  • Právní dokumenty • Soukromí
  • Zabezpečení
الْعَرَبيّة Català 简体中文 繁體中文 (台灣) Čeština Dansk Nederlands English Suomi Français Deutsch हिंदी Bahasa Indonesia Italiano 日本語 한국어 (KR) Lietuvių kalba Język polski Português (BR) română русский язык Slovenský jazyk slovenščina Español (América Latina) Español ภาษาไทย Türkçe українська Tiếng Việt

Odoo je balíček open-source aplikací, které pokrývají všechny potřeby vaší společnosti: CRM, e-shop, účetnictví, sklady, kasy, projektové řízení a další.

Unikátní nabídka od Odoo poskytuje velmi jednoduché uživatelské rozhraní a vše je integrované na jednom místě.

Website made with

Odoo Experience on YouTube

1. Use the live chat to ask your questions.
2. The operator answers within a few minutes.

Live support on Youtube
Watch now