from odoo import models, fields, api, _ 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' ACCESS_KEY = '24bb6a1ec618ec6a' SECRET_KEY = '32e4a78ad05ee230' class UploadGinee(models.Model): _name = "upload.ginee" _description = "Upload Ginee" _order = "create_date desc" _rec = "number" ginee_lines = fields.One2many('upload.ginee.line', 'upload_ginee_id', string='Upload Ginee Lines', auto_join=True, copy=False) 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) 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) def action_import_excel(self): self.ensure_one() if not self.excel_file: raise ValidationError(_("Please upload an Excel file first.")) try: file_content = base64.b64decode(self.excel_file) workbook = xlrd.open_workbook(file_contents=file_content) sheet = workbook.sheet_by_index(0) except: 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'] if not all(h in header for h in expected_headers): raise ValidationError(_("Invalid Excel format. Expected columns: Marketplace, Shop, Invoice, Order Id")) 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): try: 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)) except Exception as e: continue self.ginee_lines.unlink() self.write({ 'ginee_lines': line_vals_list, }) return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': _('Success'), 'message': _('Imported %s lines from Excel.') % len(line_vals_list), 'sticky': False, 'next': {'type': 'ir.actions.act_window_close'}, } } def action_create_detail_order(self): for line in self.ginee_lines: self.date_upload = datetime.utcnow() line.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') 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') detail_order_id = fields.Many2one('detail.order', string='Detail Order') def create_so_and_detail_order(self): try: order_id = f"{self.order_id}" duplicate_detail_order = self.env['detail.order'].search([ ('detail_order','ilike', order_id) ]) 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), '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 }) }) except Exception as e: self.write({ '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