summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xfixco_custom/__manifest__.py1
-rwxr-xr-xfixco_custom/models/__init__.py1
-rwxr-xr-xfixco_custom/models/detail_order.py229
-rw-r--r--fixco_custom/models/purchase_order.py16
-rw-r--r--fixco_custom/models/queue_job.py56
-rwxr-xr-xfixco_custom/models/sale.py12
-rw-r--r--fixco_custom/models/sale_order_multi_invoices.py84
-rwxr-xr-xfixco_custom/models/stock_picking.py6
-rw-r--r--fixco_custom/models/upload_cancel_picking.py12
-rw-r--r--fixco_custom/models/upload_ginee.py25
-rwxr-xr-xfixco_custom/security/ir.model.access.csv1
-rw-r--r--fixco_custom/views/queue_job.xml54
-rw-r--r--fixco_custom/views/sale_order_multi_invoices.xml2
-rwxr-xr-xfixco_custom/views/stock_picking.xml2
14 files changed, 358 insertions, 143 deletions
diff --git a/fixco_custom/__manifest__.py b/fixco_custom/__manifest__.py
index aef74df..0543ec2 100755
--- a/fixco_custom/__manifest__.py
+++ b/fixco_custom/__manifest__.py
@@ -49,6 +49,7 @@
'views/token_log.xml',
'views/wizard_purchase_pricelist.xml',
'views/upload_cancel_picking.xml',
+ 'views/queue_job.xml',
],
'demo': [],
'css': [],
diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py
index 47a4176..c13c9a3 100755
--- a/fixco_custom/models/__init__.py
+++ b/fixco_custom/models/__init__.py
@@ -37,3 +37,4 @@ from . import stock_picking_return
from . import account_move_reversal
from . import upload_cancel_picking
from . import product_supplierinfo
+from . import queue_job
diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py
index 41a5466..674f11a 100755
--- a/fixco_custom/models/detail_order.py
+++ b/fixco_custom/models/detail_order.py
@@ -5,6 +5,7 @@ import requests
import json
import hmac
import base64
+from datetime import datetime
from hashlib import sha256
import logging
@@ -138,6 +139,27 @@ class DetailOrder(models.Model):
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'),
+ # '!',
+ # '|',
+ # ('json_ginee', 'like', '"orderStatus": "PENDING_PAYMENT"'),
+ # ('json_ginee', 'like', '"channel":"BLIBLI_ID"'),
+ # ]
+
+ # records = self.search(domain, order='create_date asc', limit=limit)
+
+ # for i, rec in enumerate(records, 1):
+ # try:
+ # rec.execute_queue_detail()
+ # if i % 10 == 0:
+ # self.env.cr.commit()
+ # except Exception as e:
+ # _logger.error("Failed to process record %s: %s", rec.id, str(e))
+ # self.env.cr.rollback()
+
+ # self.env.cr.commit()
def process_queue_item_detail(self, limit=100):
domain = [
('execute_status', '=', 'detail_order'),
@@ -147,15 +169,31 @@ class DetailOrder(models.Model):
('json_ginee', 'like', '"channel":"BLIBLI_ID"'),
]
- records = self.search(domain, order='create_date desc', limit=limit)
+ records = self.search(domain, order='create_date asc', limit=limit)
for i, rec in enumerate(records, 1):
try:
rec.execute_queue_detail()
+
+ # ⏳ throttle API
+ time.sleep(0.8)
+
if i % 10 == 0:
self.env.cr.commit()
+
except Exception as e:
- _logger.error("Failed to process record %s: %s", rec.id, str(e))
+ msg = str(e)
+
+ # 🎯 khusus rate limit
+ if '429' in msg or 'SERVICE_BUSY' in msg:
+ _logger.warning(
+ "Rate limit hit. Sleep & retry later. Record ID %s", rec.id
+ )
+ self.env.cr.rollback()
+ time.sleep(5 + random.uniform(1, 3))
+ break # STOP loop, jangan maksa
+
+ _logger.error("Failed record %s: %s", rec.id, msg)
self.env.cr.rollback()
self.env.cr.commit()
@@ -283,96 +321,105 @@ class DetailOrder(models.Model):
# First check if a sale order with this reference already exists
existing_order = self.env['sale.order'].search([('order_reference', '=', order_id)], limit=1)
- if order_status == 'CANCELLED':
- external_order_id = json_data.get('data', [{}])[0].get('externalOrderId')
- order_id = json_data.get('data', [{}])[0].get('orderId')
-
- # Try to find existing SO
- existing_order = self.env['sale.order'].search([
- '|',
- ('invoice_mp', '=', external_order_id),
- ('client_order_ref', '=', order_id)
- ], limit=1)
-
- if existing_order:
- if existing_order.state == 'sale':
- # Cancel all pickings linked to this order
- for picking in existing_order.picking_ids:
- if picking.state not in ['cancel', 'done']:
- picking.action_cancel()
- self.sale_id = existing_order.id
- self.execute_status = 'cancelled_so_picking'
- existing_order.action_cancel()
- else:
- existing_order.action_cancel()
+ create_at_str = json_data.get('data', [{}])[0].get('createAt')
+
+ if create_at_str:
+ create_at = datetime.strptime(create_at_str, "%Y-%m-%dT%H:%M:%SZ")
+
+ cutoff = datetime(2026, 1, 1) # 1 Jan 2026 UTC
+
+ if create_at >= cutoff:
+
+ if order_status == 'CANCELLED':
+ external_order_id = json_data.get('data', [{}])[0].get('externalOrderId')
+ order_id = json_data.get('data', [{}])[0].get('orderId')
+
+ # Try to find existing SO
+ existing_order = self.env['sale.order'].search([
+ '|',
+ ('invoice_mp', '=', external_order_id),
+ ('client_order_ref', '=', order_id)
+ ], limit=1)
+
+ if existing_order:
+ if existing_order.state == 'sale':
+ # Cancel all pickings linked to this order
+ for picking in existing_order.picking_ids:
+ if picking.state not in ['cancel', 'done']:
+ picking.action_cancel()
+ self.sale_id = existing_order.id
+ self.execute_status = 'cancelled_so_picking'
+ existing_order.action_cancel()
+ else:
+ existing_order.action_cancel()
+ self.sale_id = existing_order.id
+ self.execute_status = 'cancelled_so'
+
+ else:
+ # If no existing SO, create one, then cancel
+ data = self.prepare_data_so(json_data)
+ order_lines, product_not_found = self.prepare_data_so_line(json_data)
+ data['order_line'] = order_lines
+ sale_order = self.env['sale.order'].create(data)
+
+ self.sale_id = sale_order.id
+ sale_order.order_reference = order_id
+ sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
+ sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
+
+ sale_order.action_cancel()
+ self.execute_status = 'cancelled_so_created'
+
+ return
+
+ if existing_order:
+ # If order already exists, just update the references
self.sale_id = existing_order.id
- self.execute_status = 'cancelled_so'
-
- else:
- # If no existing SO, create one, then cancel
- data = self.prepare_data_so(json_data)
- order_lines, product_not_found = self.prepare_data_so_line(json_data)
- data['order_line'] = order_lines
- sale_order = self.env['sale.order'].create(data)
-
- self.sale_id = sale_order.id
- sale_order.order_reference = order_id
- sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
- sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
-
- sale_order.action_cancel()
- self.execute_status = 'cancelled_so_created'
-
- return
-
- if existing_order:
- # If order already exists, just update the references
- self.sale_id = existing_order.id
- self.execute_status = 'already_so'
- return # Exit early since we don't need to create anything
-
- if order_status != 'PENDING_PAYMENT':
- if order_status in ('PARTIALLY_PAID', 'PAID'):
- data['order_line'] = order_lines
- sale_order = self.env['sale.order'].create(data)
-
- self.sale_id = sale_order.id
- sale_order.order_reference = order_id
- sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
- sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
- if not product_not_found:
- sale_order.action_confirm()
- # self.picking_id = sale_order.picking_ids[0].id
- # self.picking_id.order_reference = order_id
- # self.picking_id.invoice_mp = sale_order.invoice_mp
- # self.picking_id.carrier = sale_order.carrier
- # self.picking_id.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
- # self.picking_id.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
-
- self.execute_status = 'so_confirm'
- else:
- self.execute_status = 'so_draft'
- else:
- # For other statuses, create new order only if it doesn't exist
- data['order_line'] = order_lines
- sale_order = self.env['sale.order'].create(data)
-
- self.sale_id = sale_order.id
- sale_order.order_reference = order_id
- sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
- sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
- if not product_not_found:
- sale_order.action_confirm()
- # self.picking_id = sale_order.picking_ids[0].id
- # self.picking_id.order_reference = order_id
- # self.picking_id.invoice_mp = sale_order.invoice_mp
- # self.picking_id.carrier = sale_order.carrier
- # self.picking_id.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
- # self.picking_id.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
-
- self.execute_status = 'so_confirm'
- else:
- self.execute_status = 'so_draft'
+ self.execute_status = 'already_so'
+ return # Exit early since we don't need to create anything
+
+ if order_status != 'PENDING_PAYMENT':
+ if order_status in ('PARTIALLY_PAID', 'PAID'):
+ data['order_line'] = order_lines
+ sale_order = self.env['sale.order'].create(data)
+
+ self.sale_id = sale_order.id
+ sale_order.order_reference = order_id
+ sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
+ sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
+ if not product_not_found:
+ sale_order.action_confirm()
+ # self.picking_id = sale_order.picking_ids[0].id
+ # self.picking_id.order_reference = order_id
+ # self.picking_id.invoice_mp = sale_order.invoice_mp
+ # self.picking_id.carrier = sale_order.carrier
+ # self.picking_id.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
+ # self.picking_id.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
+
+ self.execute_status = 'so_confirm'
+ else:
+ self.execute_status = 'so_draft'
+ else:
+ # For other statuses, create new order only if it doesn't exist
+ data['order_line'] = order_lines
+ sale_order = self.env['sale.order'].create(data)
+
+ self.sale_id = sale_order.id
+ sale_order.order_reference = order_id
+ sale_order.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
+ sale_order.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
+ if not product_not_found:
+ sale_order.action_confirm()
+ # self.picking_id = sale_order.picking_ids[0].id
+ # self.picking_id.order_reference = order_id
+ # self.picking_id.invoice_mp = sale_order.invoice_mp
+ # self.picking_id.carrier = sale_order.carrier
+ # self.picking_id.address = json_data.get('data', [{}])[0].get('shippingAddressInfo', []).get('fullAddress', [])
+ # self.picking_id.note_by_buyer = json_data.get('data', [{}])[0].get('extraInfo', []).get('noteByBuyer', [])
+
+ self.execute_status = 'so_confirm'
+ else:
+ self.execute_status = 'so_draft'
except Exception as e:
self.write({
diff --git a/fixco_custom/models/purchase_order.py b/fixco_custom/models/purchase_order.py
index f2a6c3e..43fe8f6 100644
--- a/fixco_custom/models/purchase_order.py
+++ b/fixco_custom/models/purchase_order.py
@@ -1,3 +1,4 @@
+from shutil import copy
from odoo import fields, models, api, _
from odoo.exceptions import AccessError, UserError, ValidationError
from dateutil.relativedelta import relativedelta
@@ -55,7 +56,7 @@ class PurchaseOrder(models.Model):
soo_price = fields.Float('SOO Price', copy=False)
soo_discount = fields.Float('SOO Discount', copy=False)
soo_tax = fields.Float('SOO Tax', copy=False)
- discount_total = fields.Float('Discount Total', help = 'Total Discount for Each Product')
+ discount_total = fields.Float('Discount Total', help = 'Total Discount for Each Product', copy=False, default=0.0)
def _get_fixco_token(self, source='auto'):
ICP = self.env['ir.config_parameter'].sudo()
@@ -227,9 +228,12 @@ class PurchaseOrder(models.Model):
unique_soo = list(set(soo_numbers))
if len(unique_soo) == 1:
order.soo_number = unique_soo[0]
+ if not order.picking_ids.number_soo:
+ order.picking_ids[0].number_soo = unique_soo[0]
elif len(unique_soo) > 1:
order.soo_number = ", ".join(unique_soo)
-
+ if not order.picking_ids.number_soo:
+ order.picking_ids[0].number_soo = ", ".join(unique_soo)
else:
order.soo_number = False
@@ -423,12 +427,18 @@ class PurchaseOrder(models.Model):
'domain': [('id', 'in', journals.ids)],
}
- @api.depends('order_line.price_total', 'biaya_lain_lain', 'discount_total')
+ @api.depends('order_line.price_total', 'biaya_lain_lain', 'discount_total', 'amount_tax', 'amount_discount')
def _amount_all(self):
super(PurchaseOrder, self)._amount_all()
for order in self:
+ line_discount = 0.0
+ for line in order.order_line:
+ if line.discount > 0:
+ line_discount += line.discount_amount
+
amount_total = order.amount_untaxed + order.amount_tax + order.biaya_lain_lain - order.discount_total
+ order.amount_discount = order.discount_total + line_discount
order.amount_total = order.currency_id.round(amount_total)
@api.depends('order_line.discount_amount')
diff --git a/fixco_custom/models/queue_job.py b/fixco_custom/models/queue_job.py
new file mode 100644
index 0000000..56926e3
--- /dev/null
+++ b/fixco_custom/models/queue_job.py
@@ -0,0 +1,56 @@
+from odoo import models, fields, api
+from odoo.exceptions import UserError
+import traceback
+
+class QueueJob(models.Model):
+ _name = 'queue.job'
+ _description = 'Queueing Job Runner'
+ _order = 'create_date desc'
+
+ name = fields.Char(required=True)
+ model_name = fields.Char(required=True)
+ method_name = fields.Char(required=True)
+ res_id = fields.Integer(string='Record ID')
+ state = fields.Selection([
+ ('draft', 'Draft'),
+ ('running', 'Running'),
+ ('done', 'Done'),
+ ('error', 'Error'),
+ ], default='draft')
+
+ error_message = fields.Text()
+
+ def action_run_selected(self):
+ for job in self:
+ job.action_run()
+
+ def action_run(self, limit=10):
+ jobs = self.search([('state', '=', 'draft'), ('method_name', '=', 'get_order_id_and_create_detail_order')], order='create_date desc', limit=limit)
+ if not jobs:
+ jobs = self.search([('state', '=', 'draft'), ('method_name', '!=', 'get_order_id_and_create_detail_order')], order='create_date desc', limit=limit)
+ for job in jobs:
+ try:
+ job.write({'state': 'running'})
+ self.env.cr.commit()
+
+ record = self.env[job.model_name].browse(job.res_id)
+ if not record.exists():
+ raise UserError('Target record not found')
+
+ method = getattr(record, job.method_name, None)
+ if not method:
+ raise UserError('Method not found')
+
+ with self.env.cr.savepoint():
+ method()
+
+ job.write({'state': 'done'})
+ self.env.cr.commit()
+
+ except Exception:
+ job.write({
+ 'state': 'error',
+ 'error_message': traceback.format_exc()
+ })
+ self.env.cr.commit()
+
diff --git a/fixco_custom/models/sale.py b/fixco_custom/models/sale.py
index b7cbe17..8b04538 100755
--- a/fixco_custom/models/sale.py
+++ b/fixco_custom/models/sale.py
@@ -19,6 +19,18 @@ class SaleOrder(models.Model):
remaining_down_payment = fields.Float('Remaining Down Payment', compute='_compute_remaining_down_payment', store=True)
+ def create_invoices(self):
+ created_invoices = self.env['account.move']
+ for order in self:
+ # Create invoice for this SO only
+ invoice = order.with_context(default_invoice_origin=order.name)._create_invoices(final=True)
+ invoice.action_post()
+ created_invoices += invoice
+
+ # Link the invoice to the SO
+ order.invoice_ids += invoice
+
+
def _compute_remaining_down_payment(self):
for order in self:
down_payments = self.env['account.move'].search([
diff --git a/fixco_custom/models/sale_order_multi_invoices.py b/fixco_custom/models/sale_order_multi_invoices.py
index 5c42dc6..e6b0b98 100644
--- a/fixco_custom/models/sale_order_multi_invoices.py
+++ b/fixco_custom/models/sale_order_multi_invoices.py
@@ -5,44 +5,58 @@ class SaleOrderMultiInvoices(models.TransientModel):
_name = 'sale.order.multi_invoices'
_description = 'Create Invoices for Multiple Sales Orders'
- def create_invoices(self):
- # Get SO IDs from context
+ def queue_job(self):
so_ids = self._context.get('so_ids', [])
- if not so_ids:
- raise UserError(_("No sales orders selected!"))
-
- # Browse all selected sales orders
sale_orders = self.env['sale.order'].browse(so_ids)
- created_invoices = self.env['account.move']
+ for sale in sale_orders:
+ queue_job = self.env['queue.job'].search([('res_id', '=', sale.id), ('method_name', '=', 'create_invoices')], limit=1)
+ if queue_job:
+ continue
+ self.env['queue.job'].create({
+ 'name': f'Create Invoice {sale.name}',
+ 'model_name': 'sale.order',
+ 'method_name': 'create_invoices',
+ 'res_id': sale.id,
+ })
+
+ # def create_invoices(self):
+ # # Get SO IDs from context
+ # so_ids = self._context.get('so_ids', [])
+ # if not so_ids:
+ # raise UserError(_("No sales orders selected!"))
+
+ # # Browse all selected sales orders
+ # sale_orders = self.env['sale.order'].browse(so_ids)
+ # created_invoices = self.env['account.move']
- # Create one invoice per SO (even if partner is the same)
- for order in sale_orders:
- # Create invoice for this SO only
- invoice = order.with_context(default_invoice_origin=order.name)._create_invoices(final=True)
- invoice.action_post()
- created_invoices += invoice
+ # # Create one invoice per SO (even if partner is the same)
+ # for order in sale_orders:
+ # # Create invoice for this SO only
+ # invoice = order.with_context(default_invoice_origin=order.name)._create_invoices(final=True)
+ # invoice.action_post()
+ # created_invoices += invoice
- # Link the invoice to the SO
- order.invoice_ids += invoice
+ # # Link the invoice to the SO
+ # order.invoice_ids += invoice
- # Return action to view created invoices
- if len(created_invoices) > 1:
- action = {
- 'name': _('Created Invoices'),
- 'type': 'ir.actions.act_window',
- 'res_model': 'account.move',
- 'view_mode': 'tree,form',
- 'domain': [('id', 'in', created_invoices.ids)],
- }
- elif created_invoices:
- action = {
- 'name': _('Created Invoice'),
- 'type': 'ir.actions.act_window',
- 'res_model': 'account.move',
- 'view_mode': 'form',
- 'res_id': created_invoices.id,
- }
- else:
- action = {'type': 'ir.actions.act_window_close'}
+ # # Return action to view created invoices
+ # if len(created_invoices) > 1:
+ # action = {
+ # 'name': _('Created Invoices'),
+ # 'type': 'ir.actions.act_window',
+ # 'res_model': 'account.move',
+ # 'view_mode': 'tree,form',
+ # 'domain': [('id', 'in', created_invoices.ids)],
+ # }
+ # elif created_invoices:
+ # action = {
+ # 'name': _('Created Invoice'),
+ # 'type': 'ir.actions.act_window',
+ # 'res_model': 'account.move',
+ # 'view_mode': 'form',
+ # 'res_id': created_invoices.id,
+ # }
+ # else:
+ # action = {'type': 'ir.actions.act_window_close'}
- return action \ No newline at end of file
+ # return action \ No newline at end of file
diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py
index b7f2fd6..7437ca5 100755
--- a/fixco_custom/models/stock_picking.py
+++ b/fixco_custom/models/stock_picking.py
@@ -62,7 +62,8 @@ class StockPicking(models.Model):
ginee_pickup_time_id = fields.Char("Pickup Time ID", tracking=True)
ginee_task_id = fields.Char("Ginee Task ID", tracking=True)
- soo_number = fields.Char(string='SOO Altama Number', related='purchase_id.soo_number')
+ soo_number = fields.Char(string='SOO Altama Number')
+ number_soo = fields.Char(string='Number SOO Altama')
type_sku = fields.Selection([('single', 'Single SKU'), ('multi', 'Multi SKU')], string='Type SKU')
list_product = fields.Char(string='List Product')
is_dispatched = fields.Boolean(string='Is Dispatched', default=False, compute='_compute_is_dispatched', readonly=True)
@@ -72,7 +73,6 @@ class StockPicking(models.Model):
for picking in self:
picking.is_dispatched = bool(picking.shipment_group_id)
-
def action_cancel_selected_pickings(self):
for picking in self:
if picking.state == 'done':
@@ -155,7 +155,7 @@ class StockPicking(models.Model):
def action_create_invoice_from_mr(self):
"""Create the invoice associated to the PO.
"""
- if self.env.user.id == 13:
+ if not self.env.user.id == 13:
raise UserError('Hanya Accounting yang bisa membuat Bill')
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
diff --git a/fixco_custom/models/upload_cancel_picking.py b/fixco_custom/models/upload_cancel_picking.py
index a42ef1d..b4038bf 100644
--- a/fixco_custom/models/upload_cancel_picking.py
+++ b/fixco_custom/models/upload_cancel_picking.py
@@ -144,8 +144,13 @@ class UploadCancelPicking(models.Model):
}
def action_cancel_picking(self):
- self.date_upload = datetime.utcnow()
- self.picking_lines.cancel_picking()
+ for line in self.picking_lines:
+ self.env['queue.job'].create({
+ 'name': f'Cancel Picking {line.name}',
+ 'model_name': 'upload.cancel.picking.line',
+ 'method_name': 'cancel_picking',
+ 'res_id': line.id,
+ })
class UploadCancelPickingLine(models.Model):
@@ -209,5 +214,4 @@ class UploadCancelPickingLine(models.Model):
) % line.invoice_marketplace
def cancel_picking(self):
- for line in self:
- line.picking_id.action_cancel() \ No newline at end of file
+ self.picking_id.action_cancel() \ No newline at end of file
diff --git a/fixco_custom/models/upload_ginee.py b/fixco_custom/models/upload_ginee.py
index d522787..4341269 100644
--- a/fixco_custom/models/upload_ginee.py
+++ b/fixco_custom/models/upload_ginee.py
@@ -161,12 +161,23 @@ class UploadGinee(models.Model):
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()
+ # 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()
+ def action_get_order_id_and_create_detail_order(self):
+ for line in self.ginee_lines:
+ queue_job = self.env['queue.job'].search([('res_id', '=', line.id), ('method_name', '=', 'get_order_id_and_create_detail_order')], limit=1)
+ if queue_job:
+ continue
+ self.env['queue.job'].create({
+ 'name': f'Get Order Ginee {line.invoice_marketplace}',
+ 'model_name': 'upload.ginee.line',
+ 'method_name': 'get_order_id_and_create_detail_order',
+ 'res_id': line.id,
+ })
+
class UploadGineeLine(models.Model):
_name = "upload.ginee.line"
_description = "Upload Ginee Line"
@@ -182,6 +193,10 @@ class UploadGineeLine(models.Model):
is_grouped = fields.Boolean('Is Grouped', default=False)
group_key = fields.Char('Group Key')
+ def get_order_id_and_create_detail_order(self):
+ self.get_order_id()
+ self.create_so_and_detail_order()
+
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]
diff --git a/fixco_custom/security/ir.model.access.csv b/fixco_custom/security/ir.model.access.csv
index 7795156..817595b 100755
--- a/fixco_custom/security/ir.model.access.csv
+++ b/fixco_custom/security/ir.model.access.csv
@@ -44,3 +44,4 @@ access_stock_return_picking,stock.return.picking,model_stock_return_picking,,1,1
access_stock_return_picking_line,stock.return.picking.line,model_stock_return_picking_line,,1,1,1,1
access_upload_cancel_picking,access.upload.cancel.picking,model_upload_cancel_picking,,1,1,1,1
access_upload_cancel_picking_line,access.upload.cancel.picking.line,model_upload_cancel_picking_line,,1,1,1,1
+access_queue_job,access.queue.job,model_queue_job,,1,1,1,1 \ No newline at end of file
diff --git a/fixco_custom/views/queue_job.xml b/fixco_custom/views/queue_job.xml
new file mode 100644
index 0000000..9934d1b
--- /dev/null
+++ b/fixco_custom/views/queue_job.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<odoo>
+ <record id="view_queue_job_tree" model="ir.ui.view">
+ <field name="name">queue.job.tree</field>
+ <field name="model">queue.job</field>
+ <field name="arch" type="xml">
+ <tree create="false" edit="false" decoration-success="state == 'done'"
+ decoration-danger="state == 'error'"
+ decoration-warning="state == 'running'">
+
+ <field name="name"/>
+ <field name="model_name"/>
+ <field name="method_name"/>
+ <field name="res_id"/>
+ <field name="state"/>
+
+ <button name="action_run"
+ type="object"
+ string="RUN"
+ class="btn-primary"
+ attrs="{'invisible': [('state', '=', 'done')]}"/>
+
+ </tree>
+ </field>
+ </record>
+
+ <record id="action_run_selected_queue_job" model="ir.actions.server">
+ <field name="name">Execute Selected Jobs</field>
+ <field name="model_id" ref="model_queue_job"/>
+ <field name="binding_model_id" ref="model_queue_job"/>
+ <field name="binding_type">action</field>
+ <field name="state">code</field>
+ <field name="code">
+ records.action_run_selected()
+ </field>
+ </record>
+
+
+
+ <record id="queue_job_action" model="ir.actions.act_window">
+ <field name="name">Queue Job</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">queue.job</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <menuitem
+ action="queue_job_action"
+ id="queue_job"
+ parent="base.menu_users"
+ name="Queue Job"
+ sequence="1"
+ />
+</odoo>
diff --git a/fixco_custom/views/sale_order_multi_invoices.xml b/fixco_custom/views/sale_order_multi_invoices.xml
index 0f8087c..1e9c24a 100644
--- a/fixco_custom/views/sale_order_multi_invoices.xml
+++ b/fixco_custom/views/sale_order_multi_invoices.xml
@@ -16,7 +16,7 @@
</div>
</sheet>
<footer>
- <button name="create_invoices" string="Create Invoices" type="object"
+ <button name="queue_job" string="Create Invoices" type="object"
class="btn-primary" default_focus="1"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
diff --git a/fixco_custom/views/stock_picking.xml b/fixco_custom/views/stock_picking.xml
index b7fb001..875e50a 100755
--- a/fixco_custom/views/stock_picking.xml
+++ b/fixco_custom/views/stock_picking.xml
@@ -72,7 +72,7 @@
<field name="location_id" position="after">
<field name="carrier"/>
<field name="shipment_group_id"/>
- <field name="soo_number"/>
+ <field name="number_soo"/>
<field name="type_sku"/>
</field>