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 +++++++++++++++++++++++++++- indoteknik_custom/models/stock_move.py | 12 ++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') 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: diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index ac2e3cc0..8214a057 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -7,6 +7,18 @@ class StockMove(models.Model): line_no = fields.Integer('No', default=0) sale_id = fields.Many2one('sale.order', string='SO') + print_barcode = fields.Boolean( + string="Print Barcode", + default=lambda self: self.product_id.print_barcode, + ) + + def write(self, vals): + res = super(StockMove, self).write(vals) + if 'print_barcode' in vals: + for line in self: + if line.product_id: + line.product_id.print_barcode = vals['print_barcode'] + return res def _do_unreserve(self, product=None, quantity=False): moves_to_unreserve = OrderedSet() -- 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') 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 8e9b91259ecd62eff4e17210678287b844f78132 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 10 Dec 2024 16:13:37 +0700 Subject: test wati --- indoteknik_custom/models/wati.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py index f3632334..ec7bd3b9 100644 --- a/indoteknik_custom/models/wati.py +++ b/indoteknik_custom/models/wati.py @@ -217,26 +217,42 @@ class WatiHistory(models.Model): limit = 50 wati_histories = self.env['wati.history'].search(domain, limit=limit) count = 0 + for wati_history in wati_histories: count += 1 - _logger.info('[Parse Notification] Process: %s/%s' % (str(count), str(limit))) + _logger.info('[Parse Notification] Processing: %s/%s', count, limit) wati_api = self.env['wati.api'] - # Perbaikan pada params 'attribute' untuk menghindari masalah "type object is not subscriptable" + # Perbaikan pada parameter JSON params = { 'pageSize': 1, 'pageNumber': 1, - 'attribute': json.dumps([{'name': "phone", 'operator': "contain", 'value': wati_history.wa_id}]), + 'attribute': json.dumps([ + {'name': "phone", 'operator': "contain", 'value': wati_history.wa_id} + ]), } - wati_contacts = wati_api.http_get('/api/v1/getContacts', params) + try: + wati_contacts = wati_api.http_get('/api/v1/getContacts', params) + except Exception as e: + _logger.error('Error while calling WATI API: %s', str(e)) + continue + # Validasi respons dari API + if not isinstance(wati_contacts, dict): + _logger.error('Invalid response format from WATI API: %s', wati_contacts) + continue + if wati_contacts.get('result') != 'success': - return + _logger.warning('WATI API request failed with result: %s', wati_contacts.get('result')) + continue contact_list = wati_contacts.get('contact_list', []) - + if not contact_list: + _logger.info('No contacts found for WA ID: %s', wati_history.wa_id) + continue + perusahaan = email = '' for data in contact_list: custom_params = data.get('customParams', []) @@ -247,12 +263,14 @@ class WatiHistory(models.Model): perusahaan = value elif name == 'email': email = value - # End inner loop # Update wati_history fields - wati_history.perusahaan = perusahaan - wati_history.email = email - wati_history.is_get_attribute = True + wati_history.write({ + 'perusahaan': perusahaan, + 'email': email, + 'is_get_attribute': True, + }) + _logger.info('Wati history updated: %s', wati_history.id) # @api.onchange('last_reply_date') # def _compute_expired_date(self): -- cgit v1.2.3 From 72f8f3081d29b100e159f766e1c3483bdef5ce45 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 10 Dec 2024 16:24:43 +0700 Subject: fix bug wati --- indoteknik_custom/models/wati.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py index ec7bd3b9..a0619f83 100644 --- a/indoteknik_custom/models/wati.py +++ b/indoteknik_custom/models/wati.py @@ -32,28 +32,43 @@ class WatiNotification(models.Model): ]).unlink() _logger.info('Success Cleanup WATI Notification') - def _parse_notification(self, limit = 0): + def _parse_notification(self, limit=0): domain = [('is_parsed', '=', False)] notifications = self.search(domain, order='id', limit=limit) notification_not_parsed_count = self.search_count(domain) i = 0 for notification in notifications: i += 1 - _logger.info('[Parse Notification][%s] Process: %s/%s | Not Parsed: %s' % (notification.id, i, str(limit), str(notification_not_parsed_count))) + _logger.info('[Parse Notification][%s] Process: %s/%s | Not Parsed: %s' % + (notification.id, i, str(limit), str(notification_not_parsed_count))) + notification_json = json.loads(notification.json_raw) sender_name = 'Indoteknik' if 'senderName' in notification_json: sender_name = notification_json['senderName'] - ticket_id = notification_json['ticketId'] - date_wati = float(notification_json['timestamp']) - date_wati = datetime.fromtimestamp(date_wati) + ticket_id = notification_json.get('ticketId') + timestamp = notification_json.get('timestamp') + + if not timestamp: + _logger.warning('[Parse Notification][%s] Missing timestamp in notification JSON: %s' % + (notification.id, notification.json_raw)) + continue # Skip this notification + + try: + date_wati = datetime.fromtimestamp(float(timestamp)) + except ValueError as e: + _logger.error('[Parse Notification][%s] Invalid timestamp format: %s. Error: %s' % + (notification.id, timestamp, str(e))) + continue + wati_history = self.env['wati.history'].search([('ticket_id', '=', ticket_id)], limit=1) if wati_history: self._create_wati_history_line(wati_history, ticket_id, sender_name, notification_json, date_wati) else: new_header = self._create_wati_history_header(ticket_id, sender_name, notification_json, date_wati) self._create_wati_history_line(new_header, ticket_id, sender_name, notification_json, date_wati) + notification.is_parsed = True return -- 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') 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