summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2025-06-25 15:54:12 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2025-06-25 15:54:12 +0700
commitc086f5e20505edbcc1d7769562393fb2e7e4b5c6 (patch)
treec08a7166dc55867d947d1488e2e5027a335f463d
parent0f1fd177780f47f1b2787767a87044a8b1705378 (diff)
upload ginee and validation create so manual duplicate
-rwxr-xr-xfixco_custom/models/sale.py28
-rw-r--r--fixco_custom/models/upload_ginee.py186
-rwxr-xr-xfixco_custom/views/sale_order.xml4
-rw-r--r--fixco_custom/views/upload_ginee.xml2
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}"/>