diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-09 13:03:09 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2026-01-09 13:03:09 +0700 |
| commit | 82c1232c08894dad3d6e326649785b5669a12077 (patch) | |
| tree | a4f479052a9d59a58719e73b2b9ef4443e98bd05 | |
| parent | 4db2619225eea1edb72da972ba2b829008e40f30 (diff) | |
push
| -rwxr-xr-x | fixco_custom/models/__init__.py | 3 | ||||
| -rw-r--r-- | fixco_custom/models/account_move.py | 39 | ||||
| -rw-r--r-- | fixco_custom/models/account_move_reversal.py | 9 | ||||
| -rw-r--r-- | fixco_custom/models/account_payment.py | 11 | ||||
| -rwxr-xr-x | fixco_custom/models/detail_order.py | 19 | ||||
| -rwxr-xr-x | fixco_custom/models/sale.py | 2 | ||||
| -rwxr-xr-x | fixco_custom/models/stock_picking.py | 28 | ||||
| -rw-r--r-- | fixco_custom/views/account_move.xml | 23 | ||||
| -rwxr-xr-x | fixco_custom/views/sale_order.xml | 2 |
9 files changed, 131 insertions, 5 deletions
diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py index 0068d32..de92dc0 100755 --- a/fixco_custom/models/__init__.py +++ b/fixco_custom/models/__init__.py @@ -38,4 +38,5 @@ from . import account_move_reversal from . import upload_cancel_picking from . import product_supplierinfo from . import queue_job -from . import purchase_order_multi_bills
\ No newline at end of file +from . import purchase_order_multi_bills +from . import account_payment
\ No newline at end of file diff --git a/fixco_custom/models/account_move.py b/fixco_custom/models/account_move.py index e40e65f..b96bed3 100644 --- a/fixco_custom/models/account_move.py +++ b/fixco_custom/models/account_move.py @@ -47,6 +47,29 @@ class AccountMove(models.Model): compute="_compute_need_refund", help="Flag otomatis kalau invoice sudah paid dan picking terkait di-return." ) + approval_refund = fields.Selection( + [('approved', 'Approved'), + ('rejected', 'Rejected'), + ('pending', 'Pending')], + string='Approval Refund', + copy=False, + tracking=True + ) + + def reject_refund(self): + if self.move_type == 'entry' and self.sale_id and self.ref.startswith('UANG MUKA PENJUALAN') and self.env.user.id in [9, 10, 15]: + self.approval_refund = 'rejected' + else: + raise UserError(_('Anda tidak memiliki akses untuk melakukan reject Uang Muka Penjualan!')) + + # def approve_refund(self): + # if self.move_type == 'entry' and self.sale_id and self.ref.startswith('UANG MUKA PENJUALAN') and self.env.user.id in [9, 10, 15]: + # self.approval_refund = 'approved' + # else: + # raise UserError(_('Anda tidak memiliki akses untuk melakukan approve Uang Muka Penjualan!')) + + def pending_refund(self): + self.approval_refund = 'pending' def queue_job_cancel_bill(self): QueueJob = self.env['queue.job'] @@ -73,7 +96,19 @@ class AccountMove(models.Model): 'res_id': move.id, } ]) - + + def button_draft(self): + if self.env.user.id not in [24, 13, 10, 2, 9, 15, 8]: + raise UserError("Hanya Finance yang bisa ubah Draft") + res = super(AccountMove, self).button_draft() + return res + + def button_cancel(self): + if self.env.user.id not in [24, 13, 10, 2, 9, 15, 8]: + raise UserError('Hanya Accounting yang bisa Cancel') + res = super(AccountMove, self).button_cancel() + + return res def _compute_need_refund(self): for move in self: @@ -223,6 +258,8 @@ class AccountMove(models.Model): } def action_post(self): + if self.env.user.id not in [24, 13, 10, 2, 9, 15, 8]: + raise UserError('Hanya Accounting yang bisa Post') res = super(AccountMove, self).action_post() for entry in self: if entry.move_type == 'out_invoice': diff --git a/fixco_custom/models/account_move_reversal.py b/fixco_custom/models/account_move_reversal.py index eac8660..2645645 100644 --- a/fixco_custom/models/account_move_reversal.py +++ b/fixco_custom/models/account_move_reversal.py @@ -11,8 +11,13 @@ class AccountMoveReversal(models.TransientModel): 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!')) + if moves.move_type == 'entry' and moves.sale_id and moves.ref.startswith('UANG MUKA PENJUALAN'): + if not moves.approval_refund: + raise UserError(_('User harus ajukan approval refund!')) + if moves.approval_refund == 'rejected': + raise UserError(_('refund telah ditolak!')) + + moves.approval_refund = 'approved' # Create default values. default_values_list = [] diff --git a/fixco_custom/models/account_payment.py b/fixco_custom/models/account_payment.py new file mode 100644 index 0000000..2c7a5b4 --- /dev/null +++ b/fixco_custom/models/account_payment.py @@ -0,0 +1,11 @@ +from odoo import fields, models, api +from odoo.tools.misc import format_date, OrderedSet +from odoo.exceptions import UserError + +class AccountPayment(models.Model): + _inherit = 'account.payment' + + @api.constrains('journal_id') + def set_default_journal_id(self): + for rec in self: + rec.journal_id = 21
\ No newline at end of file diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py index b3e10a2..c256d8c 100755 --- a/fixco_custom/models/detail_order.py +++ b/fixco_custom/models/detail_order.py @@ -5,9 +5,10 @@ import requests import json import hmac import base64 -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from hashlib import sha256 import logging +import pytz _logger = logging.getLogger(__name__) @@ -205,6 +206,21 @@ class DetailOrder(models.Model): return partner.id def prepare_data_so(self, json_data): + date_str = json_data.get('data', [{}])[0].get('promisedToShipBefore') + deadline_date = False + + if date_str: + # utc_dt = datetime.strptime( + # date_str, + # "%Y-%m-%dT%H:%M:%SZ" + # ).replace(tzinfo=pytz.UTC) + + # wib_tz = pytz.timezone('Asia/Jakarta') + # deadline_date = utc_dt.astimezone(wib_tz).replace(tzinfo=None) + deadline_date = datetime.strptime( + date_str, + "%Y-%m-%dT%H:%M:%SZ" + ) + timedelta(hours=1) data = { 'partner_id': self.get_partner(json_data.get('data', {})[0].get('shopId')), 'client_order_ref': json_data.get('data', {})[0].get('orderId'), @@ -214,6 +230,7 @@ class DetailOrder(models.Model): 'invoice_mp': json_data.get('data', {})[0].get('externalOrderId'), 'source': 'ginee', 'channel': json_data.get('data', {})[0].get('channel'), + 'deadline_date': deadline_date, } return data diff --git a/fixco_custom/models/sale.py b/fixco_custom/models/sale.py index cd5f68f..b8aa963 100755 --- a/fixco_custom/models/sale.py +++ b/fixco_custom/models/sale.py @@ -19,6 +19,8 @@ class SaleOrder(models.Model): remaining_down_payment = fields.Float('Remaining Down Payment', compute='_compute_remaining_down_payment', store=True) + deadline_date = fields.Datetime('Deadline', copy=False) + def create_invoices(self): created_invoices = self.env['account.move'] for order in self: diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py index 76c2ecf..c2d5150 100755 --- a/fixco_custom/models/stock_picking.py +++ b/fixco_custom/models/stock_picking.py @@ -68,6 +68,29 @@ class StockPicking(models.Model): list_product = fields.Char(string='List Product') is_dispatched = fields.Boolean(string='Is Dispatched', default=False, compute='_compute_is_dispatched', readonly=True) + def check_qty_bundling_product(self): + for line in self.move_ids_without_package: + if '(Bundle Component)' in line.sale_line_id.name: + if line.forecast_availability < 1 or line.quantity_done < 1: + raise UserError('Barang Bundling : %s Quantity Done tidak boleh 0' % line.product_id.display_name) + + def check_qty_done_stock(self): + for line in self.move_line_ids_without_package: + def check_qty_per_inventory(self, product, location): + quant = self.env['stock.quant'].search([ + ('product_id', '=', product.id), + ('location_id', '=', location.id), + ]) + + if quant: + return quant.quantity + + return 0 + + qty_onhand = check_qty_per_inventory(self, line.product_id, line.location_id) + if line.qty_done > qty_onhand: + raise UserError('Quantity Done melebihi Quantity Onhand') + @api.depends('shipment_group_id') def _compute_is_dispatched(self): for picking in self: @@ -122,6 +145,10 @@ class StockPicking(models.Model): return action def button_validate(self): + if not self.picking_type_code == 'incoming' and not self.name.startswith('BU/IN'): + self.check_qty_done_stock() + self.check_qty_bundling_product() + 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")) @@ -285,6 +312,7 @@ class StockPicking(models.Model): self.carrier = picking.sale_id.carrier self.address = picking.sale_id.address self.note_by_buyer = picking.sale_id.note_by_buyer + self.date_deadline = picking.sale_id.deadline_date self.schema_multi_single_sku() def schema_multi_single_sku(self): diff --git a/fixco_custom/views/account_move.xml b/fixco_custom/views/account_move.xml index 52dd64c..d5ae9ae 100644 --- a/fixco_custom/views/account_move.xml +++ b/fixco_custom/views/account_move.xml @@ -10,6 +10,28 @@ <button name="action_post" position="after"> <button name="fixco_custom.action_view_invoice_reklas" string="Reklas" type="action" class="btn-primary" attrs="{'invisible': [('state', '!=', 'posted')]}"/> + <button name="pending_refund" + string="Pengajuan Refund" + type="object" + class="btn-primary" + attrs="{'invisible': [ + '|', + ('move_type', '!=', 'entry'), + '|', + ('state', '!=', 'posted'), + ('approval_refund', 'in', ('pending','approved','rejected')) + ]}"/> + + <button name="reject_refund" string="Tolak Pengajuan Refund" + type="object" class="btn-primary" attrs="{'invisible': [ + '|', + ('move_type', '!=', 'entry'), + '|', + ('state', '!=', 'posted'), + ('approval_refund', 'in', ('approved','rejected')) + ]}"/> + <!-- <button name="approve_refund" string="Approved Pengajuan Refund" + type="object" class="btn-primary" attrs="{'invisible': [('state', '!=', 'posted'), ('move_type', '!=', 'entry'), ('approval_refund', 'in', ('approved','rejected'))]}"/> --> </button> <button name="open_reconcile_view" position="after"> @@ -48,6 +70,7 @@ <field name="reklas_used_by" readonly="1" attrs="{'invisible': [('move_type', '!=', 'entry')]}"/> </field> <field name="invoice_date" position="after"> + <field name="approval_refund" readonly="1" attrs="{'invisible': [('move_type', 'not in', ('entry'))]}"/> <field name="sale_id" readonly="1" attrs="{'invisible': [('move_type', 'not in', ('out_invoice','entry'))]}"/> <field name="purchase_order_id" readonly="1" attrs="{'invisible': [('move_type', 'not in', ('in_invoice','entry'))]}"/> <field name="picking_id" readonly="1" attrs="{'invisible': [('move_type', '!=', 'out_invoice')]}"/> diff --git a/fixco_custom/views/sale_order.xml b/fixco_custom/views/sale_order.xml index 9f6e649..b29bcb9 100755 --- a/fixco_custom/views/sale_order.xml +++ b/fixco_custom/views/sale_order.xml @@ -39,6 +39,7 @@ <field name="channel" attrs="{'required': [('source', '!=', 'manual')]}"/> <field name="note_by_buyer" readonly="1"/> <field name="source" readonly="1"/> + <field name="deadline_date"/> </field> <field name="amount_total" position="after"> <field name="remaining_down_payment"/> @@ -58,6 +59,7 @@ <field name="order_reference" optional="hide"/> <field name="invoice_mp" optional="hide"/> <field name="source" optional="hide"/> + <field name="deadline_date" optional="hide"/> </field> </field> </record> |
