diff options
| author | trisusilo48 <tri.susilo@altama.co.id> | 2025-01-20 09:27:06 +0700 |
|---|---|---|
| committer | trisusilo48 <tri.susilo@altama.co.id> | 2025-01-20 09:27:06 +0700 |
| commit | 464292a0eb2b9353f499a541991e4d88a76c2d82 (patch) | |
| tree | f8287645e73b4c23cad3e3dc50af177d34a51b94 | |
| parent | e3e7f29ad939a774878316e46e10a5c1370fda77 (diff) | |
| parent | 1b2b27941fcdaa1b1b6ddf2a4851d358abb259eb (diff) | |
Merge branch 'odoo-production' into feature/integrasi_biteship
# Conflicts:
# indoteknik_custom/security/ir.model.access.csv
24 files changed, 763 insertions, 112 deletions
diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py index 885cf3ec..307165b3 100644 --- a/indoteknik_api/controllers/api_v1/partner.py +++ b/indoteknik_api/controllers/api_v1/partner.py @@ -141,13 +141,9 @@ class Partner(controller.Controller): 'email': [], 'mobile': [] }) - - # Mengambil id_user dari request id_user = self.get_request_params(kw, { 'id_user': ['number'] }) - - # Mengambil parameter user dari request params_user = self.get_request_params(kw, { 'company_type_id': ['number'], 'industry_id': ['number'], @@ -156,17 +152,26 @@ class Partner(controller.Controller): 'alamat_lengkap_text': [], }) - # Cek validitas parameter if not params['valid']: return self.response(code=400, description=params) - # Mencari partner dan user berdasarkan ID partner = request.env[self._name].search([('id', '=', params['value']['id'])], limit=1) user = request.env[self._name].search([('id', '=', id_user['value']['id_user'])], limit=1) - if not partner: return self.response(code=404, description='Partner not found') + if not params['value'].get('tax_name'): + params['value']['nama_wajib_pajak'] = params['value'].get('name') + params_user['value']['nama_wajib_pajak'] = params_user['value'].get('name') + + if not params['value'].get('alamat_lengkap_text'): + params['value']['alamat_lengkap_text'] = params['value'].get('street') + params_user['value']['alamat_lengkap_text'] = params_user['value'].get('street') + + if not params['value'].get('npwp'): + params['value']['npwp'] = "00.000.000.0-000.000" + params_user['value']['npwp'] = "00.000.000.0-000.000" + # Filter parameter yang memiliki nilai saja untuk partner params_filtered = {k: v for k, v in params['value'].items() if v} diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index addf2c9f..f71af89f 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -130,6 +130,7 @@ class User(controller.Controller): alamat_bisnis = kw.get('alamat_bisnis', False) nama_wajib_pajak = kw.get('nama_wajib_pajak', False) is_pkp = kw.get('is_pkp') + is_terdaftar = kw.get('is_terdaftar', False) type_acc = kw.get('type_acc', 'individu') or 'individu' if not name or not email or not password: @@ -168,7 +169,7 @@ class User(controller.Controller): if type_acc == 'business' and business_name: # Eksekusi query SQL menggunakan Levenshtein distance query = """ - SELECT name, levenshtein(name::text, %s) AS distance + SELECT id, name, levenshtein(name::text, %s) AS distance FROM res_partner WHERE levenshtein(name::text, %s) < 3 ORDER BY distance ASC @@ -177,9 +178,9 @@ class User(controller.Controller): request.env.cr.execute(query, params) result = request.env.cr.fetchone() - if result: - match_company_name = result[0] - match_company_id = result[2] + if result and is_terdaftar: + match_company_name = result[2] + match_company_id = result[0] # Create a user company request request.env['user.company.request'].create({ @@ -437,8 +438,8 @@ class User(controller.Controller): @http.route(prefix + 'user/<id>/switch', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def switch_account(self, **kw): - id = kw.get('id') - user = request.env['res.users'].search([('id', '=', id)], limit=1) + id = int(kw.get('id')) + user = request.env['res.partner'].search([('id', '=', id)], limit=1) response = { 'switch': False, @@ -461,7 +462,14 @@ class User(controller.Controller): nama_wajib_pajak = kw.get('nama_wajib_pajak', False) is_pkp = kw.get('is_pkp') type_acc = kw.get('type_acc', False) - + parent_id = kw.get('parent_id', False) + if parent_id: + try: + parent_id = int(parent_id) + except ValueError: + parent_id = False + else: + parent_id = False response = { 'switch': False, @@ -473,55 +481,23 @@ class User(controller.Controller): ('company_type', '=', 'company'), ('name', 'ilike', business_name) ] - match_company = request.env['res.partner'].search(parameter, limit=1) - match_ratio = 0 - if match_company: - match_ratio = SequenceMatcher(None, match_company.name, business_name).ratio() - if match_ratio > 0.8: - # Create a user company request - request.env['user.company.request'].create({ - 'user_id': user.partner_id.id, - 'user_company_id': match_company.id, - 'user_input': business_name - }) - else: - if not nama_wajib_pajak and is_pkp == 'false': - nama_wajib_pajak = business_name - - if not alamat_wajib_pajak and is_pkp == 'false': - alamat_wajib_pajak = alamat_bisnis - - new_company_data = { + if parent_id: + match_company = request.env['res.partner'].search([('id', '=', parent_id)], limit=1) + new_data = { + 'email': email_partner, + 'customer_type': 'pkp' if is_pkp == 'true' else 'nonpkp', 'name': business_name if business_name else business_name, 'company_type_id': company_type_id if company_type_id else False, 'industry_id': industry_id, - 'customer_type': 'pkp' if is_pkp == 'true' else 'nonpkp', 'npwp': npwp if is_pkp == 'true' else (npwp if npwp else '00.000.000.0-000.000'), 'sppkp': sppkp if is_pkp == 'true' else (sppkp if sppkp else '-'), 'nama_wajib_pajak': nama_wajib_pajak, 'alamat_lengkap_text': alamat_wajib_pajak, - 'email': email_partner, 'street': alamat_bisnis, - 'company_type': 'company', - 'user_id': 3222, - 'property_account_receivable_id': 395, - 'property_account_payable_id': 438, - 'active': False, } - new_company = request.env['res.partner'].create(new_company_data) - request.env['user.company.request'].create({ - 'user_id': user.partner_id.id, - 'user_company_id': new_company.id, - 'user_input': business_name - }) - # user.partner_id.parent_id = new_company.id - # user.partner_id.customer_type = new_company.customer_type - # user.partner_id.npwp = new_company.npwp - # user.partner_id.sppkp = new_company.sppkp - # user.partner_id.nama_wajib_pajak = new_company.nama_wajib_pajak - # user.partner_id.alamat_lengkap_text = new_company.alamat_lengkap_text + match_company.write(new_data) - if npwp_document: + if npwp_document != ' ': npwp_mimetype, _ = mimetypes.guess_type(npwp_filename) npwp_mimetype = npwp_mimetype or 'application/octet-stream' pdf_data = base64.b64decode(npwp_document) @@ -530,12 +506,12 @@ class User(controller.Controller): 'type': 'binary', 'datas': base64.b64encode(pdf_data), 'res_model': 'res.partner', - 'res_id': new_company.id, + 'res_id': match_company.id, 'mimetype': npwp_mimetype }) - new_company.message_post(body="NPWP Uploaded", attachment_ids=[npwp_attachment.id]) + match_company.message_post(body="NPWP Uploaded", attachment_ids=[npwp_attachment.id]) - if sppkp_document: + if sppkp_document != ' ': sppkp_mimetype, _ = mimetypes.guess_type(sppkp_filename) sppkp_mimetype = sppkp_mimetype or 'application/octet-stream' pdf_data = base64.b64decode(sppkp_document) @@ -544,11 +520,149 @@ class User(controller.Controller): 'type': 'binary', 'datas': base64.b64encode(pdf_data), 'res_model': 'res.partner', - 'res_id': new_company.id, + 'res_id': match_company.id, 'mimetype': sppkp_mimetype }) - new_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id]) - + match_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id]) + request.env['user.company.request'].create({ + 'user_id': user.id, + 'user_company_id': match_company.id, + 'user_input': business_name, + 'is_switch_account': True + }) + else: + match_company = request.env['res.partner'].search(parameter, limit=1) + match_ratio = 0 + if match_company: + match_ratio = SequenceMatcher(None, match_company.name, business_name).ratio() + if match_ratio > 0.8: + if user.parent_id : + new_data = { + 'email': email_partner, + 'customer_type': 'pkp' if is_pkp == 'true' else 'nonpkp', + 'name': business_name if business_name else business_name, + 'company_type_id': company_type_id if company_type_id else False, + 'industry_id': industry_id, + 'npwp': npwp if is_pkp == 'true' else (npwp if npwp else '00.000.000.0-000.000'), + 'sppkp': sppkp if is_pkp == 'true' else (sppkp if sppkp else '-'), + 'nama_wajib_pajak': nama_wajib_pajak, + 'alamat_lengkap_text': alamat_wajib_pajak, + 'street': alamat_bisnis, + } + match_company.write(new_data) + + if npwp_document != ' ': + npwp_mimetype, _ = mimetypes.guess_type(npwp_filename) + npwp_mimetype = npwp_mimetype or 'application/octet-stream' + pdf_data = base64.b64decode(npwp_document) + npwp_attachment = request.env['ir.attachment'].create({ + 'name': 'NPWP Document', + 'type': 'binary', + 'datas': base64.b64encode(pdf_data), + 'res_model': 'res.partner', + 'res_id': match_company.id, + 'mimetype': npwp_mimetype + }) + match_company.message_post(body="NPWP Uploaded", attachment_ids=[npwp_attachment.id]) + + if sppkp_document != ' ': + sppkp_mimetype, _ = mimetypes.guess_type(sppkp_filename) + sppkp_mimetype = sppkp_mimetype or 'application/octet-stream' + pdf_data = base64.b64decode(sppkp_document) + sppkp_attachment = request.env['ir.attachment'].create({ + 'name': 'SPPKP Document', + 'type': 'binary', + 'datas': base64.b64encode(pdf_data), + 'res_model': 'res.partner', + 'res_id': match_company.id, + 'mimetype': sppkp_mimetype + }) + match_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id]) + else: + # Create a user company request + request.env['user.company.request'].create({ + 'user_id': user.id, + 'user_company_id': match_company.id, + 'user_input': business_name + }) + else: + if not nama_wajib_pajak and is_pkp == 'false': + nama_wajib_pajak = business_name + + if not alamat_wajib_pajak and is_pkp == 'false': + alamat_wajib_pajak = alamat_bisnis + + new_company_data = { + 'name': business_name if business_name else business_name, + 'company_type_id': company_type_id if company_type_id else False, + 'industry_id': industry_id, + 'customer_type': 'pkp' if is_pkp == 'true' else 'nonpkp', + 'npwp': npwp if is_pkp == 'true' else (npwp if npwp else '00.000.000.0-000.000'), + 'sppkp': sppkp if is_pkp == 'true' else (sppkp if sppkp else '-'), + 'nama_wajib_pajak': nama_wajib_pajak, + 'alamat_lengkap_text': alamat_wajib_pajak, + 'email': email_partner, + 'street': alamat_bisnis, + 'company_type': 'company', + 'user_id': 3222, + 'property_account_receivable_id': 395, + 'property_account_payable_id': 438, + 'active': False, + } + new_company = request.env['res.partner'].create(new_company_data) + request.env['user.company.request'].create({ + 'user_id': user.id, + 'user_company_id': new_company.id, + 'user_input': business_name + }) + # user.partner_id.parent_id = new_company.id + # user.partner_id.customer_type = new_company.customer_type + # user.partner_id.npwp = new_company.npwp + # user.partner_id.sppkp = new_company.sppkp + # user.partner_id.nama_wajib_pajak = new_company.nama_wajib_pajak + # user.partner_id.alamat_lengkap_text = new_company.alamat_lengkap_text + + if npwp_document: + npwp_mimetype, _ = mimetypes.guess_type(npwp_filename) + npwp_mimetype = npwp_mimetype or 'application/octet-stream' + pdf_data = base64.b64decode(npwp_document) + npwp_attachment = request.env['ir.attachment'].create({ + 'name': 'NPWP Document', + 'type': 'binary', + 'datas': base64.b64encode(pdf_data), + 'res_model': 'res.partner', + 'res_id': new_company.id, + 'mimetype': npwp_mimetype + }) + if user.parent_id: + match_company.message_post(body="NPWP Uploaded", attachment_ids=[npwp_attachment.id]) + else: + new_company.message_post(body="NPWP Uploaded", attachment_ids=[npwp_attachment.id]) + + if sppkp_document: + sppkp_mimetype, _ = mimetypes.guess_type(sppkp_filename) + sppkp_mimetype = sppkp_mimetype or 'application/octet-stream' + pdf_data = base64.b64decode(sppkp_document) + sppkp_attachment = request.env['ir.attachment'].create({ + 'name': 'SPPKP Document', + 'type': 'binary', + 'datas': base64.b64encode(pdf_data), + 'res_model': 'res.partner', + 'res_id': new_company.id, + 'mimetype': sppkp_mimetype + }) + if user.parent_id: + match_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id]) + else: + new_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id]) + request_company = self.get_user_by_email(user.email) + request_company.parent_name = business_name + # if user.parent_id: + # request_company.send_company_switch_approve_mail() + # else: + # request_company.send_company_request_mail_switch() + + request_company.send_company_request_mail_switch() response['switch'] = 'Pending' return self.response(response) @@ -556,7 +670,7 @@ class User(controller.Controller): # @controller.Controller.must_authorized() def switch_account_progres(self, **kw): id = int(kw.get('id')) - user = request.env['res.users'].search([('id', '=', id)], limit=1) + # user = request.env['res.partner'].search([('id', '=', id)], limit=1) response = { 'status': '' } @@ -572,5 +686,122 @@ class User(controller.Controller): else: response['status'] = new_company_request.is_approve else: - response['status'] = 'unknown' + response['status'] = False + return self.response(response) + + def get_user_by_email(self, email): + return request.env['res.users'].search([ + ('login', '=', email), + ('active', 'in', [True, False]) + ]) + + @http.route(prefix + 'user/download/npwp/<id>', auth='public', methods=['GET']) + def download_npwp(self, **kw): + id = int(kw.get('id')) + """Download NPWP file for the given company""" + # Search for the NPWP attachment associated with the company + attachment = request.env['ir.attachment'].search([ + ('res_model', '=', 'res.partner'), + ('res_id', '=', id), + ('name', '=', 'NPWP Document') + ], limit=1) + + if not attachment: + return request.not_found() + + # Get the file data and content type + npwp_mimetype = attachment.mimetype # This should be directly from the attachment + npwp_mimetype = npwp_mimetype or 'application/octet-stream' + + # Create a filename with the correct extension + filename = f"{attachment.name}" + + # Manually set the Content-Disposition header to inline + content_disposition = f'inline; filename="{filename}"' + + # Send the file as a response + return request.make_response( + base64.b64decode(attachment.datas), + headers=[ + ('Content-Type', npwp_mimetype), + ('Content-Disposition', content_disposition) + ] + ) + + @http.route(prefix + 'user/chek/npwp/<id>', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def chek_npwp(self, **kw): + id = int(kw.get('id')) + """Download NPWP file for the given company""" + # Search for the NPWP attachment associated with the company + attachment = request.env['ir.attachment'].search([ + ('res_model', '=', 'res.partner'), + ('res_id', '=', id), + ('name', '=', 'NPWP Document') + ], limit=1) + response = { + 'status': '' + } + if attachment: + response['status'] = True + else: + response['status'] = False + + # If no attachment is found, return status False + return self.response(response) + + @http.route(prefix + 'user/download/sppkp/<id>', auth='public', methods=['GET']) + def download_sppkp(self, **kw): + id = int(kw.get('id')) + """Download SPPKP file for the given company""" + # Search for the SPPKP attachment associated with the company + attachment = request.env['ir.attachment'].search([ + ('res_model', '=', 'res.partner'), + ('res_id', '=', id), + ('name', '=', 'SPPKP Document') + ], limit=1) + + if not attachment: + return request.not_found() + + # Get the file data and content type + sppkp_mimetype = attachment.mimetype # Use the MIME type directly from the attachment + sppkp_mimetype = sppkp_mimetype or 'application/octet-stream' + + # Create a filename with the correct extension + filename = attachment.name # No need to append extension since attachment should already have it + + # Manually set the Content-Disposition header to inline + content_disposition = f'inline; filename="{filename}"' + + # Send the file as a response + return request.make_response( + base64.b64decode(attachment.datas), + headers=[ + ('Content-Type', sppkp_mimetype), + ('Content-Disposition', content_disposition) # Ensure inline display + ] + ) + + @http.route(prefix + 'user/chek/sppkp/<id>', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def chek_sppkp(self, **kw): + id = int(kw.get('id')) + """Download SPPKP file for the given company""" + # Search for the SPPKP attachment associated with the company + attachment = request.env['ir.attachment'].search([ + ('res_model', '=', 'res.partner'), + ('res_id', '=', id), + ('name', '=', 'SPPKP Document') + ], limit=1) + + response = { + 'status': '' + } + if attachment: + response['status'] = True + else: + response['status'] = False + + # If no attachment is found, return status False return self.response(response)
\ No newline at end of file diff --git a/indoteknik_api/models/res_users.py b/indoteknik_api/models/res_users.py index 2021b0bb..015b9e0e 100644 --- a/indoteknik_api/models/res_users.py +++ b/indoteknik_api/models/res_users.py @@ -63,13 +63,15 @@ class ResUsers(models.Model): 'district': None, 'sub_district': None, 'zip': user.zip or '', - 'company_type_id': user.company_type_id.id or None, - 'industry_id': user.industry_id.id or None, + 'company_type_id': user.company_type_id.id or '', + 'industry_id': user.industry_id.id or '', 'tax_name': user.nama_wajib_pajak or '', 'npwp': user.npwp or '', + 'sppkp': user.sppkp or '', 'rajaongkir_city_id': user.kecamatan_id.rajaongkir_id or 0, - 'alamat_wajib_pajak': user.alamat_lengkap_text or None, - 'alamat_bisnis': user.street or None, + 'alamat_wajib_pajak': user.alamat_lengkap_text or '', + 'alamat_bisnis': user.street or '', + 'company_type': user.customer_type or 'nonpkp', 'longtitude': user.longtitude or None, 'latitude': user.latitude or None, 'address_map': user.address_map or None, diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 42678847..d62f19ae 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -62,6 +62,11 @@ class AccountMove(models.Model): so_delivery_amt = fields.Char(string="SO Delivery Amount", compute='compute_so_shipping_paid_by') flag_delivery_amt = fields.Boolean(string="Flag Delivery Amount", compute='compute_flag_delivery_amt') nomor_kwitansi = fields.Char(string="Nomor Kwitansi") + other_subtotal = fields.Float(string="Other Subtotal", compute='compute_other_subtotal') + + def compute_other_subtotal(self): + for rec in self: + rec.other_subtotal = rec.amount_untaxed * (11 / 12) @api.model def generate_attachment(self, record): @@ -253,6 +258,11 @@ class AccountMove(models.Model): line.date_maturity = entry.date return res + def button_draft(self): + res = super(AccountMove, self).button_draft() + if not self.env.user.is_accounting: + raise UserError("Hanya Finence yang bisa ubah data") + return res def _compute_invoice_day_to_due(self): for invoice in self: @@ -334,7 +344,7 @@ class AccountMove(models.Model): invalid_invoices = self - invoices if invalid_invoices: invalid_ids = ", ".join(str(inv.id) for inv in invalid_invoices) - raise UserError(_( + raise UserError(( "Faktur dengan ID berikut tidak valid untuk diekspor: {}.\n" "Pastikan faktur dalam status 'posted', belum diekspor, dan merupakan 'out_invoice'.".format(invalid_ids) )) @@ -343,7 +353,7 @@ class AccountMove(models.Model): def export_faktur_to_xml(self): - valid_invoices = self.validate_faktur_for_export() + valid_invoices = self # Panggil model coretax.faktur untuk menghasilkan XML coretax_faktur = self.env['coretax.faktur'].create({}) diff --git a/indoteknik_custom/models/account_move_due_extension.py b/indoteknik_custom/models/account_move_due_extension.py index 6fc58cdd..c48c2372 100644 --- a/indoteknik_custom/models/account_move_due_extension.py +++ b/indoteknik_custom/models/account_move_due_extension.py @@ -90,6 +90,7 @@ class DueExtension(models.Model): return self.order_id._create_approval_notification('Pimpinan') if self.order_id._requires_approval_margin_manager(): + self.order_id.check_credit_limit() self.order_id.approval_status = 'pengajuan1' return self.order_id._create_approval_notification('Sales Manager') diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 4e96e6d4..09d283eb 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -255,6 +255,7 @@ class AutomaticPurchase(models.Model): 'suggest': product._get_po_suggest(line.qty_purchase), 'product_uom_qty': line.qty_purchase, 'price_unit': line.last_price, + 'ending_price': line.last_price, 'taxes_id': [line.taxes_id.id] if line.taxes_id else None, 'so_line_id': sales_match[0].sale_line_id.id if sales_match else None, 'so_id': sales_match[0].sale_id.id if sales_match else None diff --git a/indoteknik_custom/models/coretax_fatur.py b/indoteknik_custom/models/coretax_fatur.py index ff8606b1..ae6dd2ae 100644 --- a/indoteknik_custom/models/coretax_fatur.py +++ b/indoteknik_custom/models/coretax_fatur.py @@ -49,7 +49,9 @@ class CoretaxFaktur(models.Model): for invoice in invoices: tax_invoice = ET.SubElement(list_of_tax_invoice, 'TaxInvoice') buyerTIN = self.validate_and_format_number(invoice.partner_id.npwp) - buyerIDTKU = buyerTIN.ljust(len(buyerTIN) + 6, '0') if sum(int(char) for char in buyerTIN) > 0 else '000000' + nitku = invoice.partner_id.nitku + formula = nitku if nitku else buyerTIN.ljust(len(buyerTIN) + 6, '0') + buyerIDTKU = formula if sum(int(char) for char in buyerTIN) > 0 else '000000' # Tambahkan elemen faktur ET.SubElement(tax_invoice, 'TaxInvoiceDate').text = invoice.invoice_date.strftime('%Y-%m-%d') if invoice.invoice_date else '' @@ -63,7 +65,7 @@ class CoretaxFaktur(models.Model): ET.SubElement(tax_invoice, 'BuyerTin').text = buyerTIN ET.SubElement(tax_invoice, 'BuyerDocument').text = 'TIN' if sum(int(char) for char in buyerTIN) > 0 else 'Other ID' ET.SubElement(tax_invoice, 'BuyerCountry').text = 'IDN' - ET.SubElement(tax_invoice, 'BuyerDocumentNumber').text = str(invoice.partner_id.id) + ET.SubElement(tax_invoice, 'BuyerDocumentNumber').text = '-' if sum(int(char) for char in buyerTIN) > 0 else str(invoice.partner_id.id) ET.SubElement(tax_invoice, 'BuyerName').text = invoice.partner_id.nama_wajib_pajak or '' ET.SubElement(tax_invoice, 'BuyerAdress').text = invoice.partner_id.alamat_lengkap_text or '' ET.SubElement(tax_invoice, 'BuyerEmail').text = invoice.partner_id.email or '' diff --git a/indoteknik_custom/models/manufacturing.py b/indoteknik_custom/models/manufacturing.py index 37c4e909..24a8b8c3 100644 --- a/indoteknik_custom/models/manufacturing.py +++ b/indoteknik_custom/models/manufacturing.py @@ -30,7 +30,7 @@ class Manufacturing(models.Model): # if line.quantity_done > 0 and line.quantity_done != self.product_uom_qty: # raise UserError('Qty Consume per Line tidak sama dengan Qty to Produce') if line.forecast_availability != line.product_uom_qty: - raise UserError('Qty Reserved belum sesuai dengan yang seharusnya') + raise UserError('Qty Reserved belum sesuai dengan yang seharusnya, product: %s' % line.product_id.display_name) result = super(Manufacturing, self).button_mark_done() return result diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 799c4db0..d487ada3 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -30,6 +30,11 @@ class PurchaseOrder(models.Model): ('pengajuan2', 'Approval Pimpinan'), #akbar - 7 temporary not used ('approved', 'Approved'), ], string='Approval Status', readonly=True, copy=False, index=True, tracking=3) + approval_status_unlock = fields.Selection([ + ('pengajuanFinance', 'Pengajuan Finance'), + ('approvedFinance', 'Approved Finance'), + ('approved', 'Approved'), + ], string='Approval Status Unlock', readonly=True, copy=False, index=True, tracking=3) delivery_amount = fields.Float('Delivery Amount', compute='compute_delivery_amount') delivery_amt = fields.Float('Delivery Amt') total_margin = fields.Float( @@ -75,29 +80,40 @@ class PurchaseOrder(models.Model): exclude_incoming = fields.Boolean(string='Exclude Incoming', default=False, help='Centang jika tidak mau masuk perhitungan Incoming Qty') not_update_purchasepricelist = fields.Boolean(string='Not Update Purchase Pricelist?') - # total_cost_service = fields.Float(string='Total Cost Service') + reason_unlock = fields.Char(string='Alasan unlock', tracking=3) + # total_cost_service = fields.Float(string='Total Cost Service' ) # total_delivery_amt = fields.Float(string='Total Delivery Amt') + total_cost_service = fields.Float(string='Total Cost Service') + total_delivery_amt = fields.Float(string='Total Delivery Amt') + store_name = fields.Char(string='Nama Toko') - # @api.onchange('total_cost_service') - # def _onchange_total_cost_service(self): - # for order in self: - # lines = order.order_line - # if lines: - # # Hitung nilai rata-rata cost_service - # per_line_cost_service = order.total_cost_service / len(lines) - # for line in lines: - # line.cost_service = per_line_cost_service - - # @api.onchange('total_delivery_amt') - # def _onchange_total_delivery_amt(self): - # for order in self: - # lines = order.order_line - # if lines: - # # Hitung nilai rata-rata delivery_amt - # per_line_delivery_amt = order.total_delivery_amt / len(lines) - # for line in lines: - # line.delivery_amt = per_line_delivery_amt + @api.onchange('total_cost_service') + def _onchange_total_cost_service(self): + for order in self: + lines = order.order_line + if order.total_cost_service > 0: + if lines: + # Hitung nilai rata-rata cost_service + per_line_cost_service = order.total_cost_service / len(lines) + for line in lines: + line.cost_service = per_line_cost_service + else: + for line in lines: + line.cost_service = 0 + @api.onchange('total_delivery_amt') + def _onchange_total_delivery_amt(self): + for order in self: + lines = order.order_line + if order.total_delivery_amt > 0: + if lines: + # Hitung nilai rata-rata delivery_amt + per_line_delivery_amt = order.total_delivery_amt / len(lines) + for line in lines: + line.delivery_amt = per_line_delivery_amt + else: + for line in lines: + line.delivery_amt = 0 def _compute_total_margin_match(self): for purchase in self: match = self.env['purchase.order.sales.match'] @@ -238,6 +254,7 @@ class PurchaseOrder(models.Model): move_line.name = '[IT.121456] Down Payment' move_line.partner_id = self.partner_id.id + # Tambahkan lognote lognote_message = ( f"Vendor bill created from: {self.name} ({self.partner_ref})" ) @@ -252,6 +269,7 @@ class PurchaseOrder(models.Model): 'domain': [('id', '=', bills.id)] } + def get_date_done(self): picking = self.env['stock.picking'].search([ ('purchase_id', '=', self.id), @@ -779,8 +797,12 @@ class PurchaseOrder(models.Model): def po_approve(self): greater_than_plafon, message = self._get_msg_plafon_qty() different_vendor_message = self.check_different_vendor_so() # Panggil fungsi check_different_vendor_so - - if self.env.user.is_leader or self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + if self.approval_status_unlock == 'pengajuanFinance': + if self.env.user.is_accounting: + self.approval_status_unlock = 'approvedFinance' + else: + raise UserError("Bisa langsung Confirm, menunggu persetujuan Finance jika ingin unlock PO") + elif self.env.user.is_leader or self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError("Bisa langsung Confirm") elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so and not greater_than_plafon and not different_vendor_message: raise UserError("Bisa langsung Confirm") @@ -809,7 +831,17 @@ class PurchaseOrder(models.Model): subtype_id=self.env.ref("mail.mt_note").id ) - + def po_approve_unlock(self): + if self.approval_status_unlock == 'pengajuanFinance': + if self.env.user.is_accounting: + self.approval_status_unlock = 'approvedFinance' + else: + raise UserError("Menunggu persetujuan Finance jika ingin unlock PO") + elif self.approval_status_unlock == 'approvedFinance': + raise UserError("PO bisa langsung di unlock") + else: + raise UserError("Menunggu persetujuan Finance jika ingin unlock PO") + def check_different_vendor_so(self): vendor_po = self.partner_id.id message = '' @@ -883,6 +915,13 @@ class PurchaseOrder(models.Model): sales_price -= sale_order_line.fee_third_party_line sum_sales_price += sales_price purchase_price = line.price_subtotal + if line.ending_price > 0: + if line.taxes_id.id == 22: + ending_price = line.ending_price / 1.11 + purchase_price = ending_price + else: + purchase_price = line.ending_price + # purchase_price = line.price_subtotal if line.order_id.delivery_amount > 0: purchase_price += line.delivery_amt_line if line.order_id.delivery_amt > 0: @@ -926,7 +965,14 @@ class PurchaseOrder(models.Model): sales_price -= (sale_order_line.fee_third_party_line / sale_order_line.product_uom_qty) * line.qty_po sum_sales_price += sales_price - purchase_price = po_line.price_subtotal / po_line.product_qty * line.qty_po + + purchase_price = po_line.price_subtotal + if po_line.ending_price > 0: + if po_line.taxes_id.id == 22: + ending_price = po_line.ending_price / 1.11 + purchase_price = ending_price + else: + purchase_price = po_line.ending_price if line.purchase_order_id.delivery_amount > 0: purchase_price += (po_line.delivery_amt_line / po_line.product_qty) * line.qty_po if line.purchase_order_id.delivery_amt > 0: @@ -945,6 +991,19 @@ class PurchaseOrder(models.Model): self.total_percent_margin = 0 self.total_so_margin = 0 self.total_so_percent_margin = 0 + + + if sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0: + self.total_so_margin = sum_so_margin + self.total_so_percent_margin = round((sum_so_margin / sum_sales_price), 2) * 100 + self.total_margin = sum_margin + self.total_percent_margin = round((sum_margin / sum_sales_price), 2) * 100 + + else: + self.total_margin = 0 + self.total_percent_margin = 0 + self.total_so_margin = 0 + self.total_so_percent_margin = 0 def compute_amt_total_without_service(self): for order in self: @@ -953,3 +1012,51 @@ class PurchaseOrder(models.Model): if line.product_id.type == 'product': sum_price_total += line.price_total order.amount_total_without_service = sum_price_total + + def button_unlock(self): + for order in self: + # Check if any order line has received_qty not equal to 0 + if self.env.user.is_accounting: + order.state = 'purchase' + order.approval_status_unlock = 'approved' + break + for line in order.order_line: + if line.qty_received > 0: + if order.approval_status_unlock == 'approvedFinance': + order.approval_status_unlock = 'approved' + order.state = 'purchase' + break + if order.approval_status_unlock == 'pengajuanFinance': + raise UserError(_( + "Menunggu Approve Dari Finance." + )) + else: + return { + 'type': 'ir.actions.act_window', + 'name': _('Untuk mengubah PO butuh approve dari Finance. Berikan alasan anda unlock PO!'), + 'res_model': 'purchase.order.unlock.wizard', + 'view_mode': 'form', + 'target': 'new', + 'context': { + 'default_purchase_order_id': order.id + } + } + + return super(PurchaseOrder, self).button_unlock() + + +class PurchaseOrderUnlockWizard(models.TransientModel): + _name = 'purchase.order.unlock.wizard' + _description = 'Wizard untuk memberikan alasan unlock PO' + + purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order', required=True) + alasan = fields.Text(string='Alasan', required=True) + + def confirm_reject(self): + order = self.purchase_order_id + if order: + order.write({'reason_unlock': self.alasan}) + order.approval_status_unlock = 'pengajuanFinance' + return {'type': 'ir.actions.act_window_close'} + + diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 9e7d7e81..587a09a1 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -43,7 +43,79 @@ class PurchaseOrderLine(models.Model): qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') delete_line = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') is_edit_product_qty = fields.Boolean(string='Is Edit Product Qty', compute='_compute_is_edit_product_qty') - + delivery_amt = fields.Float(string='Delivery Amt', compute='_compute_doc_delivery_amt') + delivery_amt_per_item = fields.Float(string='Delivery Amt Per Item' , compute='_compute_doc_delivery_amt') + contribution_delivery_amt = fields.Float(string='Contribution Delivery Amt', compute='_compute_doc_delivery_amt') + cost_service = fields.Float(string='Biaya Jasa', compute='_compute_doc_delivery_amt') + cost_service_per_item = fields.Float(string='Biaya Jasa Per Item', compute='_compute_doc_delivery_amt') + contribution_cost_service = fields.Float(string='Contribution Cost Service', compute='_compute_doc_delivery_amt') + ending_price = fields.Float(string='Ending Price', compute='_compute_doc_delivery_amt') + + def _compute_doc_delivery_amt(self): + for line in self: + # Inisialisasi nilai default untuk field computed + line.delivery_amt = 0.0 + line.delivery_amt_per_item = 0.0 + line.contribution_delivery_amt = 0.0 + line.cost_service = 0.0 + line.cost_service_per_item = 0.0 + line.contribution_cost_service = 0.0 + line.ending_price = line.price_unit * line.product_qty + + # Ambil nilai dari order_id + total_delivery_amt = line.order_id.total_delivery_amt + total_cost_service = line.order_id.total_cost_service + + include_price = line.price_unit * line.product_qty + if line.order_id.amount_total > 0: + if total_delivery_amt > 0: + contributions = include_price / line.order_id.amount_total + if line.taxes_id.id == 22: + contributions = line.price_subtotal / line.order_id.amount_untaxed + contribution = contributions * total_delivery_amt + line.delivery_amt = contribution + line.delivery_amt_per_item = contribution / line.product_qty + line.contribution_delivery_amt = contributions + + if total_cost_service > 0: + contributions = include_price / line.order_id.amount_total + if line.taxes_id.id == 22: + contributions = line.price_subtotal / line.order_id.amount_untaxed + contribution = contributions * total_cost_service + line.cost_service = contribution + line.cost_service_per_item = contribution / line.product_qty + line.contribution_cost_service = contributions + + if total_delivery_amt > 0 and total_cost_service > 0: + line.ending_price = (line.price_unit + line.delivery_amt_per_item + line.cost_service_per_item) * line.product_qty + elif total_delivery_amt > 0 and total_cost_service == 0: + line.ending_price = (line.price_unit + line.delivery_amt_per_item) * line.product_qty + elif total_delivery_amt == 0 and total_cost_service > 0: + line.ending_price = (line.price_unit + line.cost_service_per_item) * line.product_qty + + # @api.constrains('delivery_amt') + # def delivery_amt_margin(self): + # for line in self: + # if line.delivery_amt: + # line.delivery_amt_per_item = line.delivery_amt / line.product_qty + # line.ending_price = line.price_unit + line.delivery_amt_per_item + line.cost_service + # elif line.delivery_amt == 0: + # line. delivery_amt_per_item = 0 + # if line.cost_service: + # line.ending_price = line.price_unit + line.cost_service + # else: + # line.ending_price = line.price_unit + + # @api.constrains('cost_service') + # def cost_service_margin(self): + # for line in self: + # if line.cost_service: + # line.ending_price = line.price_unit + line.cost_service + line.delivery_amt_per_item + # elif line.cost_service == 0: + # if line.delivery_amt_per_item: + # line.ending_price = line.price_unit + line.delivery_amt_per_item + # else: + # line.ending_price = line.price_unit def _get_clean_website_description_product(self): for line in self: description = line.product_id.website_description diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 57fab403..f081e274 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -102,6 +102,7 @@ class ResPartner(models.Model): ]) sppkp = fields.Char(string="SPPKP", tracking=True) npwp = fields.Char(string="NPWP", tracking=True) + nitku = fields.Char(string="NITKU", tracking=True) counter = fields.Integer(string="Counter", default=0) leadtime = fields.Integer(string="Leadtime", default=0) digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak") @@ -449,3 +450,10 @@ class ResPartner(models.Model): return partner.property_payment_term_id.name if partner.property_payment_term_id.id else 'Cash Before Delivery (C.B.D)' + @api.constrains('nitku') + def _onchange_nitku(self): + if self.nitku: + if not self.nitku.isdigit(): + raise UserError("NITKU harus berupa angka.") + if len(self.nitku) != 22: + raise UserError("NITKU harus memiliki tepat 22 angka.")
\ No newline at end of file diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index fb9e8bfb..31b84ae3 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -36,11 +36,21 @@ class ResUsers(models.Model): for user in self: template.send_mail(user.id, force_send=True) + def send_company_request_mail_switch(self): + template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request_switch') + for user in self: + template.send_mail(user.id, force_send=True) + def send_company_request_approve_mail(self): template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request_approve') for user in self: template.send_mail(user.id, force_send=True) + def send_company_switch_approve_mail(self): + template = self.env.ref('indoteknik_custom.mail_template_res_user_company_switch_approve') + for user in self: + template.send_mail(user.id, force_send=True) + def send_company_request_reject_mail(self): template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request_reject') for user in self: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 7b2d9bf8..48195b77 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -816,6 +816,7 @@ class SaleOrder(models.Model): order.approval_status = 'pengajuan2' return self._create_approval_notification('Pimpinan') elif order._requires_approval_margin_manager(): + self.check_credit_limit() order.approval_status = 'pengajuan1' return self._create_approval_notification('Sales Manager') diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 29a046fa..aed95aab 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -38,11 +38,11 @@ class SaleOrderLine(models.Model): md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) margin_md = fields.Float(string='Margin MD') qty_free_bu = fields.Float(string='Free BU', compute='_get_qty_free_bandengan') - desc_updatable = fields.Boolean(string='desc boolean', default=False, compute='_get_desc_updatable') + desc_updatable = fields.Boolean(string='desc boolean', default=True, compute='_get_desc_updatable') def _get_desc_updatable(self): for line in self: - if line.product_id.id != 417724: + if line.product_id.id != 417724 and line.product_id.id: line.desc_updatable = False else: line.desc_updatable = True @@ -280,7 +280,7 @@ class SaleOrderLine(models.Model): (line.product_id.short_spesification if line.product_id.short_spesification else '') line.name = line_name line.weight = line.product_id.weight - if line.product_id.id != 417724: + if line.product_id.id != 417724 and line.product_id.id: line.desc_updatable = False else: line.desc_updatable = True diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py index 3de3d751..af8a86ba 100644 --- a/indoteknik_custom/models/user_company_request.py +++ b/indoteknik_custom/models/user_company_request.py @@ -14,7 +14,7 @@ class UserCompanyRequest(models.Model): ('rejected', 'Reject'), ], string='Approval') similar_company_ids = fields.Many2many('res.partner', compute="_compute_similar_companies", string="Similar Companies") - + is_switch_account = fields.Boolean( string='Switch Account', default=False) @api.depends('user_input') def _compute_similar_companies(self): for record in self: @@ -102,7 +102,7 @@ class UserCompanyRequest(models.Model): self.user_id.property_payment_term_id = user_company_id.property_payment_term_id if user_company_id else self.user_company_id.property_payment_term_id self.user_id.property_supplier_payment_term_id = user_company_id.property_supplier_payment_term_id if user_company_id else self.user_company_id.property_supplier_payment_term_id self.user_company_id.active = True - user.send_company_request_approve_mail() + user.send_company_switch_approve_mail() if vals.get('is_switch_account') == True else user.send_company_request_approve_mail() else: new_company = self.env['res.partner'].create({ 'name': self.user_input diff --git a/indoteknik_custom/models/user_pengajuan_tempo_request.py b/indoteknik_custom/models/user_pengajuan_tempo_request.py index f5261cd4..b43f56ac 100644 --- a/indoteknik_custom/models/user_pengajuan_tempo_request.py +++ b/indoteknik_custom/models/user_pengajuan_tempo_request.py @@ -332,7 +332,7 @@ class UserPengajuanTempoRequest(models.Model): self.pengajuan_tempo_id.dokumen_tempat_bekerja = self.dokumen_tempat_bekerja @api.onchange('tempo_duration') - def _tempo_duration_change(self, vals): + def _tempo_duration_change(self): for tempo in self: if tempo.env.user.id not in (7, 377, 12182): raise UserError("Durasi tempo hanya bisa di ubah oleh Sales Manager atau Direktur") diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 67756cc7..b6212f1b 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -152,6 +152,7 @@ access_va_multi_reject,access.va.multi.reject,model_va_multi_reject,,1,1,1,1 access_vendor_sla,access.vendor_sla,model_vendor_sla,,1,1,1,1 access_stock_immediate_transfer,access.stock.immediate.transfer,model_stock_immediate_transfer,,1,1,1,1 access_coretax_faktur,access.coretax.faktur,model_coretax_faktur,,1,1,1,1 +access_purchase_order_unlock_wizard,access.purchase.order.unlock.wizard,model_purchase_order_unlock_wizard,,1,1,1,1 access_User_pengajuan_tempo_line,access.user.pengajuan.tempo.line,model_user_pengajuan_tempo_line,,1,1,1,1 access_user_pengajuan_tempo,access.user.pengajuan.tempo,model_user_pengajuan_tempo,,1,1,1,1 access_reject_reason_wizard,reject.reason.wizard,model_reject_reason_wizard,,1,1,1,0 diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 4cc35b6d..36b292e8 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -59,6 +59,9 @@ <field name="so_delivery_amt"/> <field name="flag_delivery_amt"/> </field> + <field name="amount_untaxed" position="after"> + <field name="other_subtotal" invisible="1"/> + </field> <notebook position="inside"> <page string="Due Extension" attrs="{'invisible': [('move_type', '!=', 'out_invoice')]}"> <field name="due_line"> diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index d22c3b5c..022937f4 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -20,6 +20,11 @@ type="object" attrs="{'invisible': [('approval_status', '=', 'approved')]}" /> + <button name="po_approve_unlock" + string="Ask Approval Unlock PO" + type="object" + attrs="{'invisible': [('approval_status_unlock', '=', 'approved')]}" + /> <button name="indoteknik_custom.action_view_uangmuka_pembelian" string="UangMuka" type="action" attrs="{'invisible': [('approval_status', '!=', 'approved')]}"/> </button> @@ -43,6 +48,9 @@ <field name="revisi_po"/> <field name="not_update_purchasepricelist"/> </field> + <field name="approval_status" position="after"> + <field name="approval_status_unlock" invisible="True"/> + </field> <field name="incoterm_id" position="after"> <field name="amount_total_without_service"/> <field name="delivery_amt"/> @@ -52,6 +60,8 @@ <field name="summary_qty_po"/> <field name="count_line_product"/> <field name="payment_term_id"/> + <field name="total_cost_service" attrs="{'required': [('partner_id', 'in', [9688, 29712])]}"/> + <field name="total_delivery_amt" attrs="{'required': [('partner_id', 'in', [9688, 29712])]}"/> </field> <field name="amount_total" position="after"> <field name="total_margin"/> @@ -59,6 +69,9 @@ <field name="total_percent_margin"/> <field name="total_so_percent_margin"/> </field> + <field name="partner_ref" position="before"> + <field name="store_name" attrs="{'invisible': [('partner_id', 'not in', [9688, 29712])]}"/> + </field> <field name="product_id" position="before"> <field name="line_no" attrs="{'readonly': 1}" optional="hide"/> </field> @@ -74,6 +87,13 @@ <field name="qty_available" readonly="1" optional="hide"/> <field name="qty_reserved" readonly="1" optional="hide"/> <field name="suggest" readonly="1" widget="badge" decoration-danger="suggest == 'harus beli'" decoration-success="suggest == 'masih cukup'"/> + <field name="delivery_amt" optional="hide"/> + <field name="delivery_amt_per_item" optional="hide"/> + <field name="contribution_delivery_amt" optional="hide"/> + <field name="cost_service" optional="hide"/> + <field name="cost_service_per_item" optional="hide"/> + <field name="contribution_cost_service" optional="hide"/> + <field name="ending_price" optional="hide"/> <!-- <field name="suggest" readonly="1"/> --> </field> <field name="product_id" position="before"> @@ -137,7 +157,30 @@ </field> </record> </data> - + <data> + <record id="view_purchase_order_unlock_wizard_form" model="ir.ui.view"> + <field name="name">purchase.order.unlock.wizard.form</field> + <field name="model">purchase.order.unlock.wizard</field> + <field name="arch" type="xml"> + <form string="Reject Reason"> + <group> + <field name="alasan" widget="text"/> + </group> + <footer> + <button string="Confirm" type="object" name="confirm_reject" class="btn-primary"/> + <button string="Cancel" class="btn-secondary" special="cancel"/> + </footer> + </form> + </field> + </record> + + <record id="action_purchase_order_unlock_wizard" model="ir.actions.act_window"> + <field name="name">Reject Reason</field> + <field name="res_model">purchase.order.unlock.wizard</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> + </data> <data> <record id="rfq_order_tree_view_inherit" model="ir.ui.view"> @@ -153,6 +196,9 @@ <field name="logbook_bill_id" optional="hide"/> <field name="status_printed" optional="hide"/> </field> + <field name="partner_id" position="after"> + <field name="store_name" optional="hide"/> + </field> </field> </record> </data> diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index 7e759e31..bd664890 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -56,6 +56,9 @@ <field name="npwp" position="before"> <field name="customer_type" required="1"/> </field> + <field name="alamat_lengkap_text" position="after"> + <field name="nitku" /> + </field> <field name="is_berikat" position="after"> <field name="pakta_integritas"/> </field> diff --git a/indoteknik_custom/views/res_users.xml b/indoteknik_custom/views/res_users.xml index d7a6b2dd..9553bb91 100644 --- a/indoteknik_custom/views/res_users.xml +++ b/indoteknik_custom/views/res_users.xml @@ -5,7 +5,7 @@ <field name="model_id" ref="base.model_res_users"/> <field name="subject">Aktivasi Akun - Indoteknik.com</field> <field name="email_from">"Indoteknik.com" <noreply@indoteknik.com></field> - <field name="reply_to">noreply@indoteknik.com</field> + <field name="reply_to">sales@indoteknik.com</field> <field name="email_to">${object.login | safe}</field> <field name="body_html" type="html"> <table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Inter, Helvetica, Verdana, Arial,sans-serif; line-height: 24px; color: #454748; width: 100%; border-collapse:separate;"> @@ -45,6 +45,11 @@ <tr><td style="padding-bottom: 2px;">Hormat kami,</td></tr> <tr><td style="padding-bottom: 2px;">PT. Indoteknik Dotcom Gemilang</td></tr> <tr> + <td valign="middle" align="left"> + <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2135765" alt="Indoteknik" style="max-width: 50%; height: auto;"></img> + </td> + </tr> + <tr> <td style="text-align:center;"> <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> @@ -65,7 +70,7 @@ <field name="model_id" ref="base.model_res_users"/> <field name="subject">Email Pendaftaran Bisnis dalam Proses Review</field> <field name="email_from">"Indoteknik.com" <noreply@indoteknik.com></field> - <field name="reply_to">noreply@indoteknik.com</field> + <field name="reply_to">sales@indoteknik.com</field> <field name="email_to">${object.login | safe}</field> <field name="body_html" type="html"> <table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Inter, Helvetica, Verdana, Arial,sans-serif; line-height: 24px; color: #454748; width: 100%; border-collapse:separate;"> @@ -105,6 +110,76 @@ <tr><td style="padding-bottom: 2px;"><strong>Hormat kami,</strong></td></tr> <tr><td style="padding-bottom: 2px;">Indoteknik.com</td></tr> <tr> + <td valign="middle" align="left"> + <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2135765" alt="Indoteknik" style="max-width: 50%; height: auto;"></img> + </td> + </tr> + <tr> + <td style="text-align:center;"> + <hr width="100%" + style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> + </td> + </tr> + </table> + </td> + </tr> + <!-- CONTENT --> + </tbody> + </table> + </td></tr> + </table> + </field> + </record> + <record id="mail_template_res_user_company_request_switch" model="mail.template"> + <field name="name">Users: Company Request</field> + <field name="model_id" ref="base.model_res_users"/> + <field name="subject">Email Pendaftaran Bisnis dalam Proses Review</field> + <field name="email_from">"Indoteknik.com" <noreply@indoteknik.com></field> + <field name="reply_to">sales@indoteknik.com</field> + <field name="email_to">${object.login | safe}</field> + <field name="body_html" type="html"> + <table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Inter, Helvetica, Verdana, Arial,sans-serif; line-height: 24px; color: #454748; width: 100%; border-collapse:separate;"> + <tr><td align="center"> + <table border="0" cellpadding="0" cellspacing="0" width="590" style="font-size: 13px; padding: 16px; background-color: white; color: #454748; border-collapse:separate;"> + <!-- HEADER --> + <tbody> + <tr> + <td align="center" style="min-width: 590px;"> + <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;"> + <tr> + <td valign="middle"> + <span></span> + </td> + </tr> + + <tr> + <td colspan="2" style="text-align:center;"> + <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> + </td> + </tr> + </table> + </td> + </tr> + <!-- CONTENT --> + <tr> + <td align="center" style="min-width: 590px;"> + <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;"> + <tr><td style="padding-bottom: 24px;"><b>Halo ${object.name},</b></td></tr> + + <tr><td style="padding-bottom: 16px;">Terima kasih atas kepercayaan Anda dengan mendaftarkan bisnis Anda di Indoteknik.com. Permohonan Anda saat ini sedang dalam proses review oleh tim kami.</td></tr> + <tr><td style="padding-bottom: 16px;">Saat ini, kami sedang melakukan pengecekan akhir pada data yang Anda berikan. Proses ini biasanya memakan waktu sekitar 2 x 24 jam.</td></tr> + <tr><td style="padding-bottom: 16px;">Setelah proses review selesai, kami akan segera menginformasikan status akun bisnis Anda melalui email.</td></tr> + <tr><td style="padding-bottom: 16px;">Jika ada pertanyaan lebih lanjut, jangan ragu untuk menghubungi kami di <a href="mailto:sales@indoteknik.com">sales@indoteknik.com</a> atau hubungi whatsapp kami di <a href="https://wa.me/6281717181922">0817-1718-1922</a></td></tr> + <tr><td style="padding-bottom: 16px;">Terima kasih atas perhatiannya.</td></tr> + + <tr><td style="padding-bottom: 2px;"><strong>Hormat kami,</strong></td></tr> + <tr><td style="padding-bottom: 2px;">Indoteknik.com</td></tr> + <tr> + <td valign="middle" align="left"> + <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2135765" alt="Indoteknik" style="max-width: 50%; height: auto;"></img> + </td> + </tr> + <tr> <td style="text-align:center;"> <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> @@ -125,7 +200,7 @@ <field name="model_id" ref="base.model_res_users"/> <field name="subject">Email Pendaftaran Bisnis Berhasil</field> <field name="email_from">"Indoteknik.com" <noreply@indoteknik.com></field> - <field name="reply_to">noreply@indoteknik.com</field> + <field name="reply_to">sales@indoteknik.com</field> <field name="email_to">${object.login | safe}</field> <field name="body_html" type="html"> <table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Inter, Helvetica, Verdana, Arial,sans-serif; line-height: 24px; color: #454748; width: 100%; border-collapse:separate;"> @@ -166,6 +241,74 @@ <tr><td style="padding-bottom: 2px;"><b>Hormat kami,</b></td></tr> <tr><td style="padding-bottom: 2px;">Indoteknik.com</td></tr> <tr> + <td valign="middle" align="left"> + <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2135765" alt="Indoteknik" style="max-width: 50%; height: auto;"></img> + </td> + </tr> + <tr> + <td style="text-align:center;"> + <hr width="100%" + style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> + </td> + </tr> + </table> + </td> + </tr> + <!-- CONTENT --> + </tbody> + </table> + </td></tr> + </table> + </field> + </record> + <record id="mail_template_res_user_company_switch_approve" model="mail.template"> + <field name="name">Users: Switch Account Success</field> + <field name="model_id" ref="base.model_res_users"/> + <field name="subject">Selamat! Bisnis Anda Sudah Naik Kelas Jadi PKP!</field> + <field name="email_from">"Indoteknik.com" <noreply@indoteknik.com></field> + <field name="reply_to">sales@indoteknik.com</field> + <field name="email_to">${object.login | safe}</field> + <field name="body_html" type="html"> + <table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Inter, Helvetica, Verdana, Arial,sans-serif; line-height: 24px; color: #454748; width: 100%; border-collapse:separate;"> + <tr><td align="center"> + <table border="0" cellpadding="0" cellspacing="0" width="590" style="font-size: 13px; padding: 16px; background-color: white; color: #454748; border-collapse:separate;"> + <!-- HEADER --> + <tbody> + <tr> + <td align="center" style="min-width: 590px;"> + <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;"> + <tr> + <td valign="middle"> + <span></span> + </td> + </tr> + + <tr> + <td colspan="2" style="text-align:center;"> + <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> + </td> + </tr> + </table> + </td> + </tr> + <!-- CONTENT --> + <tr> + <td align="center" style="min-width: 590px;"> + <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;"> + <tr><td style="padding-bottom: 24px;"><b>Hai ${object.parent_name},</b></td></tr> + + <tr><td style="padding-bottom: 16px;">Selamat! Akun bisnis Anda di indoteknik.com sekarang sudah resmi menjadi PKP dari yang sebelumnya Non-PKP.</td></tr> + <tr><td style="padding-bottom: 16px;">Jangan lupa untuk mengecek kembali semua data perusahaan kamu, ya. Pastikan NPWP dan informasi Perusahaan lainnya sudah kamu isi dengan benar.</td></tr> + <tr><td style="padding-bottom: 16px;">Kamu juga dapat mengubah informasi perusahaan dengan mengunjungi profil atau <a href="https://indoteknik.com/my/profile">klik disini</a></td></tr> + + <tr><td style="padding-bottom: 2px;">Industrial Supply & Solutions</td></tr> + <tr><td style="padding-bottom: 2px;">Tim Indoteknik.com</td></tr> + <tr> + <td valign="middle" align="left"> + <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2135765" alt="Indoteknik" style="max-width: 50%; height: auto;"></img> + </td> + </tr> + <tr> <td style="text-align:center;"> <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> @@ -186,7 +329,7 @@ <field name="model_id" ref="base.model_res_users"/> <field name="subject">Email Pendaftaran Bisnis Tidak Berhasil</field> <field name="email_from">"Indoteknik.com" <noreply@indoteknik.com></field> - <field name="reply_to">noreply@indoteknik.com</field> + <field name="reply_to">sales@indoteknik.com</field> <field name="email_to">${object.login | safe}</field> <field name="body_html" type="html"> <table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Inter, Helvetica, Verdana, Arial,sans-serif; line-height: 24px; color: #454748; width: 100%; border-collapse:separate;"> @@ -239,6 +382,11 @@ <tr><td style="padding-bottom: 2px;"><b>Hormat kami,</b></td></tr> <tr><td style="padding-bottom: 2px;">Indoteknik.com</td></tr> <tr> + <td valign="middle" align="left"> + <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2135765" alt="Indoteknik" style="max-width: 50%; height: auto;"></img> + </td> + </tr> + <tr> <td style="text-align:center;"> <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;" /> diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 3539dbf3..008a04ed 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -14,7 +14,7 @@ <button name="sale_order_approve" string="Ask Approval" type="object" - attrs="{'invisible': [('approval_status', 'in', ['pengajuan1', 'pengajuan2', 'approved'])]}" + attrs="{'invisible': [('approval_status', '=', ['approved'])]}" /> <button name="action_web_approve" string="Web Approve" diff --git a/indoteknik_custom/views/user_company_request.xml b/indoteknik_custom/views/user_company_request.xml index 6d5642e6..88d04c64 100644 --- a/indoteknik_custom/views/user_company_request.xml +++ b/indoteknik_custom/views/user_company_request.xml @@ -8,7 +8,7 @@ <field name="user_id"/> <field name="user_company_id"/> <field name="user_input"/> - <field + <field name="is_approve" widget="badge" decoration-success="is_approve == 'approved'" @@ -33,8 +33,8 @@ <field name="similar_company_ids" invisible="1"/> <field name="user_company_id" domain="[('id', 'in', similar_company_ids)]"/> <field name="user_input" readonly="1"/> - <field - name="is_approve" + <field + name="is_approve" required="1" decoration-success="is_approve == 'approved'" decoration-danger="is_approve == 'rejected'" diff --git a/indoteknik_custom/views/user_pengajuan_tempo.xml b/indoteknik_custom/views/user_pengajuan_tempo.xml index f9e747b3..33ad91cf 100644 --- a/indoteknik_custom/views/user_pengajuan_tempo.xml +++ b/indoteknik_custom/views/user_pengajuan_tempo.xml @@ -339,6 +339,6 @@ </record> <!-- Menu item to access Pengajuan Tempo --> - <menuitem id="menu_user_pengajuan_tempo_root" name="Pengajuan Tempo" /> - <menuitem id="menu_user_pengajuan_tempo" name="Pengajuan Tempo Records" parent="menu_user_pengajuan_tempo_root" action="action_user_pengajuan_tempo"/> +<!-- <menuitem id="menu_user_pengajuan_tempo_root" name="Pengajuan Tempo" />--> +<!-- <menuitem id="menu_user_pengajuan_tempo" name="Pengajuan Tempo Records" parent="menu_user_pengajuan_tempo_root" action="action_user_pengajuan_tempo"/>--> </odoo> |
