diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-06-25 15:54:12 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-06-25 15:54:12 +0700 |
| commit | c086f5e20505edbcc1d7769562393fb2e7e4b5c6 (patch) | |
| tree | c08a7166dc55867d947d1488e2e5027a335f463d | |
| parent | 0f1fd177780f47f1b2787767a87044a8b1705378 (diff) | |
upload ginee and validation create so manual duplicate
| -rwxr-xr-x | fixco_custom/models/sale.py | 28 | ||||
| -rw-r--r-- | fixco_custom/models/upload_ginee.py | 186 | ||||
| -rwxr-xr-x | fixco_custom/views/sale_order.xml | 4 | ||||
| -rw-r--r-- | fixco_custom/views/upload_ginee.xml | 2 |
4 files changed, 137 insertions, 83 deletions
diff --git a/fixco_custom/models/sale.py b/fixco_custom/models/sale.py index a192928..a36be0f 100755 --- a/fixco_custom/models/sale.py +++ b/fixco_custom/models/sale.py @@ -5,11 +5,23 @@ from odoo.exceptions import UserError class SaleOrder(models.Model): _inherit = "sale.order" - carrier = fields.Char(string='Shipping Method') - invoice_mp = fields.Char(string='Invoice Marketplace') - order_reference = fields.Char(string='Order Reference') + carrier = fields.Char(string='Shipping Method', required=True) + invoice_mp = fields.Char(string='Invoice Marketplace', required=True) + order_reference = fields.Char(string='Order Reference', required=True) address = fields.Char('Address') - note_by_buyer = fields.Char('Note By Buyer') + note_by_buyer = fields.Char('Note By Buyer') + + def _check_duplicate_order_id(self): + for rec in self: + so_duplicate = self.search([ + '|', + ('order_reference', '=', rec.order_reference), + ('invoice_mp', '=', rec.invoice_mp), + ('id', '!=', rec.id), + ], limit=1) + + if so_duplicate: + raise UserError(f'Order Id tersebut sudah digunakan di so {so_duplicate.name}') # def open_form_multi_create_invoices(self): # action = self.env['ir.actions.act_window']._for_xml_id('fixco_custom.action_sale_order_multi_invoices') @@ -34,7 +46,7 @@ class SaleOrder(models.Model): 'ref': self.client_order_ref or '', 'move_type': 'out_invoice', 'narration': self.note, - 'transaction_type': self.partner_invoice_id.transaction_type, + 'transaction_type': self.partner_id.transaction_type, 'invoice_marketplace': self.invoice_mp, 'address': self.address, 'sale_id': self.id, @@ -84,3 +96,9 @@ class SaleOrder(models.Model): 'default_partner_name': self.partner_id.name } } + + def action_confirm(self): + for order in self: + order._check_duplicate_order_id() + res = super(SaleOrder, self).action_confirm() + return res
\ No newline at end of file diff --git a/fixco_custom/models/upload_ginee.py b/fixco_custom/models/upload_ginee.py index 0910ef3..cfab74a 100644 --- a/fixco_custom/models/upload_ginee.py +++ b/fixco_custom/models/upload_ginee.py @@ -3,13 +3,14 @@ from datetime import datetime import base64 import xlrd from odoo.exceptions import ValidationError, UserError -import time import requests import json import hmac from hashlib import sha256 -Request_URI = '/openapi/order/v1/batch-get' +API_BASE_URL = "https://api.ginee.com" +BATCH_GET_URI = '/openapi/order/v1/batch-get' +LIST_ORDER_URI = '/openapi/order/v2/list-order' ACCESS_KEY = '24bb6a1ec618ec6a' SECRET_KEY = '32e4a78ad05ee230' @@ -17,20 +18,20 @@ class UploadGinee(models.Model): _name = "upload.ginee" _description = "Upload Ginee" _order = "create_date desc" - _rec = "number" + _rec_name = "number" - ginee_lines = fields.One2many('upload.ginee.line', 'upload_ginee_id', string='Upload Ginee Lines', auto_join=True, copy=False) + ginee_lines = fields.One2many('upload.ginee.line', 'upload_ginee_id', + string='Lines', copy=False, auto_join=True) number = fields.Char('Number', copy=False) date_upload = fields.Datetime('Upload Date', copy=False) - user_id = fields.Many2one('res.users', string='Created By', copy=False, default=lambda self: self.env.user.id) + user_id = fields.Many2one('res.users', 'Created By', default=lambda self: self.env.user.id) excel_file = fields.Binary('Excel File', attachment=True) filename = fields.Char('File Name') - filename = fields.Char('File Name') @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('upload.ginee') or '/' - return super(UploadGinee, self).create(vals) + return super().create(vals) def action_import_excel(self): self.ensure_one() @@ -45,15 +46,14 @@ class UploadGinee(models.Model): raise ValidationError(_("Invalid Excel file format.")) header = [str(sheet.cell(0, col).value).strip().lower() for col in range(sheet.ncols)] - expected_headers = ['marketplace', 'shop', 'invoice', 'order id'] + expected_headers = ['marketplace', 'shop', 'invoice'] if not all(h in header for h in expected_headers): - raise ValidationError(_("Invalid Excel format. Expected columns: Marketplace, Shop, Invoice, Order Id")) + raise ValidationError(_("Invalid Excel format. Expected columns: Marketplace, Shop, Invoice")) marketplace_col = header.index('marketplace') shop_col = header.index('shop') invoice_col = header.index('invoice') - order_id_col = header.index('order id') line_vals_list = [] for row in range(1, sheet.nrows): @@ -61,13 +61,11 @@ class UploadGinee(models.Model): marketplace = str(sheet.cell(row, marketplace_col).value).strip() shop = str(sheet.cell(row, shop_col).value).strip() invoice_marketplace = str(sheet.cell(row, invoice_col).value).strip() - order_id = str(sheet.cell(row, order_id_col).value).strip() line_vals = { 'marketplace': marketplace, 'shop': shop, 'invoice_marketplace': invoice_marketplace, - 'order_id': order_id, 'upload_ginee_id': self.id, } line_vals_list.append((0, 0, line_vals)) @@ -89,87 +87,123 @@ class UploadGinee(models.Model): 'next': {'type': 'ir.actions.act_window_close'}, } } - + + + def _show_notification(self, message): + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': _('Success'), + 'message': message, + 'sticky': False, + } + } + + def action_get_order_id(self): + self.date_upload = datetime.utcnow() + self.ginee_lines.get_order_id() + def action_create_detail_order(self): - for line in self.ginee_lines: - self.date_upload = datetime.utcnow() - line.create_so_and_detail_order() - - + self.date_upload = datetime.utcnow() + self.ginee_lines.create_so_and_detail_order() + def action_get_order_id_and_create_detail_order(self): + self.date_upload = datetime.utcnow() + self.ginee_lines.get_order_id() + self.ginee_lines.create_so_and_detail_order() + class UploadGineeLine(models.Model): _name = "upload.ginee.line" _description = "Upload Ginee Line" _inherit = ['mail.thread'] - upload_ginee_id = fields.Many2one('upload.ginee', string='Upload Ginee') + upload_ginee_id = fields.Many2one('upload.ginee', string='Upload') marketplace = fields.Char('Marketplace') shop = fields.Char('Shop') invoice_marketplace = fields.Char('Invoice Marketplace') order_id = fields.Char('Order ID') - message_error = fields.Text('Message Error') + message_error = fields.Text('Error Message') detail_order_id = fields.Many2one('detail.order', string='Detail Order') - def create_so_and_detail_order(self): - try: - order_id = f"{self.order_id}" + def _sign_request(self, uri): + """Membuat tanda tangan sesuai format yang berhasil""" + sign_data = f'POST${uri}$' + signature = hmac.new( + SECRET_KEY.encode('utf-8'), + sign_data.encode('utf-8'), + digestmod=sha256 + ).digest() + return f"{ACCESS_KEY}:{base64.b64encode(signature).decode('ascii')}" - duplicate_detail_order = self.env['detail.order'].search([ - ('detail_order','ilike', order_id) - ]) + def _call_api(self, uri, payload): + """Memanggil API dengan autentikasi yang benar""" + headers = { + 'Content-Type': 'application/json', + 'X-Advai-Country': 'ID', + 'Authorization': self._sign_request(uri) + } + + response = requests.post( + f"{API_BASE_URL}{uri}", + headers=headers, + data=json.dumps(payload) + ) + + if response.status_code != 200: + error_msg = f"API Error ({response.status_code}): {response.text}" + raise UserError(_(error_msg)) + + return response.json() - if duplicate_detail_order: - raise UserError(f'Untuk SO Dengan Order Id {order_id} sudah ada di detail order') - - authorization = self.sign_request() - headers = { - 'Content-Type': 'application/json', - 'X-Advai-Country': 'ID', - 'Authorization': authorization - } - - payload = { - "orderIds": [order_id] - } - - url = "https://api.ginee.com/openapi/order/v1/batch-get" - - response = requests.post( - url, - headers=headers, - data=json.dumps(payload) - ) - - if response.status_code == 200: - data = response.json() - # self.detail_order = json.dumps(data, indent=4, sort_keys=True) - detail_order = self.env['detail.order'].create([{ - 'detail_order': json.dumps(data, indent=4, sort_keys=True), + def create_so_and_detail_order(self): + try: + for rec in self: + if not rec.order_id: + raise UserError(_('Order ID is empty!')) + + if self.env['detail.order'].search([('detail_order', 'ilike', rec.order_id)]): + raise UserError(_( + "Order ID %s already exists in Detail Orders") % rec.order_id) + + data = self._call_api(BATCH_GET_URI, {"orderIds": [rec.order_id]}) + detail_order = self.env['detail.order'].create({ + 'detail_order': json.dumps(data, indent=4), 'source': 'manual', - }]) - - detail_order.execute_queue_detail() - self.message_error = 'Success!!' - self.detail_order_id = detail_order.id - else: - self.write({ - 'message_error': json.dumps({ - 'error': f"Request failed with status code {response.status_code}", - 'response': response.text - }) }) + detail_order.execute_queue_detail() - except Exception as e: - self.write({ - 'message_error': json.dumps({ - 'error': str(e) + rec.update({ + 'message_error': 'Success', + 'detail_order_id': detail_order.id }) - }) - + except Exception as e: + self.message_error = str(e) - def sign_request(self): - signData = '$'.join(['POST', Request_URI]) + '$' - authorization = ACCESS_KEY + ':' + base64.b64encode( - hmac.new(SECRET_KEY.encode('utf-8'), signData.encode('utf-8'), digestmod=sha256).digest() - ).decode('ascii') - return authorization
\ No newline at end of file + def get_order_id(self): + try: + for rec in self: + if self.search_count([ + ('marketplace', '=', rec.marketplace), + ('invoice_marketplace', '=', rec.invoice_marketplace), + ('id', '!=', rec.id) + ]): + raise UserError(_( + "Invoice %s already exists") % rec.invoice_marketplace) + + data = self._call_api( + LIST_ORDER_URI, + { + "channel": rec.marketplace, + "orderNumbers": [rec.invoice_marketplace] + } + ) + + orders = data.get('data', {}).get('content', []) + if orders: + rec.order_id = orders[0].get('orderId') + rec.message_error = 'Success' + else: + raise UserError(_("No orders found for invoice: %s") % self.invoice_marketplace) + except Exception as e: + self.message_error = str(e)
\ No newline at end of file diff --git a/fixco_custom/views/sale_order.xml b/fixco_custom/views/sale_order.xml index 2fd452e..eb609e9 100755 --- a/fixco_custom/views/sale_order.xml +++ b/fixco_custom/views/sale_order.xml @@ -18,8 +18,8 @@ <field name="address"/> </field> <field name="client_order_ref" position="after"> - <field name="order_reference"/> - <field name="invoice_mp" readonly="1"/> + <field name="order_reference" required="1"/> + <field name="invoice_mp" required="1"/> <field name="note_by_buyer" readonly="1"/> </field> </field> diff --git a/fixco_custom/views/upload_ginee.xml b/fixco_custom/views/upload_ginee.xml index 99ecb1e..ec8aae4 100644 --- a/fixco_custom/views/upload_ginee.xml +++ b/fixco_custom/views/upload_ginee.xml @@ -20,7 +20,9 @@ <form string="Upload Ginee"> <header> <button name="action_import_excel" string="Import Excel" type="object" class="oe_highlight"/> + <button name="action_get_order_id" string="Get Order ID" type="object" class="oe_highlight"/> <button name="action_create_detail_order" string="Create Detail Order" type="object" class="oe_highlight"/> + <button name="action_get_order_id_and_create_detail_order" string="Get Order ID And Create Detail Order" type="object" class="oe_highlight"/> <field name="number" widget="field_no_edit" options="{'no_open': True}"/> <field name="date_upload"/> <field name="user_id" widget="field_no_edit" options="{'no_open': True}"/> |
