summaryrefslogtreecommitdiff
path: root/fixco_custom/models
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2025-05-21 15:07:20 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2025-05-21 15:07:20 +0700
commit4eff6c52574cd5664c65d9f496506c5ae5bfe9c5 (patch)
treee9322f66ecd229b27f61b0c795651045bc075a6a /fixco_custom/models
parent6c6940052eb8d480fc6719819c06a964dc0827dc (diff)
detail order logic
Diffstat (limited to 'fixco_custom/models')
-rw-r--r--fixco_custom/models/__init__.py1
-rw-r--r--fixco_custom/models/detail_order.py242
-rw-r--r--fixco_custom/models/stock_picking.py31
-rw-r--r--fixco_custom/models/webhook_ginee.py92
4 files changed, 277 insertions, 89 deletions
diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py
index 5815aa3..9b3459e 100644
--- a/fixco_custom/models/__init__.py
+++ b/fixco_custom/models/__init__.py
@@ -2,3 +2,4 @@ from . import partner
from . import sale
from . import webhook_ginee
from . import detail_order
+from . import stock_picking
diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py
index c93bc72..1154be1 100644
--- a/fixco_custom/models/detail_order.py
+++ b/fixco_custom/models/detail_order.py
@@ -7,25 +7,34 @@ import hmac
import base64
from hashlib import sha256
+Request_URI = '/openapi/order/v1/batch-get'
+ACCESS_KEY = '24bb6a1ec618ec6a'
+SECRET_KEY = '32e4a78ad05ee230'
+
class DetailOrder(models.Model):
_name = "detail.order"
_inherit = ['mail.thread']
+ json_ginee = fields.Text('JSON Ginee')
detail_order = fields.Text()
execute_status = fields.Selection([
- ('success', 'Success'),
- ('failed', 'Failed'),
+ ('from_webhook', 'From Webhook'),
+ ('detail_order', 'Detail Order'),
+ ('so_confirm', 'SO Confirm'),
('done', 'Done'),
- ('not_found', 'Record not found')
], 'Execute Status')
+ sale_id = fields.Many2one('sale.order', 'Sale Order')
+ picking_id = fields.Many2one('stock.picking', 'Picking')
+ invoice_id = fields.Many2one('account.move', 'Invoice')
+ message_error = fields.Text('Message Error')
+
+ # get detail order section
def get_order_id(self):
try:
if self.json_ginee:
json_data = json.loads(self.json_ginee)
- order_id = json_data.get('data', {}).get('orderId')
- order_status = json_data.get('data', {}).get('orderStatus')
- print_info = json_data.get('data', {}).get('printInfo', {}).get('labelPrintStatus')
+ order_id = json_data.get('payload', {}).get('orderId')
if not order_id:
raise UserError(_("Order ID not found in JSON data"))
return order_id
@@ -34,9 +43,9 @@ class DetailOrder(models.Model):
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, max_exec_time=30):
- domain = [('execute_status', '=', 'success')]
+ domain = [('execute_status', '=', False)]
records = self.search(domain, order='create_date asc', limit=limit)
start_time = time.time()
for rec in records:
@@ -45,11 +54,46 @@ class DetailOrder(models.Model):
if elapsed_time > max_exec_time:
break
rec.execute_queue()
-
+
def execute_queue(self):
try:
- order_id, order_status, print_info = self.get_order_id()
+ 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()
+ self.detail_order = json.dumps(data)
+ self.execute_status = 'detail_order'
+ else:
+ self.write({
+ 'execute_status': 'failed',
+ 'json_ginee': json.dumps({
+ 'error': f"Request failed with status code {response.status_code}",
+ 'response': response.text
+ })
+ })
+
except Exception as e:
self.write({
'execute_status': 'failed',
@@ -57,3 +101,181 @@ class DetailOrder(models.Model):
'error': str(e)
})
})
+
+
+ # detail order to so section
+
+
+ def get_order_id_detail(self):
+ try:
+ 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')
+ print_info = json_data.get('data', {})[0].get('printInfo', {}).get('labelPrintStatus')
+ if not order_id:
+ raise UserError(_("Order ID not found in JSON data"))
+ return order_id, order_status, print_info
+ raise UserError(_("No JSON data available"))
+ except json.JSONDecodeError:
+ 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')]
+ records = self.search(domain, order='create_date asc', limit=limit)
+ for rec in records:
+ rec.execute_queue_detail()
+
+ def prepare_data_so(self, json_data):
+ data = {
+ 'partner_id': 45,
+ 'client_order_ref': json_data.get('data', {})[0].get('orderId'),
+ 'warehouse_id': 4,
+ 'picking_policy': 'direct',
+ }
+ return data
+
+ def prepare_data_so_line(self, json_data):
+ order_lines = []
+ items = json_data.get('data', [{}])[0].get('items', [])
+
+ for item in items:
+ product = self.env['product.product'].search(
+ [('default_code', '=', item.get('sku'))],
+ limit=1
+ )
+ if not product:
+ raise UserError(_("Product not found for SKU: %s") % item.get('sku'))
+
+ line_data = {
+ 'product_id': product.id,
+ 'product_uom_qty': item.get('quantity'),
+ 'price_unit': item.get('actualPrice'),
+ }
+ order_lines.append((0, 0, line_data))
+
+ return order_lines
+
+ def execute_queue_detail(self):
+ try:
+ json_data = json.loads(self.detail_order)
+ data = self.prepare_data_so(json_data)
+ order_lines = self.prepare_data_so_line(json_data)
+ order_id, order_status, print_info = self.get_order_id_detail()
+
+ if order_status == 'READY_TO_SHIP' and print_info == 'NOT_PRINTED':
+ # if order_status == 'SHIPPING' and print_info == 'PRINTED':
+ data['order_line'] = order_lines
+
+ sale_order = self.env['sale.order'].create(data)
+
+ self.sale_id = sale_order.id
+ sale_order.action_confirm()
+
+ self.picking_id = sale_order.picking_ids[0].id
+
+ self.execute_status = 'so_confirm'
+ elif order_status == 'READY_TO_SHIP' and print_info == 'PRINTED':
+ data['order_line'] = order_lines
+
+ sale_order = self.env['sale.order'].create(data)
+
+ self.sale_id = sale_order.id
+ sale_order.action_confirm()
+
+ self.picking_id = sale_order.picking_ids[0].id
+ self.picking_id.sync_qty_reserved_qty_done()
+
+ self.execute_status = 'so_confirm'
+
+
+ except Exception as e:
+ self.write({
+ 'execute_status': 'failed',
+ 'message_error': json.dumps({
+ '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
+
+
+ # check print do section
+
+
+ def get_order_id_check_print(self):
+ try:
+ if self.detail_order:
+ json_data = json.loads(self.detail_order)
+ order_id = json_data.get('data', {})[0].get('orderId')
+ if not order_id:
+ raise UserError(_("Order ID not found in JSON data"))
+ return order_id
+ raise UserError(_("No JSON data available"))
+ except json.JSONDecodeError:
+ raise UserError(_("Invalid JSON format in check_print field"))
+ except Exception as e:
+ raise UserError(_("Error extracting order ID: %s") % str(e))
+
+ def process_queue_item_check_print(self, limit=100):
+ domain = [('picking_id.state', 'not in', ['done', 'cancel'])]
+ records = self.search(domain, order='create_date asc', limit=limit)
+ for rec in records:
+ rec.execute_queue_check_print()
+
+ def execute_queue_check_print(self):
+ try:
+ order_id = self.get_order_id_check_print()
+
+ 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)
+ detail_order = json.loads(self.detail_order)
+ if detail_order['data'][0]['printInfo']['labelPrintStatus'] == 'PRINTED': #ubah ke printed lagi nanti
+ self.picking_id.sync_qty_reserved_qty_done()
+ # self.sale_id.api_create_invoices(self.sale_id.id)
+ self.execute_status = 'done'
+ else:
+ self.write({
+ 'execute_status': 'failed',
+ 'json_ginee': json.dumps({
+ 'error': f"Request failed with status code {response.status_code}",
+ 'response': response.text
+ })
+ })
+
+ except Exception as e:
+ self.write({
+ 'execute_status': 'failed',
+ 'json_ginee': json.dumps({
+ 'error': str(e)
+ })
+ })
+
+ \ No newline at end of file
diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py
new file mode 100644
index 0000000..498983e
--- /dev/null
+++ b/fixco_custom/models/stock_picking.py
@@ -0,0 +1,31 @@
+from odoo import fields, models, api, _
+from odoo.exceptions import AccessError, UserError, ValidationError
+from odoo.tools.float_utils import float_is_zero
+from collections import defaultdict
+from datetime import timedelta, datetime
+from datetime import timedelta, datetime as waktu
+from itertools import groupby
+import pytz, requests, json, requests
+from dateutil import parser
+import datetime
+import hmac
+import hashlib
+import base64
+import requests
+import time
+import logging
+import re
+
+_logger = logging.getLogger(__name__)
+
+
+class StockPicking(models.Model):
+ _inherit = 'stock.picking'
+
+
+ def sync_qty_reserved_qty_done(self):
+ for picking in self:
+ for line in picking.move_line_ids_without_package:
+ line.qty_done = line.product_uom_qty
+
+ picking.button_validate() \ No newline at end of file
diff --git a/fixco_custom/models/webhook_ginee.py b/fixco_custom/models/webhook_ginee.py
index 1ee814f..e1fb608 100644
--- a/fixco_custom/models/webhook_ginee.py
+++ b/fixco_custom/models/webhook_ginee.py
@@ -7,10 +7,6 @@ import hmac
import base64
from hashlib import sha256
-Request_URI = '/openapi/order/v1/batch-get'
-ACCESS_KEY = '24bb6a1ec618ec6a'
-SECRET_KEY = '32e4a78ad05ee230'
-
class WebhookGinee(models.Model):
_name = "webhook.ginee"
_inherit = ['mail.thread']
@@ -23,85 +19,23 @@ class WebhookGinee(models.Model):
('not_found', 'Record not found')
], 'Execute Status')
- def get_order_id(self):
- try:
- 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
- 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, 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, max_exec_time=30):
+ def process_queue_item(self, limit=100):
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 execute_queue(self):
- try:
- # Get order ID from json_ginee
- 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()
- detail_order = self.env['detail.order'].create({
- 'detail_order': json.dumps(data),
- 'execute_status': 'success'
- })
- self.execute_status = 'done'
- else:
- self.write({
- 'execute_status': 'failed',
- 'json_ginee': json.dumps({
- 'error': f"Request failed with status code {response.status_code}",
- 'response': response.text
- })
- })
-
- except Exception as e:
- self.write({
- 'execute_status': 'failed',
- 'json_ginee': json.dumps({
- '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
+ detail_order = self.env['detail.order'].create({'json_ginee': self.json_ginee})
+ self.execute_status = 'success'