diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-12-22 13:36:43 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-12-22 13:36:43 +0700 |
| commit | 74bc0544d9789479f599e808930e01ecea7fbf22 (patch) | |
| tree | ef11ccc1620ab31ee1b560c8b16f0552041a7742 | |
| parent | b03b5e7d3ab83db6f26610490fc2a4e7dc4d3d9c (diff) | |
push
| -rwxr-xr-x | fixco_custom/models/__init__.py | 3 | ||||
| -rw-r--r-- | fixco_custom/models/account_move_line.py | 2 | ||||
| -rw-r--r-- | fixco_custom/models/account_move_reversal.py | 67 | ||||
| -rwxr-xr-x | fixco_custom/models/detail_order.py | 1 | ||||
| -rwxr-xr-x | fixco_custom/models/sale.py | 32 | ||||
| -rw-r--r-- | fixco_custom/models/sale_order_multi_invoices.py | 1 | ||||
| -rw-r--r-- | fixco_custom/models/shipment_group.py | 2 | ||||
| -rwxr-xr-x | fixco_custom/models/stock_picking.py | 35 | ||||
| -rw-r--r-- | fixco_custom/models/stock_picking_return.py | 2 | ||||
| -rw-r--r-- | fixco_custom/models/upload_ginee.py | 4 | ||||
| -rw-r--r-- | fixco_custom/models/upload_payments.py | 1 | ||||
| -rwxr-xr-x | fixco_custom/views/sale_order.xml | 10 |
12 files changed, 135 insertions, 25 deletions
diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py index f20c116..37c8b45 100755 --- a/fixco_custom/models/__init__.py +++ b/fixco_custom/models/__init__.py @@ -33,4 +33,5 @@ from . import uangmuka_pembelian from . import coretax_faktur from . import token_log from . import purchase_pricelist_wizard -from . import stock_picking_return
\ No newline at end of file +from . import stock_picking_return +from . import account_move_reversal
\ No newline at end of file diff --git a/fixco_custom/models/account_move_line.py b/fixco_custom/models/account_move_line.py index 68df00b..d28a9de 100644 --- a/fixco_custom/models/account_move_line.py +++ b/fixco_custom/models/account_move_line.py @@ -15,6 +15,6 @@ class AccountMoveLine(models.Model): @api.onchange('quantity') def _onchange_quantity(self): for line in self: - if line.move_id.move_type == 'in_invoice': + if line.move_id.move_type == 'in_invoice' and line.id.origin: if line and line.quantity > line.qty_outstanding: raise UserError(_("Quantity Tidak Boleh Melebihi Qty Outstanding")) diff --git a/fixco_custom/models/account_move_reversal.py b/fixco_custom/models/account_move_reversal.py new file mode 100644 index 0000000..eac8660 --- /dev/null +++ b/fixco_custom/models/account_move_reversal.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api +from odoo.tools.translate import _ +from odoo.exceptions import UserError + + +class AccountMoveReversal(models.TransientModel): + _inherit = 'account.move.reversal' + + def reverse_moves(self): + self.ensure_one() + moves = self.move_ids + + if moves.move_type == 'entry' and moves.sale_id and moves.ref.startswith('UANG MUKA PENJUALAN') and self.env.user.id not in [9, 10, 15]: + raise UserError(_('Anda tidak memiliki akses untuk melakukan reverse Uang Muka Penjualan!')) + + # Create default values. + default_values_list = [] + for move in moves: + default_values_list.append(self._prepare_default_reversal(move)) + + batches = [ + [self.env['account.move'], [], True], # Moves to be cancelled by the reverses. + [self.env['account.move'], [], False], # Others. + ] + for move, default_vals in zip(moves, default_values_list): + is_auto_post = bool(default_vals.get('auto_post')) + is_cancel_needed = not is_auto_post and self.refund_method in ('cancel', 'modify') + batch_index = 0 if is_cancel_needed else 1 + batches[batch_index][0] |= move + batches[batch_index][1].append(default_vals) + + # Handle reverse method. + moves_to_redirect = self.env['account.move'] + for moves, default_values_list, is_cancel_needed in batches: + new_moves = moves._reverse_moves(default_values_list, cancel=is_cancel_needed) + + if self.refund_method == 'modify': + moves_vals_list = [] + for move in moves.with_context(include_business_fields=True): + moves_vals_list.append(move.copy_data({'date': self.date if self.date_mode == 'custom' else move.date})[0]) + new_moves = self.env['account.move'].create(moves_vals_list) + + moves_to_redirect |= new_moves + + self.new_move_ids = moves_to_redirect + + # Create action. + action = { + 'name': _('Reverse Moves'), + 'type': 'ir.actions.act_window', + 'res_model': 'account.move', + } + if len(moves_to_redirect) == 1: + action.update({ + 'view_mode': 'form', + 'res_id': moves_to_redirect.id, + 'context': {'default_move_type': moves_to_redirect.move_type}, + }) + else: + action.update({ + 'view_mode': 'tree,form', + 'domain': [('id', 'in', moves_to_redirect.ids)], + }) + if len(set(moves_to_redirect.mapped('move_type'))) == 1: + action['context'] = {'default_move_type': moves_to_redirect.mapped('move_type').pop()} + return action diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py index 6bb5429..598fb70 100755 --- a/fixco_custom/models/detail_order.py +++ b/fixco_custom/models/detail_order.py @@ -167,6 +167,7 @@ class DetailOrder(models.Model): 'picking_policy': 'direct', 'carrier': json_data.get('data', {})[0].get('logisticsInfos')[0].get('logisticsProviderName'), 'invoice_mp': json_data.get('data', {})[0].get('externalOrderId'), + 'source': 'ginee', 'channel': json_data.get('data', {})[0].get('channel'), } return data diff --git a/fixco_custom/models/sale.py b/fixco_custom/models/sale.py index 4a1b79e..b7cbe17 100755 --- a/fixco_custom/models/sale.py +++ b/fixco_custom/models/sale.py @@ -5,12 +5,13 @@ from odoo.exceptions import UserError class SaleOrder(models.Model): _inherit = "sale.order" - 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') - channel = fields.Char('Channel') - note_by_buyer = fields.Char('Note By Buyer') + carrier = fields.Char(string='Shipping Method', required=True, copy=False) + invoice_mp = fields.Char(string='Invoice Marketplace', required=True, copy=False) + order_reference = fields.Char(string='Order Reference', required=True, copy=False) + address = fields.Char('Address', copy=False) + channel = fields.Char('Channel', copy=False) + note_by_buyer = fields.Char('Note By Buyer', copy=False) + source = fields.Selection([('manual', 'Manual'), ('ginee', 'Ginee')], string='Source', default='manual', copy=False) count_payment = fields.Integer('Count Payment', compute='_compute_count_payment') @@ -107,15 +108,16 @@ class SaleOrder(models.Model): 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 rec.order_reference and rec.invoice_mp: + 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}') + 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') @@ -193,6 +195,8 @@ class SaleOrder(models.Model): def action_confirm(self): for order in self: + if order.source == 'manual' and self.env.user.id not in [9, 10, 15]: + raise UserError("Anda tidak memiliki akses untuk approve SO manual") order._check_duplicate_order_id() res = super(SaleOrder, self).action_confirm() return res diff --git a/fixco_custom/models/sale_order_multi_invoices.py b/fixco_custom/models/sale_order_multi_invoices.py index 2638ddc..5c42dc6 100644 --- a/fixco_custom/models/sale_order_multi_invoices.py +++ b/fixco_custom/models/sale_order_multi_invoices.py @@ -19,6 +19,7 @@ class SaleOrderMultiInvoices(models.TransientModel): 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 diff --git a/fixco_custom/models/shipment_group.py b/fixco_custom/models/shipment_group.py index 546251a..b57cfa8 100644 --- a/fixco_custom/models/shipment_group.py +++ b/fixco_custom/models/shipment_group.py @@ -96,7 +96,7 @@ class ShipmentGroup(models.Model): if not picking_line.picking_id: continue - for move in picking_line.picking_id.move_ids_without_package: + for move in picking_line.picking_id.move_line_ids_without_package: existing_line = record.shipment_line.filtered( lambda l: l.product_id == move.product_id and l.picking_id.tracking_number == picking_line.scan_receipt and diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py index e4ed1b5..3610179 100755 --- a/fixco_custom/models/stock_picking.py +++ b/fixco_custom/models/stock_picking.py @@ -66,13 +66,44 @@ class StockPicking(models.Model): type_sku = fields.Selection([('single', 'Single SKU'), ('multi', 'Multi SKU')], string='Type SKU') list_product = fields.Char(string='List Product') + def create_invoices(self): + so_id = self.sale_id.id + if not so_id: + raise UserError(_("Gaada So nya!")) + + sale_orders = self.env['sale.order'].browse(so_id) + created_invoices = self.env['account.move'] + + for order in sale_orders: + invoice = order.with_context(default_invoice_origin=order.name)._create_invoices(final=True) + invoice.action_post() + created_invoices += invoice + + order.invoice_ids += invoice + + if 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 + def button_validate(self): origin = self.origin or '' if any(prefix in origin for prefix in ['PO/', 'SO/']) and not self.check_product_lines and not self.name.startswith('BU/INT'): raise UserError(_("Belum ada check product, gabisa validate")) + + res = super(StockPicking, self).button_validate() - - return super(StockPicking, self).button_validate() + if self.name.startswith('BU/OUT') and self.origin.startswith('SO/'): + self.create_invoices() + return res @api.depends('move_lines.origin_returned_move_id') diff --git a/fixco_custom/models/stock_picking_return.py b/fixco_custom/models/stock_picking_return.py index 0574d66..2e57241 100644 --- a/fixco_custom/models/stock_picking_return.py +++ b/fixco_custom/models/stock_picking_return.py @@ -10,7 +10,7 @@ class ReturnPicking(models.TransientModel): def create_returns(self): if ( - self.env.user.id not in [12, 10, 2, 15] + self.env.user.id not in [12, 10, 2, 15,] and 'BU/IN' in self.picking_id.name and 'PO/' in self.picking_id.origin and self.picking_id.picking_type_code == 'incoming' diff --git a/fixco_custom/models/upload_ginee.py b/fixco_custom/models/upload_ginee.py index 8cb07cf..cdfa3a8 100644 --- a/fixco_custom/models/upload_ginee.py +++ b/fixco_custom/models/upload_ginee.py @@ -162,6 +162,7 @@ class UploadGinee(models.Model): 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() @@ -255,6 +256,8 @@ class UploadGineeLine(models.Model): # First group BLIBLI orders by their invoice prefix grouped_lines = {} for rec in self: + if rec.detail_order_id: + continue if rec.upload_ginee_id.upload_type == 'blibli' and '-' in rec.invoice_marketplace: prefix = rec.invoice_marketplace.split('-')[0] if prefix not in grouped_lines: @@ -306,6 +309,7 @@ class UploadGineeLine(models.Model): line.message_error = str(e) def get_order_id(self): + for rec in self: try: if rec.order_id: diff --git a/fixco_custom/models/upload_payments.py b/fixco_custom/models/upload_payments.py index 44e2e27..c7e144f 100644 --- a/fixco_custom/models/upload_payments.py +++ b/fixco_custom/models/upload_payments.py @@ -70,7 +70,6 @@ class UploadPayments(models.Model): created_payments = [] for line in self.payments_lines.filtered(lambda l: not l.payment_id): - # Cari invoice berdasarkan invoice_marketplace invoice = self.env['account.move'].search([ ('invoice_marketplace', '=', line.no_invoice), ('state', '=', 'posted'), diff --git a/fixco_custom/views/sale_order.xml b/fixco_custom/views/sale_order.xml index 5d702e5..9f6e649 100755 --- a/fixco_custom/views/sale_order.xml +++ b/fixco_custom/views/sale_order.xml @@ -34,10 +34,11 @@ <field name="address"/> </field> <field name="client_order_ref" position="after"> - <field name="order_reference" required="1"/> - <field name="invoice_mp" required="1"/> - <field name="channel" required="1"/> + <field name="order_reference" attrs="{'required': [('source', '!=', 'manual')]}"/> + <field name="invoice_mp" attrs="{'required': [('source', '!=', 'manual')]}"/> + <field name="channel" attrs="{'required': [('source', '!=', 'manual')]}"/> <field name="note_by_buyer" readonly="1"/> + <field name="source" readonly="1"/> </field> <field name="amount_total" position="after"> <field name="remaining_down_payment"/> @@ -56,6 +57,7 @@ <field name="remaining_down_payment" optional="hide"/> <field name="order_reference" optional="hide"/> <field name="invoice_mp" optional="hide"/> + <field name="source" optional="hide"/> </field> </field> </record> @@ -71,7 +73,7 @@ <field name="remaining_down_payment" optional="hide"/> <field name="order_reference" optional="hide"/> <field name="invoice_mp" optional="hide"/> - <field name="channel" optional="hide"/> + <field name="source" optional="hide"/> </field> </field> </record> |
