diff options
| -rw-r--r-- | indoteknik_custom/models/approval_invoice_date.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/automatic_purchase.py | 38 | ||||
| -rw-r--r-- | indoteknik_custom/models/dunning_run.py | 5 | ||||
| -rw-r--r-- | indoteknik_custom/models/mrp_production.py | 32 | ||||
| -rwxr-xr-x | indoteknik_custom/models/product_template.py | 186 | ||||
| -rw-r--r-- | indoteknik_custom/models/requisition.py | 14 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 35 | ||||
| -rw-r--r-- | indoteknik_custom/models/user_pengajuan_tempo_request.py | 9 | ||||
| -rw-r--r-- | indoteknik_custom/views/product_product.xml | 1 | ||||
| -rw-r--r-- | indoteknik_custom/views/user_pengajuan_tempo_request.xml | 2 |
10 files changed, 171 insertions, 152 deletions
diff --git a/indoteknik_custom/models/approval_invoice_date.py b/indoteknik_custom/models/approval_invoice_date.py index b58d55d4..e1bc4c9b 100644 --- a/indoteknik_custom/models/approval_invoice_date.py +++ b/indoteknik_custom/models/approval_invoice_date.py @@ -32,6 +32,7 @@ class ApprovalInvoiceDate(models.Model): if not self.env.user.is_accounting: raise UserError("Hanya Accounting Yang Bisa Approve") self.move_id.invoice_date = self.date_doc_do.date() + self.picking_id.date_doc_kirim = self.date_doc_do self.state = 'done' self.approve_date = datetime.utcnow() self.approve_by = self.env.user.id diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index b66121e1..c9edf07c 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -486,7 +486,7 @@ class AutomaticPurchase(models.Model): # _logger.info('test %s' % point.product_id.name) if point.product_id.qty_available_bandengan > point.product_min_qty: continue - qty_purchase = point.product_max_qty - point.product_id.qty_available_bandengan + qty_purchase = point.product_max_qty - point.product_id.qty_incoming_bandengan - point.product_id.qty_onhand_bandengan po_line = self.env['purchase.order.line'].search([('product_id', '=', point.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1) if self.vendor_id: @@ -589,18 +589,18 @@ class AutomaticPurchaseLine(models.Model): def _get_valid_purchase_price(self, purchase_price): price = 0 - taxes = '' + taxes = 24 human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min - if purchase_price.taxes_product_id.type_tax_use == 'purchase': - price = purchase_price.product_price - taxes = purchase_price.taxes_product_id.id + #if purchase_price.taxes_product_id.type_tax_use == 'purchase': + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id or 24 if system_last_update > human_last_update: - if purchase_price.taxes_system_id.type_tax_use == 'purchase': - price = purchase_price.system_price - taxes = purchase_price.taxes_system_id.id + #if purchase_price.taxes_system_id.type_tax_use == 'purchase': + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id or 24 return price, taxes @@ -696,6 +696,26 @@ class SaleNotInMatchPO(models.Model): purchase_tax_id = fields.Many2one('account.tax', string='Purchase Tax') note_procurement = fields.Many2one(string='Note Procurement') + # 1. yang bug + # def init(self): + # tools.drop_view_if_exists(self.env.cr, self._table) + # self.env.cr.execute(""" + # CREATE OR REPLACE VIEW %s AS( + # select apsm.id, apsm.automatic_purchase_id, apsm.automatic_purchase_line_id, apsm.sale_id, apsm.sale_line_id, + # apsm.picking_id, apsm.move_id, apsm.partner_id, + # apsm.partner_invoice_id, apsm.salesperson_id, apsm.product_id, apsm.qty_so, apsm.qty_po, apsm.create_uid, + # apsm.create_date, apsm.write_uid, apsm.write_date, apsm.purchase_price, + # apsm.purchase_tax_id, apsm.note_procurement + # from automatic_purchase_sales_match apsm + # where apsm.sale_line_id not in ( + # select distinct coalesce(posm.sale_line_id,0) + # from purchase_order_sales_match posm + # join purchase_order po on po.id = posm.purchase_order_id + # where po.state not in ('cancel') + # ) + # ) + # """ % self._table) + def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" @@ -713,4 +733,4 @@ class SaleNotInMatchPO(models.Model): where po.state not in ('cancel') ) ) - """ % self._table) + """ % self._table)
\ No newline at end of file diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index c167aab7..bb53fc0c 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -19,7 +19,7 @@ class DunningRun(models.Model): partner_id = fields.Many2one( 'res.partner', string='Customer', required=True, change_default=True, index=True, tracking=1) - dunning_line = fields.One2many('dunning.run.line', 'dunning_id', string='Dunning Lines', auto_join=True) + dunning_line = fields.One2many('dunning.run.line', 'dunning_id', string='Dunning Lines', auto_join=True, order='invoice_id desc') # dunning_level = fields.Integer(string='Dunning Level', default=30, help='30 hari sebelum jatuh tempo invoice') date_kirim_tukar_faktur = fields.Date(string='Kirim Faktur') resi_tukar_faktur = fields.Char(string='Resi Faktur') @@ -122,7 +122,8 @@ class DunningRun(models.Model): class DunningRunLine(models.Model): _name = 'dunning.run.line' _description = 'Dunning Run Line' - _order = 'dunning_id, id' + # _order = 'dunning_id, id' + _order = 'invoice_id desc, id' dunning_id = fields.Many2one('dunning.run', string='Dunning Ref', required=True, ondelete='cascade', index=True, copy=False) partner_id = fields.Many2one('res.partner', string='Customer') diff --git a/indoteknik_custom/models/mrp_production.py b/indoteknik_custom/models/mrp_production.py index 58c2512c..14821f27 100644 --- a/indoteknik_custom/models/mrp_production.py +++ b/indoteknik_custom/models/mrp_production.py @@ -180,29 +180,29 @@ class MrpProduction(models.Model): # delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') price = 0 - taxes = '' + taxes = 24 vendor_id = '' human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min - if purchase_price.taxes_product_id.type_tax_use == 'purchase': - price = purchase_price.product_price - taxes = purchase_price.taxes_product_id.id + #if purchase_price.taxes_product_id.type_tax_use == 'purchase': + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id or 24 + vendor_id = purchase_price.vendor_id.id + if delta_time > human_last_update: + price = 0 + taxes = '' + vendor_id = '' + + if system_last_update > human_last_update: + #if purchase_price.taxes_system_id.type_tax_use == 'purchase': + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id or 24 vendor_id = purchase_price.vendor_id.id - if delta_time > human_last_update: + if delta_time > system_last_update: price = 0 - taxes = '' + taxes = 24 vendor_id = '' - - if system_last_update > human_last_update: - if purchase_price.taxes_system_id.type_tax_use == 'purchase': - price = purchase_price.system_price - taxes = purchase_price.taxes_system_id.id - vendor_id = purchase_price.vendor_id.id - if delta_time > system_last_update: - price = 0 - taxes = '' - vendor_id = '' return price, taxes, vendor_id diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 17805c6c..3bb54f44 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -797,7 +797,7 @@ class ProductTemplate(models.Model): self.message_post(body=f"<b>Vendor Pricelist</b>: all removed") def _log_field_changes_product(self, vals, old_values): - """Log general field changes for product template""" + """Revised - Log general field changes for product template without posting to variants""" exclude_fields = ['solr_flag', 'desc_update_solr', 'last_update_solr', 'is_edited'] image_fields = ['image_1920', 'image_carousel_lines', 'product_template_image_ids'] @@ -867,13 +867,9 @@ class ProductTemplate(models.Model): changes.append(f"<li><b>{field_label}</b>: '{old_val_str}' → '{new_val_str}'</li>") if changes: + # PERBAIKAN: Hanya post ke template, HAPUS bagian log ke variants record.message_post(body=f"<b>Updated:</b><ul>{''.join(changes)}</ul>") - # log changes to product variants - variant_message = f"<b>Updated:</b><ul>{''.join(changes)}</ul>" - for variant in record.product_variant_ids: - variant.message_post(body=variant_message) - # simpan data lama dan log perubahan field def write(self, vals): context = self._get_context_with_all_info(vals) @@ -913,7 +909,8 @@ class ProductProduct(models.Model): qty_onhand_bandengan = fields.Float(string='Onhand BU', compute='_get_qty_onhand_bandengan') clean_website_description = fields.Char(string='Clean Website Description', compute='_get_clean_website_description') qty_incoming_bandengan = fields.Float(string='Incoming BU', compute='_get_qty_incoming_bandengan') - qty_outgoing_bandengan = fields.Float(string='Outgoing BU', compute='_get_qty_outgoing_bandengan') + qty_outgoing_bandengan = fields.Float(string='Outgoing BU', compute='_get_qty_outgoing_bandengan', help='only outgoing from sales order bandengan') + qty_outgoing_mo_bandengan = fields.Float(string='Outgoing MO BU', compute='_get_qty_outgoing_mo_bandengan', help='only outgoing from manufacturing order bandengan') qty_available_bandengan = fields.Float(string='Available BU', compute='_get_qty_available_bandengan') qty_free_bandengan = fields.Float(string='Free BU', compute='_get_qty_free_bandengan') qty_upcoming = fields.Float(string='Qty Upcoming', compute='_get_qty_upcoming') @@ -1115,12 +1112,24 @@ class ProductProduct(models.Model): domain=[ ('product_id', '=', product.id), ('location_id', 'in', [57, 83]), + ('mo_id', '=', False), + ('hold_outgoing', '=', False) ], fields=['qty_need'], groupby=[] )[0].get('qty_need', 0.0) product.qty_outgoing_bandengan = qty + def _get_qty_outgoing_mo_bandengan(self): + for product in self: + records = self.env['v.move.outstanding'].search([ + ('product_id.id', '=', product.id), + ('location_id.id', 'in', [57, 83]), + ('mo_id.id', '>', 0) + ]) + qty = sum(records.mapped('qty_need') or [0.0]) + product.qty_outgoing_mo_bandengan = qty + def _get_qty_onhand_bandengan(self): for product in self: qty_onhand = self.env['stock.quant'].search([ @@ -1132,7 +1141,7 @@ class ProductProduct(models.Model): def _get_qty_available_bandengan(self): for product in self: - qty_available = product.qty_incoming_bandengan + product.qty_onhand_bandengan - product.qty_outgoing_bandengan + qty_available = product.qty_incoming_bandengan + product.qty_onhand_bandengan - product.qty_outgoing_bandengan - product.qty_outgoing_mo_bandengan product.qty_available_bandengan = qty_available or 0 def _get_qty_free_bandengan(self): @@ -1222,101 +1231,77 @@ class ProductProduct(models.Model): # log perubahan field def _log_field_changes_product_variants(self, vals, old_values): - exclude_fields = ['solr_flag', 'desc_update_solr', 'last_update_solr', 'is_edited'] - # for image fields, use custom labels - custom_labels = { - 'image_1920': 'Main Image', - 'image_carousel_lines': 'Carousel Images', - 'product_template_image_ids': 'Extra Product Media', - } - - template_changes = {} + """Revised - Log field changes for variants without posting to template""" + exclude_fields = ['solr_flag', 'desc_update_solr', 'last_update_solr', 'is_edited'] + + # Custom labels for image fields + custom_labels = { + 'image_1920': 'Main Image', + 'image_carousel_lines': 'Carousel Images', + 'product_template_image_ids': 'Extra Product Media', + } - for record in self: - changes = [] - for field_name in vals: - if field_name not in record._fields or field_name in exclude_fields: - continue + for record in self: + changes = [] + for field_name in vals: + if field_name not in record._fields or field_name in exclude_fields: + continue - field = record._fields[field_name] - field_label = custom_labels.get(field_name, field.string or field_name) - old_value = old_values.get(record.id, {}).get(field_name) - new_value = record[field_name] # nilai setelah write + field = record._fields[field_name] + field_label = custom_labels.get(field_name, field.string or field_name) + old_value = old_values.get(record.id, {}).get(field_name) + new_value = record[field_name] - def stringify(val, field, record): - if val in [None, False]: - return 'None' - if isinstance(field, fields.Selection): - selection = field.selection - if callable(selection): - selection = selection(record) - return dict(selection).get(val, str(val)) - if isinstance(field, fields.Boolean): - return 'Yes' if val else 'No' - if isinstance(field, fields.Many2one): - if isinstance(val, int): - rec = record.env[field.comodel_name].browse(val) - return rec.display_name if rec.exists() else str(val) - elif isinstance(val, models.BaseModel): - return val.display_name - return str(val) - if isinstance(field, fields.Many2many): - records = val if isinstance(val, models.BaseModel) else record[field.name] - if not records: - return 'None' - for attr in ['name', 'x_name', 'display_name']: - if hasattr(records[0], attr): - return ", ".join(records.mapped(attr)) - return ", ".join(str(r.id) for r in records) - if isinstance(field, fields.One2many): - records = val if isinstance(val, models.BaseModel) else record[field.name] - if not records: - return 'None' - return f"{field.comodel_name}({', '.join(str(r.id) for r in records)})" + def stringify(val, field, record): + if val in [None, False]: + return 'None' + if isinstance(field, fields.Selection): + selection = field.selection + if callable(selection): + selection = selection(record) + return dict(selection).get(val, str(val)) + if isinstance(field, fields.Boolean): + return 'Yes' if val else 'No' + if isinstance(field, fields.Many2one): + if isinstance(val, int): + rec = record.env[field.comodel_name].browse(val) + return rec.display_name if rec.exists() else str(val) + elif isinstance(val, models.BaseModel): + return val.display_name return str(val) + if isinstance(field, fields.Many2many): + records = val if isinstance(val, models.BaseModel) else record[field.name] + if not records: + return 'None' + for attr in ['name', 'x_name', 'display_name']: + if hasattr(records[0], attr): + return ", ".join(records.mapped(attr)) + return ", ".join(str(r.id) for r in records) + if isinstance(field, fields.One2many): + records = val if isinstance(val, models.BaseModel) else record[field.name] + if not records: + return 'None' + return f"{field.comodel_name}({', '.join(str(r.id) for r in records)})" + return str(val) - old_val_str = stringify(old_value, field, record) - new_val_str = stringify(new_value, field, record) - - if old_val_str != new_val_str: - if field_name in custom_labels: # handle image field - if old_val_str == 'None' and new_val_str != 'None': - changes.append(f"<li><b>{field_label}</b>: image added</li>") - elif old_val_str != 'None' and new_val_str == 'None': - changes.append(f"<li><b>{field_label}</b>: image removed</li>") - else: - changes.append(f"<li><b>{field_label}</b>: image updated</li>") - else: - changes.append(f"<li><b>{field_label}</b>: '{old_val_str}' → '{new_val_str}'</li>") + old_val_str = stringify(old_value, field, record) + new_val_str = stringify(new_value, field, record) - if changes: - # Post message to variant - variant_message = "<b>Updated:</b><ul>%s</ul>" % "".join(changes) - record.message_post(body=variant_message) - - # Group changes by template for posting to template - template_id = record.product_tmpl_id.id - if template_id not in template_changes: - template_changes[template_id] = {} - - # Store variant information including ID for creating clickable link - template_changes[template_id][record.id] = { - 'name': record.display_name or f"Variant {record.id}", - 'changes': changes - } + if old_val_str != new_val_str: + if field_name in custom_labels: # handle image field + if old_val_str == 'None' and new_val_str != 'None': + changes.append(f"<li><b>{field_label}</b>: image added</li>") + elif old_val_str != 'None' and new_val_str == 'None': + changes.append(f"<li><b>{field_label}</b>: image removed</li>") + else: + changes.append(f"<li><b>{field_label}</b>: image updated</li>") + else: + changes.append(f"<li><b>{field_label}</b>: '{old_val_str}' → '{new_val_str}'</li>") - # Post grouped messages to templates with clickable links using your format - for template_id, variants_data in template_changes.items(): - template = self.env['product.template'].browse(template_id) - if template.exists(): - template_message = "<b>Variant Updates:</b><br/>" - - for variant_id, variant_data in variants_data.items(): - # Create clickable link using your format - variant_link = f"<a href=\"#id={variant_id}&model=product.product&view_type=form\">{variant_data['name']}</a><br/>" - template_message += f"{variant_link}<ul>{''.join(variant_data['changes'])}</ul><br/>" - - template.message_post(body=template_message) + if changes: + # PERBAIKAN: Hanya post message ke variant, HAPUS bagian template_changes + variant_message = "<b>Updated:</b><ul>%s</ul>" % "".join(changes) + record.message_post(body=variant_message) # simpan data lama dan log perubahan field def write(self, vals): @@ -1334,6 +1319,7 @@ class ProductProduct(models.Model): else: return super().write(vals) + class OutstandingMove(models.Model): _name = 'v.move.outstanding' _auto = False @@ -1345,6 +1331,8 @@ class OutstandingMove(models.Model): qty_need = fields.Float(string='Qty Need', help='Qty yang akan outgoing / incoming') location_id = fields.Many2one('stock.location', string='Location', help='Lokasi asal') location_dest_id = fields.Many2one('stock.location', string='Location To', help='Lokasi tujuan') + mo_id = fields.Many2one('mrp.production', string='Manufacturing Order') + hold_outgoing = fields.Boolean(string='Hold Outgoing') def init(self): # where clause 'state in' follow the origin of outgoing and incoming odoo @@ -1353,8 +1341,12 @@ class OutstandingMove(models.Model): CREATE OR REPLACE VIEW %s AS select sm.id, sm.reference, sm.product_id, sm.product_uom_qty as qty_need, - sm.location_id, sm.location_dest_id + sm.location_id, sm.location_dest_id, + sm.raw_material_production_id as mo_id, + so.hold_outgoing from stock_move sm + left join procurement_group pg on pg.id = sm.group_id + left join sale_order so on so.id = pg.sale_id where 1=1 and sm.state in( 'waiting', diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 1d350929..74236850 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -299,18 +299,18 @@ class RequisitionLine(models.Model): def _get_valid_purchase_price(self, purchase_price): price = 0 - taxes = '' + taxes = 24 human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min - if purchase_price.taxes_product_id.type_tax_use == 'purchase': - price = purchase_price.product_price - taxes = purchase_price.taxes_product_id.id + #if purchase_price.taxes_product_id.type_tax_use == 'purchase': + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id or 24 if system_last_update > human_last_update: - if purchase_price.taxes_system_id.type_tax_use == 'purchase': - price = purchase_price.system_price - taxes = purchase_price.taxes_system_id.id + #if purchase_price.taxes_system_id.type_tax_use == 'purchase': + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id or 24 return price, taxes diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 049bee2d..9247d1c1 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -255,32 +255,33 @@ class SaleOrderLine(models.Model): def _get_valid_purchase_price(self, purchase_price): current_time = datetime.now() delta_time = current_time - timedelta(days=365) + default_timestamp = datetime(1970, 1, 1, 0, 0, 0) # delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') price = 0 - taxes = '' + taxes = 24 vendor_id = '' human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min - - if purchase_price.taxes_product_id.type_tax_use == 'purchase': - price = purchase_price.product_price - taxes = purchase_price.taxes_product_id.id + + # if purchase_price.taxes_product_id.type_tax_use == 'purchase': + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id or 24 + vendor_id = purchase_price.vendor_id.id + if delta_time > human_last_update: + price = 0 + taxes = 24 + vendor_id = '' + + if system_last_update > human_last_update: + #if purchase_price.taxes_system_id.type_tax_use == 'purchase': + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id or 24 vendor_id = purchase_price.vendor_id.id - if delta_time > human_last_update: + if delta_time > system_last_update: price = 0 - taxes = '' + taxes = 24 vendor_id = '' - - if system_last_update > human_last_update: - if purchase_price.taxes_system_id.type_tax_use == 'purchase': - price = purchase_price.system_price - taxes = purchase_price.taxes_system_id.id - vendor_id = purchase_price.vendor_id.id - if delta_time > system_last_update: - price = 0 - taxes = '' - vendor_id = '' return price, taxes, vendor_id diff --git a/indoteknik_custom/models/user_pengajuan_tempo_request.py b/indoteknik_custom/models/user_pengajuan_tempo_request.py index 565b0315..87227764 100644 --- a/indoteknik_custom/models/user_pengajuan_tempo_request.py +++ b/indoteknik_custom/models/user_pengajuan_tempo_request.py @@ -365,13 +365,13 @@ class UserPengajuanTempoRequest(models.Model): @api.onchange('tempo_duration') def _tempo_duration_change(self): for tempo in self: - if tempo.env.user.id not in (7, 688, 28, 377, 12182): + if tempo.env.user.id not in (7, 688, 28, 377, 12182, 375): raise UserError("Durasi tempo hanya bisa di ubah oleh Sales Manager atau Direktur") @api.onchange('tempo_limit') def _onchange_tempo_limit(self): for tempo in self: - if tempo.env.user.id not in (7, 688, 28, 377, 12182): + if tempo.env.user.id not in (7, 688, 28, 377, 12182, 375): raise UserError("Limit tempo hanya bisa diubah oleh Sales Manager atau Direktur") def button_approve(self): for tempo in self: @@ -381,7 +381,7 @@ class UserPengajuanTempoRequest(models.Model): if tempo.env.user.id in (688, 28, 7): raise UserError("Pengajuan tempo harus di approve oleh sales manager terlebih dahulu") else: - if tempo.env.user.id not in (377, 12182): + if tempo.env.user.id not in (377, 12182, 375): # if tempo.env.user.id != 12182: raise UserError("Pengajuan tempo hanya bisa di approve oleh sales manager") else: @@ -682,6 +682,9 @@ class UserPengajuanTempoRequest(models.Model): ('active', 'in', [True, False]) ]) + def _message_get_suggested_recipients(self): + return {} + def format_currency(self, number): number = int(number) return "{:,}".format(number).replace(',', '.')
\ No newline at end of file diff --git a/indoteknik_custom/views/product_product.xml b/indoteknik_custom/views/product_product.xml index b214dc87..1d04e708 100644 --- a/indoteknik_custom/views/product_product.xml +++ b/indoteknik_custom/views/product_product.xml @@ -15,6 +15,7 @@ <field name="qty_onhand_bandengan" optional="hide"/> <field name="qty_incoming_bandengan" optional="hide"/> <field name="qty_outgoing_bandengan" optional="hide"/> + <field name="qty_outgoing_mo_bandengan" optional="hide"/> <field name="qty_available_bandengan" optional="hide"/> <field name="qty_free_bandengan" optional="hide"/> <field name="qty_rpo" optional="hide"/> diff --git a/indoteknik_custom/views/user_pengajuan_tempo_request.xml b/indoteknik_custom/views/user_pengajuan_tempo_request.xml index 339ce8db..898d5b2a 100644 --- a/indoteknik_custom/views/user_pengajuan_tempo_request.xml +++ b/indoteknik_custom/views/user_pengajuan_tempo_request.xml @@ -426,7 +426,7 @@ <menuitem id="menu_user_pengajuan_tempo_request" name="User Pengajuan Tempo Request" - parent="res_partner_menu_user" + parent="account.menu_finance_receivables" sequence="3" action="action_user_pengajuan_tempo_request" /> |
