From 23c04baabdfe5df35d4aea2849004f86b285ce32 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 26 Nov 2024 14:15:31 +0700 Subject: before testing outgoing and incoming v2 --- indoteknik_custom/models/product_template.py | 79 +++++++++++++++++++++------- 1 file changed, 59 insertions(+), 20 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 25473ab8..3642c0d7 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -1,4 +1,4 @@ -from odoo import fields, models, api +from odoo import fields, models, api, tools, _ from datetime import datetime, timedelta, date from odoo.exceptions import UserError import logging @@ -482,33 +482,48 @@ class ProductProduct(models.Model): def _get_qty_incoming_bandengan(self): for product in self: - qty_incoming = self.env['stock.move'].search([ - ('product_id', '=', product.id), - ('location_dest_id', 'in', [57, 83]), - ('state', 'not in', ['done', 'cancel']) - ]) - qty = sum(qty_incoming.mapped('product_uom_qty')) + qty = self.env['stock.move'].read_group( + domain=[ + ('product_id', '=', product.id), + ('location_dest_id', 'in', [57, 83]), + ('state', 'not in', ['done', 'cancel', 'draft']) + ], + fields=['product_uom_qty'], + groupby=[] + )[0].get('product_uom_qty', 0.0) product.qty_incoming_bandengan = qty def _get_qty_incoming_bandengan_with_exclude(self): for product in self: - qty_incoming = self.env['stock.move'].search([ - ('product_id', '=', product.id), - ('location_dest_id', 'in', [57, 83]), - ('state', 'not in', ['done', 'cancel']) - ]) - qty = sum(qty_incoming.mapped('product_uom_qty')) + qty = self.env['stock.move'].read_group( + domain=[ + ('product_id', '=', product.id), + ('location_dest_id', 'in', [57, 83]), + ('state', 'not in', ['done', 'cancel', 'draft']) + ], + fields=['product_uom_qty'], + groupby=[] + )[0].get('product_uom_qty', 0.0) product.qty_incoming_bandengan = qty def _get_qty_outgoing_bandengan(self): for product in self: - qty_incoming = self.env['stock.move'].search([ - ('product_id', '=', product.id), - ('location_dest_id', '=', 5), - ('location_id', 'in', [57, 83]), - ('state', 'not in', ['done', 'cancel']) - ]) - qty = sum(qty_incoming.mapped('product_uom_qty')) + # qty_outgoing = self.env['stock.move'].search([ + # ('product_id', '=', product.id), + # # ('location_dest_id', '=', 5), + # ('location_id', 'in', [57, 83]), + # ('state', 'not in', ['done', 'cancel', 'draft']) + # ]) + # qty = sum(qty_outgoing.mapped('product_uom_qty')) + qty = self.env['stock.move'].read_group( + domain=[ + ('product_id', '=', product.id), + ('location_id', 'in', [57, 83]), + ('state', 'not in', ['done', 'cancel', 'draft']) + ], + fields=['product_uom_qty'], + groupby=[] + )[0].get('product_uom_qty', 0.0) product.qty_outgoing_bandengan = qty def _get_qty_onhand_bandengan(self): @@ -598,3 +613,27 @@ class ProductProduct(models.Model): ('end_date', '>=', current_time) ], limit=1) return pricelist + + +class OutstandingMove(models.Model): + _name = 'v.move.oustanding' + _auto = False + _rec_name = 'id' + + id = fields.Integer(string='ID') + product_id = fields.Many2one('product.product', string='Product') + reference = fields.Char(string='Reference', help='Nomor Dokumen terkait') + qty_need = fields.Float(string='Qty Need', help='Qty yang akan outgoing / incoming') + qty_reserved = fields.Float(string='Qty Reserved', help='Qty yang sudah ter-reserved jika outgoing') + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute(""" + CREATE OR REPLACE VIEW %s AS + select sml.id, sm.reference, sm.product_id, + sm.product_uom_qty as qty_need, sml.product_uom_qty as qty_reserved + from stock_move sm + join stock_move_line sml on sml.move_id = sm.id + where 1=1 + and sm.state not in('done', 'cancel', 'draft') + """ % self._table) -- cgit v1.2.3 From 75a1c83707d1c078e3e200e7bc3d3ca39497ad1c Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 26 Nov 2024 14:18:22 +0700 Subject: fix typo and add some comment --- indoteknik_custom/models/product_template.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 3642c0d7..df131ff6 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -616,7 +616,7 @@ class ProductProduct(models.Model): class OutstandingMove(models.Model): - _name = 'v.move.oustanding' + _name = 'v.move.outstanding' _auto = False _rec_name = 'id' @@ -627,6 +627,7 @@ class OutstandingMove(models.Model): qty_reserved = fields.Float(string='Qty Reserved', help='Qty yang sudah ter-reserved jika outgoing') def init(self): + # where clause 'state in' follow the origin of outgoing and incoming odoo tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" CREATE OR REPLACE VIEW %s AS @@ -635,5 +636,10 @@ class OutstandingMove(models.Model): from stock_move sm join stock_move_line sml on sml.move_id = sm.id where 1=1 - and sm.state not in('done', 'cancel', 'draft') + and sm.state in( + 'waiting', + 'confirmed', + 'assigned', + 'partially_available' + ) """ % self._table) -- cgit v1.2.3 From 2f5430e4a50d6203f1a0d0b7b70786d766bd235f Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 26 Nov 2024 14:44:36 +0700 Subject: change function of qty before test --- indoteknik_custom/models/product_template.py | 33 +++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index df131ff6..8d044695 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -482,48 +482,38 @@ class ProductProduct(models.Model): def _get_qty_incoming_bandengan(self): for product in self: - qty = self.env['stock.move'].read_group( + qty = self.env['v.move.outstanding'].read_group( domain=[ ('product_id', '=', product.id), ('location_dest_id', 'in', [57, 83]), - ('state', 'not in', ['done', 'cancel', 'draft']) ], - fields=['product_uom_qty'], + fields=['qty_need'], groupby=[] - )[0].get('product_uom_qty', 0.0) + )[0].get('qty_need', 0.0) product.qty_incoming_bandengan = qty def _get_qty_incoming_bandengan_with_exclude(self): for product in self: - qty = self.env['stock.move'].read_group( + qty = self.env['v.move.outstanding'].read_group( domain=[ ('product_id', '=', product.id), ('location_dest_id', 'in', [57, 83]), - ('state', 'not in', ['done', 'cancel', 'draft']) ], - fields=['product_uom_qty'], + fields=['qty_need'], groupby=[] - )[0].get('product_uom_qty', 0.0) + )[0].get('qty_need', 0.0) product.qty_incoming_bandengan = qty def _get_qty_outgoing_bandengan(self): for product in self: - # qty_outgoing = self.env['stock.move'].search([ - # ('product_id', '=', product.id), - # # ('location_dest_id', '=', 5), - # ('location_id', 'in', [57, 83]), - # ('state', 'not in', ['done', 'cancel', 'draft']) - # ]) - # qty = sum(qty_outgoing.mapped('product_uom_qty')) - qty = self.env['stock.move'].read_group( + qty = self.env['v.move.outstanding'].read_group( domain=[ ('product_id', '=', product.id), ('location_id', 'in', [57, 83]), - ('state', 'not in', ['done', 'cancel', 'draft']) ], - fields=['product_uom_qty'], + fields=['qty_reserved'], groupby=[] - )[0].get('product_uom_qty', 0.0) + )[0].get('qty_reserved', 0.0) product.qty_outgoing_bandengan = qty def _get_qty_onhand_bandengan(self): @@ -625,6 +615,8 @@ class OutstandingMove(models.Model): reference = fields.Char(string='Reference', help='Nomor Dokumen terkait') qty_need = fields.Float(string='Qty Need', help='Qty yang akan outgoing / incoming') qty_reserved = fields.Float(string='Qty Reserved', help='Qty yang sudah ter-reserved jika outgoing') + location_id = fields.Many2one('stock.location', string='Location', help='Lokasi asal') + location_dest_id = fields.Many2one('stock.location', string='Location To', help='Lokasi tujuan') def init(self): # where clause 'state in' follow the origin of outgoing and incoming odoo @@ -632,7 +624,8 @@ class OutstandingMove(models.Model): self.env.cr.execute(""" CREATE OR REPLACE VIEW %s AS select sml.id, sm.reference, sm.product_id, - sm.product_uom_qty as qty_need, sml.product_uom_qty as qty_reserved + sm.product_uom_qty as qty_need, sml.product_uom_qty as qty_reserved, + sm.location_id, sm.location_dest_id from stock_move sm join stock_move_line sml on sml.move_id = sm.id where 1=1 -- cgit v1.2.3 From 080e5ca9d4f312e2d7938f55e5ce8f7833b18b0d Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 26 Nov 2024 15:18:57 +0700 Subject: fix qty outgoing --- indoteknik_custom/models/product_template.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 8d044695..fe459ee3 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -511,9 +511,9 @@ class ProductProduct(models.Model): ('product_id', '=', product.id), ('location_id', 'in', [57, 83]), ], - fields=['qty_reserved'], + fields=['qty_need'], groupby=[] - )[0].get('qty_reserved', 0.0) + )[0].get('qty_need', 0.0) product.qty_outgoing_bandengan = qty def _get_qty_onhand_bandengan(self): @@ -614,7 +614,6 @@ class OutstandingMove(models.Model): product_id = fields.Many2one('product.product', string='Product') reference = fields.Char(string='Reference', help='Nomor Dokumen terkait') qty_need = fields.Float(string='Qty Need', help='Qty yang akan outgoing / incoming') - qty_reserved = fields.Float(string='Qty Reserved', help='Qty yang sudah ter-reserved jika outgoing') location_id = fields.Many2one('stock.location', string='Location', help='Lokasi asal') location_dest_id = fields.Many2one('stock.location', string='Location To', help='Lokasi tujuan') @@ -623,11 +622,10 @@ class OutstandingMove(models.Model): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" CREATE OR REPLACE VIEW %s AS - select sml.id, sm.reference, sm.product_id, - sm.product_uom_qty as qty_need, sml.product_uom_qty as qty_reserved, + select sm.id, sm.reference, sm.product_id, + sm.product_uom_qty as qty_need, sm.location_id, sm.location_dest_id from stock_move sm - join stock_move_line sml on sml.move_id = sm.id where 1=1 and sm.state in( 'waiting', -- cgit v1.2.3 From 0080b6b1da5f181cee32fae7bb5166ce65165374 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 29 Nov 2024 09:53:07 +0700 Subject: cr note product promotion --- indoteknik_custom/models/product_template.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 25473ab8..2e80beec 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -61,6 +61,7 @@ class ProductTemplate(models.Model): sni = fields.Boolean(string='SNI') tkdn = fields.Boolean(string='TKDN') short_spesification = fields.Char(string='Short Spesification') + merchandise_ok = fields.Boolean(string='Product Promotion') @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): @@ -377,6 +378,7 @@ class ProductProduct(models.Model): max_qty_reorder = fields.Float(string='Max Qty Reorder', compute='_get_max_qty_reordering_rule') qty_rpo = fields.Float(string='Qty RPO', compute='_get_qty_rpo') plafon_qty = fields.Float(string='Max Plafon', compute='_get_plafon_qty_product') + merchandise_ok = fields.Boolean(string='Product Promotion') def _get_clean_website_description(self): for rec in self: -- cgit v1.2.3 From c60a7a4b0844fe04ec29656b185b9fa80d398c26 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 4 Dec 2024 14:10:10 +0700 Subject: add validation mandatory category --- indoteknik_custom/models/product_template.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 4d186568..6fb8c7a0 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -66,7 +66,7 @@ class ProductTemplate(models.Model): @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): for rec in self: - if not rec.public_categ_ids: + if not rec.public_categ_ids and rec.type == 'product': raise UserError('Field Categories harus diisi') def _get_qty_sold(self): @@ -388,7 +388,7 @@ class ProductProduct(models.Model): @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): for rec in self: - if not rec.public_categ_ids: + if not rec.public_categ_ids and rec.type == 'product': raise UserError('Field Categories harus diisi') @api.constrains('active') -- cgit v1.2.3 From 9dbae80871e94f439ea1b6c3cf6a13cab9221532 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 10 Dec 2024 10:27:44 +0700 Subject: barcode product --- indoteknik_custom/models/product_template.py | 43 +++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 6fb8c7a0..ebf81811 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -5,7 +5,9 @@ import logging import requests import json import re +import qrcode, base64 from bs4 import BeautifulSoup +from io import BytesIO _logger = logging.getLogger(__name__) @@ -58,10 +60,30 @@ class ProductTemplate(models.Model): ('sp', 'Spare Part'), ('acc', 'Accessories') ], string='Kind of', copy=False) - sni = fields.Boolean(string='SNI') + sni = fields.Boolean(string='SNI') tkdn = fields.Boolean(string='TKDN') short_spesification = fields.Char(string='Short Spesification') merchandise_ok = fields.Boolean(string='Product Promotion') + print_barcode = fields.Boolean(string='Print Barcode', default="True") + qr_code = fields.Binary("QR Code", compute='_compute_qr_code') + + def _compute_qr_code(self): + for rec in self.product_variant_ids: + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=5, + border=4, + ) + qr.add_data(rec.display_name) + qr.make(fit=True) + img = qr.make_image(fill_color="black", back_color="white") + + buffer = BytesIO() + img.save(buffer, format="PNG") + qr_code_img = base64.b64encode(buffer.getvalue()).decode() + + rec.qr_code = qr_code_img @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): @@ -379,6 +401,25 @@ class ProductProduct(models.Model): qty_rpo = fields.Float(string='Qty RPO', compute='_get_qty_rpo') plafon_qty = fields.Float(string='Max Plafon', compute='_get_plafon_qty_product') merchandise_ok = fields.Boolean(string='Product Promotion') + qr_code_variant = fields.Binary("QR Code Variant", compute='_compute_qr_code_variant') + + def _compute_qr_code_variant(self): + for rec in self.product_variant_ids: + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=5, + border=4, + ) + qr.add_data(rec.display_name) + qr.make(fit=True) + img = qr.make_image(fill_color="black", back_color="white") + + buffer = BytesIO() + img.save(buffer, format="PNG") + qr_code_img = base64.b64encode(buffer.getvalue()).decode() + + rec.qr_code_variant = qr_code_img def _get_clean_website_description(self): for rec in self: -- cgit v1.2.3 From cc9abe07512a6e317dc82f6a4be626c55f298379 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 10 Dec 2024 11:25:10 +0700 Subject: fix bug --- indoteknik_custom/models/product_template.py | 38 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index ebf81811..b38f9155 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -65,25 +65,25 @@ class ProductTemplate(models.Model): short_spesification = fields.Char(string='Short Spesification') merchandise_ok = fields.Boolean(string='Product Promotion') print_barcode = fields.Boolean(string='Print Barcode', default="True") - qr_code = fields.Binary("QR Code", compute='_compute_qr_code') - - def _compute_qr_code(self): - for rec in self.product_variant_ids: - qr = qrcode.QRCode( - version=1, - error_correction=qrcode.constants.ERROR_CORRECT_L, - box_size=5, - border=4, - ) - qr.add_data(rec.display_name) - qr.make(fit=True) - img = qr.make_image(fill_color="black", back_color="white") - - buffer = BytesIO() - img.save(buffer, format="PNG") - qr_code_img = base64.b64encode(buffer.getvalue()).decode() - - rec.qr_code = qr_code_img + # qr_code = fields.Binary("QR Code", compute='_compute_qr_code') + + # def _compute_qr_code(self): + # for rec in self.product_variant_ids: + # qr = qrcode.QRCode( + # version=1, + # error_correction=qrcode.constants.ERROR_CORRECT_L, + # box_size=5, + # border=4, + # ) + # qr.add_data(rec.display_name) + # qr.make(fit=True) + # img = qr.make_image(fill_color="black", back_color="white") + + # buffer = BytesIO() + # img.save(buffer, format="PNG") + # qr_code_img = base64.b64encode(buffer.getvalue()).decode() + + # rec.qr_code = qr_code_img @api.constrains('name', 'internal_reference', 'x_manufacture') def required_public_categ_ids(self): -- cgit v1.2.3 From 335d724a7f359223138de74bf682cfc3530b5ea7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 11 Dec 2024 08:44:08 +0700 Subject: cr default qr code product variants --- indoteknik_custom/models/product_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index b38f9155..00e756c9 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -64,7 +64,7 @@ class ProductTemplate(models.Model): tkdn = fields.Boolean(string='TKDN') short_spesification = fields.Char(string='Short Spesification') merchandise_ok = fields.Boolean(string='Product Promotion') - print_barcode = fields.Boolean(string='Print Barcode', default="True") + print_barcode = fields.Boolean(string='Print Barcode', default=True) # qr_code = fields.Binary("QR Code", compute='_compute_qr_code') # def _compute_qr_code(self): -- cgit v1.2.3 From d35c2dce88a87bc05d30c4935d51d7d58aa5d37d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 19 Dec 2024 10:33:53 +0700 Subject: fix qr code variant --- indoteknik_custom/models/product_template.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 00e756c9..9007dd71 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -404,12 +404,17 @@ class ProductProduct(models.Model): qr_code_variant = fields.Binary("QR Code Variant", compute='_compute_qr_code_variant') def _compute_qr_code_variant(self): - for rec in self.product_variant_ids: + for rec in self: + # Skip inactive variants + if not rec.active: + rec.qr_code_variant = False # Clear the QR Code for archived variants + continue + qr = qrcode.QRCode( - version=1, - error_correction=qrcode.constants.ERROR_CORRECT_L, - box_size=5, - border=4, + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=5, + border=4, ) qr.add_data(rec.display_name) qr.make(fit=True) -- cgit v1.2.3 From 509245ca0f8c208dfcbc50de63032fce7fb11e12 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 10 Jan 2025 15:12:20 +0700 Subject: cr qr code product --- indoteknik_custom/models/product_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/product_template.py') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 9007dd71..5bedae13 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -416,7 +416,7 @@ class ProductProduct(models.Model): box_size=5, border=4, ) - qr.add_data(rec.display_name) + qr.add_data(rec.default_code) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") -- cgit v1.2.3