diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-01 06:13:19 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-01 06:13:19 +0700 |
| commit | 956be5a7ac4cd008dad9c854f1ba2e5b1346cc01 (patch) | |
| tree | 58de506497a0562748487ada2d9c9906906836a7 | |
| parent | 1f3660c422500d06676547e10292536b7a6a5f8b (diff) | |
| parent | 4f29a01888d72ffe07ebffa4e9e0637efb2495d2 (diff) | |
Merge branch 'main' of bitbucket.org:altafixco/fixco-addons
# Conflicts:
# fixco_custom/models/webhook_ginee.py
| -rw-r--r-- | fixco_custom/models/account_move.py | 13 | ||||
| -rwxr-xr-x | fixco_custom/models/detail_order.py | 92 | ||||
| -rwxr-xr-x | fixco_custom/models/webhook_ginee.py | 25 |
3 files changed, 70 insertions, 60 deletions
diff --git a/fixco_custom/models/account_move.py b/fixco_custom/models/account_move.py index 63b3e8e..58c94f7 100644 --- a/fixco_custom/models/account_move.py +++ b/fixco_custom/models/account_move.py @@ -1,3 +1,4 @@ +from cmath import e from odoo import models, api, fields, _ from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date, datetime @@ -63,7 +64,7 @@ class AccountMove(models.Model): def export_faktur_to_xml(self): valid_invoices = self - + coretax_faktur = self.env['coretax.faktur'].create({}) response = coretax_faktur.export_to_download( @@ -130,7 +131,7 @@ class AccountMove(models.Model): 'target': 'current', 'domain': [('id', 'in', list(reverses.ids))], } - + def action_reverse(self): action = self.env["ir.actions.actions"]._for_xml_id("account.action_view_account_move_reversal") @@ -198,10 +199,12 @@ class AccountMove(models.Model): res = super(AccountMove, self).action_post() for entry in self: if entry.move_type == 'out_invoice': - entry.invoice_date = entry.picking_id.date_done + if entry.picking_id: + entry.invoice_date = entry.picking_id.date_done + return res - + @api.onchange('purchase_vendor_bill_ids', 'purchase_id') def _onchange_purchase_auto_complete(self): """ Load from either multiple old purchase orders or vendor bills. """ @@ -235,7 +238,7 @@ class AccountMove(models.Model): new_lines += new_line new_lines._onchange_mark_recompute_taxes() - + # Compute invoice_origin origins = set(self.line_ids.mapped('purchase_line_id.order_id.name')) diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py index 3e2a6d8..41a5466 100755 --- a/fixco_custom/models/detail_order.py +++ b/fixco_custom/models/detail_order.py @@ -48,20 +48,26 @@ class DetailOrder(models.Model): def get_order_id(self): try: - if self.json_ginee: + if self.json_ginee: json_data = json.loads(self.json_ginee) order_id = json_data.get('payload', {}).get('orderId') if not order_id: raise UserError(_("Order ID not found in JSON data")) - return order_id + return order_id raise UserError(_("No JSON data available")) except json.JSONDecodeError: raise UserError(_("Invalid JSON format in json_ginee field")) except Exception as e: raise UserError(_("Error extracting order ID: %s") % str(e)) + # def process_queue_item(self, limit=100): + # domain = [('create_date', '>', '2025-12-31 23:59:59')] + # records = self.search(domain, order='create_date asc', limit=limit) + # for rec in records: + # rec.execute_queue() + def process_queue_item(self, limit=100): - domain = [('create_date', '>', '2025-12-31 23:59:59')] + domain = [('execute_status', '=', False)] records = self.search(domain, order='create_date asc', limit=limit) for rec in records: rec.execute_queue() @@ -70,28 +76,28 @@ class DetailOrder(models.Model): def execute_queue(self): try: order_id = self.get_order_id() - + authorization = self.sign_request() headers = { 'Content-Type': 'application/json', 'X-Advai-Country': 'ID', 'Authorization': authorization } - + payload = { "orderIds": [order_id] } - + # URL endpoint Ginee url = "https://api.ginee.com/openapi/order/v1/batch-get" - + # Melakukan POST request response = requests.post( url, headers=headers, data=json.dumps(payload) ) - + # Cek status response if response.status_code == 200: data = response.json() @@ -104,7 +110,7 @@ class DetailOrder(models.Model): 'response': response.text }) }) - + except Exception as e: self.write({ 'message_error': json.dumps({ @@ -118,7 +124,7 @@ class DetailOrder(models.Model): def get_order_id_detail(self): try: - if self.detail_order: + if self.detail_order: json_data = json.loads(self.detail_order) order_id = json_data.get('data', {})[0].get('orderId') order_status = json_data.get('data', {})[0].get('orderStatus') @@ -131,7 +137,7 @@ class DetailOrder(models.Model): raise UserError(_("Invalid JSON format in detail_order field")) except Exception as e: raise UserError(_("Error extracting order ID: %s") % str(e)) - + def process_queue_item_detail(self, limit=100): domain = [ ('execute_status', '=', 'detail_order'), @@ -142,7 +148,7 @@ class DetailOrder(models.Model): ] records = self.search(domain, order='create_date desc', limit=limit) - + for i, rec in enumerate(records, 1): try: rec.execute_queue_detail() @@ -151,9 +157,9 @@ class DetailOrder(models.Model): except Exception as e: _logger.error("Failed to process record %s: %s", rec.id, str(e)) self.env.cr.rollback() - + self.env.cr.commit() - + def get_partner(self, shop_id): partner = self.env['res.partner'].search([('ginee_shop_id', '=', shop_id)], limit=1) if not partner: @@ -172,7 +178,7 @@ class DetailOrder(models.Model): 'channel': json_data.get('data', {})[0].get('channel'), } return data - + def _combine_order_items(self, items): """Combine quantities of the same products from multiple orders""" product_quantities = {} @@ -190,25 +196,25 @@ class DetailOrder(models.Model): 'item_data': item # Keep original item data } return product_quantities - + def prepare_data_so_line(self, json_data): order_lines = [] product_not_found = False - + # Get all items (already combined if grouped) items = json_data.get('data', [{}])[0].get('items', []) - + # Combine quantities of the same products product_quantities = self._combine_order_items(items) - + # Process the combined items for sku, combined_item in product_quantities.items(): item = combined_item['item_data'] product = self.env['product.product'].search( - [('default_code', '=', sku)], + [('default_code', '=', sku)], limit=1 ) - + if product and item.get('masterSkuType') == 'BUNDLE': order_lines.append((0, 0, { 'display_type': 'line_note', @@ -216,18 +222,18 @@ class DetailOrder(models.Model): 'product_uom_qty': 0, 'price_unit': 0, })) - + bundling_lines = self.env['bundling.line'].search([('product_id', '=', product.id)]) bundling_variant_ids = bundling_lines.mapped('variant_id').ids sale_pricelist = self.env['product.pricelist.item'].search([ - ('product_id', 'in', bundling_variant_ids), + ('product_id', 'in', bundling_variant_ids), ('pricelist_id', '=', 17) ]) price_bundling_bottom = sum(item.fixed_price for item in sale_pricelist) - + for bline in bundling_lines: bottom_price = self.env['product.pricelist.item'].search([ - ('product_id', '=', bline.variant_id.id), + ('product_id', '=', bline.variant_id.id), ('pricelist_id', '=', 17) ], limit=1) price = bottom_price.fixed_price @@ -251,43 +257,43 @@ class DetailOrder(models.Model): 'price_unit': 0, })) continue - + # Regular product line line_data = { 'product_id': product.id if product else 5792, 'product_uom_qty': combined_item['quantity'], 'price_unit': combined_item['actualPrice'], } - + if not product: line_data['name'] = f"{sku} ({combined_item['productName']})" product_not_found = True - + order_lines.append((0, 0, line_data)) - + return order_lines, product_not_found - def execute_queue_detail(self): + def execute_queue_detail(self): try: json_data = json.loads(self.detail_order) data = self.prepare_data_so(json_data) order_lines, product_not_found = self.prepare_data_so_line(json_data) order_id, order_status, print_info = self.get_order_id_detail() - + # First check if a sale order with this reference already exists existing_order = self.env['sale.order'].search([('order_reference', '=', order_id)], limit=1) - + if order_status == 'CANCELLED': external_order_id = json_data.get('data', [{}])[0].get('externalOrderId') order_id = json_data.get('data', [{}])[0].get('orderId') - + # Try to find existing SO existing_order = self.env['sale.order'].search([ '|', ('invoice_mp', '=', external_order_id), ('client_order_ref', '=', order_id) ], limit=1) - + if existing_order: if existing_order.state == 'sale': # Cancel all pickings linked to this order @@ -301,22 +307,22 @@ class DetailOrder(models.Model): existing_order.action_cancel() self.sale_id = existing_order.id self.execute_status = 'cancelled_so' - + else: # If no existing SO, create one, then cancel data = self.prepare_data_so(json_data) order_lines, product_not_found = self.prepare_data_so_line(json_data) data['order_line'] = order_lines sale_order = self.env['sale.order'].create(data) - + self.sale_id = sale_order.id sale_order.order_reference = order_id sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', []) sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', []) - + sale_order.action_cancel() self.execute_status = 'cancelled_so_created' - + return if existing_order: @@ -325,11 +331,11 @@ class DetailOrder(models.Model): self.execute_status = 'already_so' return # Exit early since we don't need to create anything - if order_status != 'PENDING_PAYMENT': + if order_status != 'PENDING_PAYMENT': if order_status in ('PARTIALLY_PAID', 'PAID'): data['order_line'] = order_lines sale_order = self.env['sale.order'].create(data) - + self.sale_id = sale_order.id sale_order.order_reference = order_id sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', []) @@ -350,7 +356,7 @@ class DetailOrder(models.Model): # For other statuses, create new order only if it doesn't exist data['order_line'] = order_lines sale_order = self.env['sale.order'].create(data) - + self.sale_id = sale_order.id sale_order.order_reference = order_id sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', []) @@ -381,9 +387,9 @@ class DetailOrder(models.Model): hmac.new(SECRET_KEY.encode('utf-8'), signData.encode('utf-8'), digestmod=sha256).digest() ).decode('ascii') return authorization - + def prorate_price_bundling(self, product, sum_bottom, price_bottom,actual_price): percent = price_bottom / sum_bottom real_price = percent * actual_price - return real_price
\ No newline at end of file + return real_price diff --git a/fixco_custom/models/webhook_ginee.py b/fixco_custom/models/webhook_ginee.py index 606bd21..444306b 100755 --- a/fixco_custom/models/webhook_ginee.py +++ b/fixco_custom/models/webhook_ginee.py @@ -19,23 +19,24 @@ class WebhookGinee(models.Model): ('not_found', 'Record not found') ], 'Execute Status') - # def process_queue_item(self, limit=100, max_exec_time=30): - # domain = [('execute_status', '=', False)] - # records = self.search(domain, order='create_date asc', limit=limit) - # start_time = time.time() - # for rec in records: - # end_time = time.time() - # elapsed_time = end_time - start_time - # if elapsed_time > max_exec_time: - # break - # rec.execute_queue() - - def process_queue_item(self, limit=100): + def process_queue_item(self, limit=100, max_exec_time=30): domain = [('execute_status', '=', False)] records = self.search(domain, order='create_date asc', limit=limit) + start_time = time.time() for rec in records: + end_time = time.time() + elapsed_time = end_time - start_time + if elapsed_time > max_exec_time: + break rec.execute_queue() + # def process_queue_item(self, limit=100): + # domain = [('create_date', '>', '2025-12-31 23:59:59')] + # records = self.search(domain, order='create_date asc', limit=limit) + # for rec in records: + # rec.execute_queue() + + def execute_queue(self): detail_order = self.env['detail.order'].create({ 'json_ginee': self.json_ginee, |
