diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-06-28 08:54:35 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-06-28 08:54:35 +0700 |
| commit | be3af87277be6d884abbcc9f584f52a3871a6869 (patch) | |
| tree | ccca579890fd93518eeb9b8ad646de0363172139 | |
| parent | 87f6bc09d6fe91526116301375efc544f31be625 (diff) | |
schema SO Blibli
| -rw-r--r-- | fixco_custom/models/account_move.py | 10 | ||||
| -rwxr-xr-x | fixco_custom/models/detail_order.py | 62 | ||||
| -rw-r--r-- | fixco_custom/models/upload_ginee.py | 86 | ||||
| -rwxr-xr-x | fixco_custom/views/detail_order.xml | 4 |
4 files changed, 142 insertions, 20 deletions
diff --git a/fixco_custom/models/account_move.py b/fixco_custom/models/account_move.py index 82223b6..0cdc22d 100644 --- a/fixco_custom/models/account_move.py +++ b/fixco_custom/models/account_move.py @@ -22,4 +22,12 @@ class AccountMove(models.Model): [('digunggung', 'Digunggung'), ('difaktur', 'Faktur Pajak')], string='Transaction Type' - )
\ No newline at end of file + ) + + + def action_post(self): + res = super(AccountMove, self).action_post() + for entry in self: + entry.invoice_date = entry.picking_id.date_done + + return res
\ No newline at end of file diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py index b0940a8..f0c0760 100755 --- a/fixco_custom/models/detail_order.py +++ b/fixco_custom/models/detail_order.py @@ -38,6 +38,8 @@ class DetailOrder(models.Model): picking_id = fields.Many2one('stock.picking', 'Picking') invoice_id = fields.Many2one('account.move', 'Invoice') message_error = fields.Text('Message Error') + is_grouped_order = fields.Boolean('Is Grouped Order', default=False) + original_order_ids = fields.Char('Original Order IDs') # get detail order section @@ -161,37 +163,74 @@ class DetailOrder(models.Model): 'invoice_mp': json_data.get('data', {})[0].get('externalOrderId'), } return data + + def _combine_order_items(self, items): + """Combine quantities of the same products from multiple orders""" + product_quantities = {} + for item in items: + key = item.get('masterSku') + if key in product_quantities: + product_quantities[key]['quantity'] += item.get('quantity', 0) + product_quantities[key]['actualPrice'] += item.get('actualPrice', 0) + else: + product_quantities[key] = { + 'quantity': item.get('quantity', 0), + 'actualPrice': item.get('actualPrice', 0), + 'productName': item.get('productName'), + 'masterSkuType': item.get('masterSkuType'), + 'item_data': item # Keep original item data + } + return product_quantities def prepare_data_so_line(self, json_data): order_lines = [] - items = json_data.get('data', [{}])[0].get('items', []) product_not_found = False - for item in items: + # 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', '=', item.get('masterSku'))], + [('default_code', '=', sku)], limit=1 ) if product and item.get('masterSkuType') == 'BUNDLE': order_lines.append((0, 0, { 'display_type': 'line_note', - 'name': f"Bundle: {item.get('productName')}, Qty: {item.get('quantity')}, Master SKU: {item.get('masterSku')}", + 'name': f"Bundle: {item.get('productName')}, Qty: {combined_item['quantity']}, Master SKU: {sku}", '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), ('pricelist_id', '=', 17)]) + sale_pricelist = self.env['product.pricelist.item'].search([ + ('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), ('pricelist_id', '=', 17)], limit=1) + bottom_price = self.env['product.pricelist.item'].search([ + ('product_id', '=', bline.variant_id.id), + ('pricelist_id', '=', 17) + ], limit=1) price = bottom_price.fixed_price - price_unit = self.prorate_price_bundling(bline.variant_id,price_bundling_bottom,price,actual_price=item.get('actualPrice')) + price_unit = self.prorate_price_bundling( + bline.variant_id, + price_bundling_bottom, + price, + actual_price=combined_item['actualPrice']/combined_item['quantity'] # Use average price + ) order_lines.append((0, 0, { 'product_id': bline.variant_id.id if bline.variant_id else product.id, - 'product_uom_qty': bline.product_uom_qty * item.get('quantity') if bline.product_uom_qty else item.get('quantity'), + 'product_uom_qty': bline.product_uom_qty * combined_item['quantity'], 'price_unit': price_unit, 'name': f"{bline.variant_id.display_name} (Bundle Component)" if bline.variant_id.display_name else product.name, })) @@ -204,14 +243,15 @@ class DetailOrder(models.Model): })) continue + # Regular product line line_data = { 'product_id': product.id if product else 5792, - 'product_uom_qty': item.get('quantity'), - 'price_unit': item.get('actualPrice'), + 'product_uom_qty': combined_item['quantity'], + 'price_unit': combined_item['actualPrice'] / combined_item['quantity'], # Average price } if not product: - line_data['name'] = f"{item.get('masterSku')} ({item.get('productName')})" + line_data['name'] = f"{sku} ({combined_item['productName']})" product_not_found = True order_lines.append((0, 0, line_data)) diff --git a/fixco_custom/models/upload_ginee.py b/fixco_custom/models/upload_ginee.py index c19fa03..f69e7d2 100644 --- a/fixco_custom/models/upload_ginee.py +++ b/fixco_custom/models/upload_ginee.py @@ -178,6 +178,48 @@ class UploadGineeLine(models.Model): order_id = fields.Char('Order ID') message_error = fields.Text('Error Message') detail_order_id = fields.Many2one('detail.order', string='Detail Order') + is_grouped = fields.Boolean('Is Grouped', default=False) + group_key = fields.Char('Group Key') + + def _process_grouped_blibli_orders(self, lines): + """Process a group of BLIBLI orders with the same invoice prefix""" + order_ids = [line.order_id for line in lines if line.order_id] + + if not order_ids: + raise UserError(_('Order ID is empty for one or more records in group!')) + + # Check if any of these orders already exist + existing_detail = self.env['detail.order'].search([ + ('detail_order', 'ilike', order_ids[0]) + ], limit=1) + + if existing_detail: + return existing_detail + + # Call API with all order IDs in the group + data = lines[0]._call_api(BATCH_GET_URI, {"orderIds": order_ids}) + + # Combine items from all orders in the group + combined_items = [] + for order_data in data.get('data', []): + combined_items.extend(order_data.get('items', [])) + + # Create a modified json_data structure that includes all items + combined_json_data = { + 'data': [{ + **data.get('data', [{}])[0], # Keep all original fields from first order + 'items': combined_items, # Combined items from all orders + 'shopId': data.get('data', [{}])[0].get('shopId'), + 'externalOrderId': ', '.join([line.invoice_marketplace for line in lines]), + 'orderId': ', '.join(order_ids), # Mark as grouped + }] + } + + detail_order = self.env['detail.order'].create({ + 'detail_order': json.dumps(combined_json_data, indent=4), + 'source': 'manual', + }) + return detail_order def _sign_request(self, uri): """Membuat tanda tangan sesuai format yang berhasil""" @@ -210,32 +252,64 @@ class UploadGineeLine(models.Model): return response.json() def create_so_and_detail_order(self): + # First group BLIBLI orders by their invoice prefix + grouped_lines = {} for rec in self: + if rec.upload_ginee_id.upload_type == 'blibli' and '-' in rec.invoice_marketplace: + prefix = rec.invoice_marketplace.split('-')[0] + if prefix not in grouped_lines: + grouped_lines[prefix] = [] + grouped_lines[prefix].append(rec) + else: + # For non-BLIBLI or BLIBLI without dash, process individually + grouped_lines[rec.id] = [rec] + + # Process each group + for group_key, lines in grouped_lines.items(): try: - if not rec.order_id: + if len(lines) > 1: + # Process grouped BLIBLI orders + detail_order = self._process_grouped_blibli_orders(lines) + + # Update all lines in the group + for line in lines: + line.update({ + 'message_error': 'Success (grouped)', + 'detail_order_id': detail_order.id + }) + detail_order.execute_queue_detail() + else: + # Process single line (non-grouped) + line = lines[0] + if not line.order_id: raise UserError(_('Order ID is empty!')) - if self.env['detail.order'].search([('detail_order', 'ilike', rec.order_id)]): + if self.env['detail.order'].search([('detail_order', 'ilike', line.order_id)]): raise UserError(_( - "Order ID %s already exists in Detail Orders") % rec.order_id) + "Order ID %s already exists in Detail Orders") % line.order_id) - data = self._call_api(BATCH_GET_URI, {"orderIds": [rec.order_id]}) + data = line._call_api(BATCH_GET_URI, {"orderIds": [line.order_id]}) detail_order = self.env['detail.order'].create({ 'detail_order': json.dumps(data, indent=4), 'source': 'manual', }) detail_order.execute_queue_detail() - rec.update({ + line.update({ 'message_error': 'Success', 'detail_order_id': detail_order.id }) + except Exception as e: - rec.message_error = str(e) + # Update all lines in group with error if any + for line in lines: + line.message_error = str(e) def get_order_id(self): for rec in self: try: + if rec.order_id: + continue if self.search_count([ ('marketplace', '=', rec.marketplace), ('invoice_marketplace', '=', rec.invoice_marketplace), diff --git a/fixco_custom/views/detail_order.xml b/fixco_custom/views/detail_order.xml index 586e10d..422c471 100755 --- a/fixco_custom/views/detail_order.xml +++ b/fixco_custom/views/detail_order.xml @@ -27,12 +27,12 @@ <button name="execute_queue" string="Create Detail Order" type="object" - attrs="{'invisible': [('detail_order', '=', False)]}" + attrs="{'invisible': [('detail_order', '!=', True)]}" /> <button name="execute_queue_detail" string="Create SO" type="object" - attrs="{'invisible': [('sale_id', '=', False)]}" + attrs="{'invisible': [('sale_id', '!=', True)]}" /> </header> <sheet> |
