diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-20 11:34:14 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-20 11:34:14 +0700 |
| commit | d2268706824167cd23dd3ea9e22acc241bc35122 (patch) | |
| tree | bf46314de8b23f8c164f2f094e2ef50fb4908f7f | |
| parent | d90a7762d13adf43520ea006a2ab9d3034dfdd15 (diff) | |
push payment bill
| -rwxr-xr-x | fixco_custom/__manifest__.py | 1 | ||||
| -rw-r--r-- | fixco_custom/models/account_payment.py | 29 | ||||
| -rwxr-xr-x | fixco_custom/models/detail_order.py | 3 | ||||
| -rw-r--r-- | fixco_custom/models/upload_ginee.py | 146 | ||||
| -rw-r--r-- | fixco_custom/views/account_payment.xml | 15 |
5 files changed, 132 insertions, 62 deletions
diff --git a/fixco_custom/__manifest__.py b/fixco_custom/__manifest__.py index 557b2ae..3e32552 100755 --- a/fixco_custom/__manifest__.py +++ b/fixco_custom/__manifest__.py @@ -53,6 +53,7 @@ 'views/purchase_order_multi_bills.xml', 'views/report_picking_list_new.xml', 'views/purchase_order_line_wizard.xml', + 'views/account_payment.xml', ], 'demo': [], 'css': [], diff --git a/fixco_custom/models/account_payment.py b/fixco_custom/models/account_payment.py index 2c7a5b4..41a2ce5 100644 --- a/fixco_custom/models/account_payment.py +++ b/fixco_custom/models/account_payment.py @@ -8,4 +8,31 @@ class AccountPayment(models.Model): @api.constrains('journal_id') def set_default_journal_id(self): for rec in self: - rec.journal_id = 21
\ No newline at end of file + rec.journal_id = 21 + + def auto_sync_payment(self): + for payment in self: + if not payment.ref: + continue + + # bill_names = payment.ref.split() + bill_names = [x.strip() for x in payment.ref.split() if x.strip()] + + move_line = self.env['account.move.line'].search([ + ('move_id', '=', payment.move_id.id), + ('account_id', '=', 388), + ]) + + for bill_name in bill_names: + bill = self.env['account.move'].search([ + ('name', '=', bill_name), + ('move_type', '=', 'in_invoice'), + ('state', '=', 'posted'), + ('payment_state', '=', 'not_paid'), + ], limit=1) + + if not bill: + continue + + if move_line: + bill.js_assign_outstanding_line(move_line.id) diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py index c256d8c..d392b30 100755 --- a/fixco_custom/models/detail_order.py +++ b/fixco_custom/models/detail_order.py @@ -238,7 +238,8 @@ class DetailOrder(models.Model): """Combine quantities of the same products from multiple orders""" product_quantities = {} for item in items: - key = item.get('masterSku') + # key = item.get('masterSku') + key = item.get('sku') if key in product_quantities: product_quantities[key]['quantity'] += item.get('quantity', 0) product_quantities[key]['actualPrice'] += item.get('actualPrice', 0) diff --git a/fixco_custom/models/upload_ginee.py b/fixco_custom/models/upload_ginee.py index b211709..19aa965 100644 --- a/fixco_custom/models/upload_ginee.py +++ b/fixco_custom/models/upload_ginee.py @@ -204,43 +204,53 @@ class UploadGineeLine(models.Model): 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] - + + order_ids = [l.order_id for l in lines if l.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) - + + # ===== 1. Fast duplicate check (still same behavior) ===== + 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 + + # ===== 2. Single API call ===== + data = lines[0]._call_api( + BATCH_GET_URI, + {"orderIds": order_ids} + ) + + orders_data = data.get('data', []) + if not orders_data: + raise UserError(_('No data returned from BLIBLI API')) + + # ===== 3. Combine items (lebih ringkas) ===== + combined_items = [ + item + for order in orders_data + for item in order.get('items', []) + ] + + base_order = orders_data[0] + + # ===== 4. Build grouped payload ===== 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 + **base_order, + 'items': combined_items, + 'externalOrderId': ', '.join(lines.mapped('invoice_marketplace')), + 'orderId': ', '.join(order_ids), }] } - - detail_order = self.env['detail.order'].create({ + + return 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""" @@ -273,69 +283,84 @@ 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.detail_order_id: - continue + + # ===== 1. Grouping (lebih rapi & cepat) ===== + for rec in self.filtered(lambda r: not r.detail_order_id): 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) + key = rec.invoice_marketplace.split('-')[0] 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(): + key = rec.id + grouped_lines.setdefault(key, []).append(rec) + + # ===== 2. Preload sale.order (hindari query berulang) ===== + invoice_list = [ + line.invoice_marketplace + for lines in grouped_lines.values() + for line in lines + if len(lines) == 1 + ] + + existing_so_map = {} + if invoice_list: + so_records = self.env['sale.order'].search([ + ('invoice_mp', 'in', invoice_list) + ]) + for so in so_records: + existing_so_map.setdefault(so.invoice_mp, []).append(so.name) + + # ===== 3. Process per group ===== + for _, lines in grouped_lines.items(): try: + # ===== GROUPED BLIBLI ===== if len(lines) > 1: - # Process grouped BLIBLI orders detail_order = self._process_grouped_blibli_orders(lines) - - # Update all lines in the group + detail_order.execute_queue_detail() + for line in lines: - line.update({ + line.write({ 'message_error': 'Success (grouped)', 'detail_order_id': detail_order.id }) - detail_order.execute_queue_detail() + + # ===== SINGLE LINE ===== else: - # Process single line (non-grouped) line = lines[0] - so_exist = self.env['sale.order'].search( - [('invoice_mp', 'ilike', line.invoice_marketplace)] - ) - if so_exist: + if line.invoice_marketplace in existing_so_map: raise UserError(_( "Invoice Marketplace %s sudah terdaftar di Sale Order: %s" ) % ( line.invoice_marketplace, - ', '.join(so_exist.mapped('name')) + ', '.join(existing_so_map[line.invoice_marketplace]) )) if not line.order_id: raise UserError(_('Order ID is empty!')) - - - data = line._call_api(BATCH_GET_URI, {"orderIds": [line.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() - - line.update({ + + line.write({ 'message_error': 'Success', 'detail_order_id': detail_order.id }) - + except Exception as e: - # Update all lines in group with error if any - for line in lines: - line.message_error = str(e) + self.env['upload.ginee.line'].browse( + [l.id for l in lines] + ).write({ + 'message_error': str(e) + }) + def get_order_id(self): for rec in self: @@ -366,4 +391,5 @@ class UploadGineeLine(models.Model): raise UserError(_("No orders found for invoice: %s") % rec.invoice_marketplace) except Exception as e: - rec.message_error = str(e)
\ No newline at end of file + rec.message_error = str(e) + raise
\ No newline at end of file diff --git a/fixco_custom/views/account_payment.xml b/fixco_custom/views/account_payment.xml new file mode 100644 index 0000000..c291281 --- /dev/null +++ b/fixco_custom/views/account_payment.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data> + <record id="inherited_payment_form_view" model="ir.ui.view"> + <field name="name">inherited_payment_form_view</field> + <field name="model">account.payment</field> + <field name="inherit_id" ref="account.view_account_payment_form" /> + <field name="arch" type="xml"> + <button name="mark_as_sent" position="after"> + <button name="auto_sync_payment" string="Sync Payment" type="object" attrs="{'invisible': ['|', '|', ('state', '!=', 'posted'), ('is_move_sent', '=', True), ('payment_method_code', '!=', 'manual')]}"/> + </button> + </field> + </record> + </data> +</odoo> |
