from .. import controller from odoo import http from odoo.http import request import json import base64 import mimetypes class Partner(controller.Controller): _name = 'res.partner' prefix = '/api/v1/' def get_partner_child_ids(self, partner_id): partner = request.env[self._name].search([('id', '=', partner_id)], limit=1) if not partner.parent_id: partner_child_ids = [x['id'] for x in partner.child_ids] + [partner.id] if partner.parent_id: partner_child_ids = [x['id'] for x in partner.parent_id.child_ids] partner_child_ids += [partner.parent_id.id] return partner_child_ids @http.route(prefix + 'partner//list/site', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_list_partner_by_id(self, **kw): params = self.get_request_params(kw, { 'id': ['required', 'number'] }) if not params['valid']: return self.response(code=400, description=params) partner_id = params['value']['id'] partner_child_ids = self.get_partner_child_ids(partner_id) partners = request.env['res.partner'].search([('id', 'in', partner_child_ids)]) site_names = set() for partner in partners: if partner.site_id: site_names.add(partner.site_id.name) data = { 'sites': list(site_names) } return self.response(data) @http.route(prefix + 'partner//address', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_partner_address_by_id(self, **kw): params = self.get_request_params(kw, { 'id': ['required', 'number'] }) if not params['valid']: return self.response(code=400, description=params) partner = request.env[self._name].search([('id', '=', params['value']['id'])]) partner = request.env['res.users'].api_address_response(partner) return self.response(partner) @http.route(prefix + 'partner//address', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def write_partner_address_by_id(self, **kw): params = self.get_request_params(kw, { 'id': ['required', 'number'], 'type': ['default:other'], 'name': ['required'], 'email': ['required'], 'mobile': ['required'], 'phone': [''], 'street': ['required'], 'state_id': ['required', 'number', 'alias:state_id'], 'city_id': ['required', 'number', 'alias:kota_id'], 'district_id': ['number', 'alias:kecamatan_id'], 'sub_district_id': ['number', 'alias:kelurahan_id', 'exclude_if_null'], 'zip': ['required'], 'longtitude': [], 'latitude': [], 'address_map': [], 'alamat_lengkap_text': [] }) if not params['valid']: return self.response(code=400, description=params) partner = request.env[self._name].search([('id', '=', params['value']['id'])], limit=1) if not partner: return self.response(code=404, description='User not found') partner.write(params['value']) return self.response({ 'id': partner.id }) @http.route(prefix + 'partner/address', auth='public', methods=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def create_partner_address(self, **kw): params = self.get_request_params(kw, { 'parent_id': ['required', 'number'], 'type': ['default:other'], 'name': ['required'], 'email': ['required'], 'mobile': ['required'], 'phone': [''], 'street': ['required'], 'state_id': ['required', 'number', 'alias:state_id'], 'city_id': ['required', 'number', 'alias:kota_id'], 'district_id': ['number', 'alias:kecamatan_id'], 'sub_district_id': ['number', 'alias:kelurahan_id', 'exclude_if_null'], 'longtitude': [], 'latitude': [], 'address_map': [], 'zip': ['required'] }) if not params['valid']: return self.response(code=400, description=params) partner = request.env[self._name].create([ params['value'] ]) return self.response({ 'id': partner.id, }) @http.route(prefix + 'partner/', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def write_partner_by_id(self, **kw): params = self.get_request_params(kw, { 'id': ['', 'number'], 'name': [], 'company_type_id': ['number'], 'industry_id': ['number'], 'tax_name': ['alias:nama_wajib_pajak'], 'npwp': [], 'alamat_lengkap_text': [], 'street': [], }) # 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'], 'tax_name': ['alias:nama_wajib_pajak'], 'npwp': [], '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') # Filter parameter yang memiliki nilai saja untuk partner params_filtered = {k: v for k, v in params['value'].items() if v} # Filter parameter yang memiliki nilai saja untuk user params_user_filtered = {k: v for k, v in params_user['value'].items() if v} # Update partner dan user hanya dengan parameter yang memiliki nilai if params_filtered: partner.write(params_filtered) if params_user_filtered: user.write(params_user_filtered) # Return response dengan ID partner yang di-update return self.response({ 'id': partner.id }) @http.route(prefix + 'partner/industry', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_partner_industry(self): partner_industry = request.env['res.partner.industry'].search([]) data = [] for industry in partner_industry: full_name = industry.full_name category = full_name.title() if full_name else '-' data.append({ 'id': industry.id, 'name': industry.name, 'category': category }) return self.response(data) @http.route(prefix + 'partner/company_type', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_partner_company_type(self): partner_company_type = request.env['res.partner.company_type'].search([]) data = [] for company_type in partner_company_type: data.append({ 'id': company_type.id, 'name': company_type.name }) return self.response(data) @http.route(prefix + 'partner/payment_term', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_partner_payment_term(self): partner_industry = request.env['account.payment.term'].search([]) data = [] for industry in partner_industry: if 'tempo' in industry.name.lower(): data.append({ 'id': industry.id, 'name': industry.name }) return self.response(data) @http.route(prefix + 'partner/detail-tempo/', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_partner_detail_tempo(self, **kw): params = self.get_request_params(kw, { 'id': ['required', 'number'] }) pengajuan_tempo = request.env['user.pengajuan.tempo'].search([('name_tempo', '=', params['value']['id'])], limit=1) if not pengajuan_tempo: return self.response(code=404, description='pengajuan tempo not found') pengajuan_tempo = request.env['res.partner'].api_single_response(pengajuan_tempo) return self.response(pengajuan_tempo) @http.route(prefix + 'check//tempo', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_check_tempo_partner(self, **kw): partner_id = int(kw.get('partner_id')) partner = request.env['res.partner'].search([('id', '=', partner_id)], limit=1) if not partner: return self.response(code=404, description='Partner not found') partner = partner.parent_id or partner if any(line.days == 0 for line in partner.property_payment_term_id.line_ids): return self.response(code=402, description='Partner not tempo') result_tempo = sum(m.amount_total_signed for m in request.env['account.move'].search([('partner_id', '=', partner.id), ('payment_state', '=', 'not_paid'), ('state', '=', 'posted')])) remaining_limit = partner.blocking_stage - result_tempo if partner.active_limit else None data = { 'name': partner.name, 'payment_term': partner.property_payment_term_id.name, 'amount_due': result_tempo, 'remaining_limit': remaining_limit } return self.response(data) @http.route(prefix + 'check//tempo_progress', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_check_tempo_partner_progres(self, **kw): partner_id = int(kw.get('partner_id')) partner = request.env['res.partner'].search([('id', '=', partner_id)], limit=1) pengajuan_tempo = request.env['user.pengajuan.tempo'].search([('name_tempo', '=', partner.id)], limit=1) if not pengajuan_tempo: return self.response(code=404, description='Partner not found') data = True if pengajuan_tempo.id else False return self.response(data) @http.route(prefix + 'partner/pengajuan_tempo', auth='public', methods=['POST'], csrf=False) @controller.Controller.must_authorized() def write_pengajuan_tempo(self, **kw): id = int(kw.get('partner_id')) user_id = int(kw.get('user_id')) tempo_request = True if kw.get('tempo_request') == 'true' else False pengajuan_tempo = request.env['user.pengajuan.tempo'].search([('name_tempo', '=', user_id)], limit=1) user = request.env['res.partner'].search([('id', '=', id)], limit=1) company_name = kw.get('name', pengajuan_tempo.name_tempo.name) partner_id = request.env['res.partner'].search([('name', 'like', company_name)], limit=1) user_account = self.get_user_by_email(user.user_id.email) params = self.get_request_params(kw, { # informasi perusahaan # 'name': ['required', 'alias:name_tempo'], 'industryId': ['alias:industry_id_tempo'], 'street': ['alias:street_tempo'], 'state': ['alias:state_id_tempo'], 'city': ['alias:city_id_tempo'], 'zip': ['alias:zip_tempo'], 'mobile': ['alias:mobile_tempo'], 'bankName': ['alias:bank_name_tempo'], 'accountName': ['alias:account_name_tempo'], 'accountNumber': ['alias:account_number_tempo'], 'website': ['alias:website_tempo'], 'estimasi': ['alias:estimasi_tempo'], 'tempoDuration': ['alias:tempo_duration'], 'tempoLimit': ['alias:tempo_limit'], # informasi perusahaan 'direkturName': ['alias:direktur_name'], 'direkturMobile': ['alias:direktur_mobile'], 'direkturEmail': ['alias:direktur_email'], 'purchasingName': ['alias:purchasing_name'], 'purchasingMobile': ['alias:purchasing_mobile'], 'purchasingEmail': ['alias:purchasing_email'], 'financeName': ['alias:finance_name'], 'financeMobile': ['alias:finance_mobile'], 'financeEmail': ['alias:finance_email'], # Pengiriman 'PICName': ['alias:pic_name'], 'streetPengiriman': ['alias:street_pengiriman'], 'statePengiriman': ['alias:state_id_pengiriman'], 'cityPengiriman': ['alias:city_id_pengiriman'], 'zipPengiriman': ['alias:zip_pengiriman'], 'invoicePic': ['alias:invoice_pic'], 'streetInvoice': ['alias:street_invoice'], 'stateInvoice': ['alias:state_id_invoice'], 'cityInvoice': ['alias:city_id_invoice'], 'isSameAddrees':['alias:is_same_address'], 'isSameAddreesStreet': ['alias:is_same_address_street'], }) if not params['valid']: return self.response(code=400, description=params) # Filter data baru yang dikirim (non-kosong) new_data = {key: value for key, value in params['value'].items() if value} if pengajuan_tempo: # Jika pengajuan_tempo sudah ada, hanya write data baru yang non-kosong pengajuan_tempo.write(new_data) else: # Jika belum ada, buat record baru pengajuan_tempo = request.env['user.pengajuan.tempo'].create(new_data) pengajuan_tempo.partner_id = user_id if partner_id: pengajuan_tempo.name_tempo = partner_id form_supplier_data = kw.get('formSupplier', False) if form_supplier_data: try: form_supplier_data = json.loads(form_supplier_data) supplier_ids_to_add = [] for item in form_supplier_data: supplier_name = item.get("supplier") pic_name = item.get("pic") phone = item.get("telepon") tempo_duration = item.get("durasiTempo") credit_limit = item.get("creditLimit") new_data = { 'name_supplier': supplier_name, 'pic_name': pic_name, 'phone': phone, 'tempo_duration': tempo_duration, 'credit_limit': credit_limit, } new_supplier_data = request.env['user.pengajuan.tempo.line'].create(new_data) supplier_ids_to_add.append(new_supplier_data.id) pengajuan_tempo.write({'supplier_ids': [(4, supplier_id, 0) for supplier_id in supplier_ids_to_add]}) except json.JSONDecodeError: return http.Response(status=400, json_body={'error': 'Invalid JSON format for formSupplier'}) category_produk_ids = kw.get('categoryProduk', False) category_ids = '' if category_produk_ids: category_ids = list(map(int, category_produk_ids.split(','))) pengajuan_tempo.category_produk_ids = [(6, 0, category_ids)] every_weekday = True if kw.get('everyWeekday') == "true" else False every_weekday_input = kw.get('everyWeekdayInput') every_week = True if kw.get('everyWeek') == 'true' else False every_week_input = kw.get('everyWeekInput') tukar_invoice = True if kw.get('tukarInvoice') == 'true' else False tukar_invoice_input = kw.get('tukarInvoiceInput') jadwal_tukar_invoice = "" if every_weekday: jadwal_tukar_invoice += f"setiap hari {every_weekday_input}" if every_week: jadwal_tukar_invoice += f", setiap {every_week_input}" if tukar_invoice or tukar_invoice_input: jadwal_tukar_invoice += f", {tukar_invoice_input}" if jadwal_tukar_invoice: pengajuan_tempo.tukar_invoice = jadwal_tukar_invoice every_weekday_pembayaran = True if kw.get('everyWeekdayPembayaran') == 'true' else False every_weekday_input_pembayaran = kw.get('everyWeekdayInputPembayaran') every_week_pembayaran = True if kw.get('everyWeekPembayaran') == 'true' else False every_week_input_pembayaran = kw.get('everyWeekInputPembayaran') tukar_invoice_pembayaran = True if kw.get('tukarInvoicePembayaran') == 'true' else False tukar_invoice_input_pembayaran = kw.get('tukarInvoiceInputPembayaran') jadwal_tukar_invoice_pembayaran = "" if every_weekday_pembayaran: jadwal_tukar_invoice_pembayaran += f"setiap hari {every_weekday_input_pembayaran}" if every_week_pembayaran: jadwal_tukar_invoice_pembayaran += f", setiap {every_week_input_pembayaran}" if tukar_invoice_pembayaran or tukar_invoice_input_pembayaran: jadwal_tukar_invoice_pembayaran += f", {tukar_invoice_input_pembayaran}" if jadwal_tukar_invoice_pembayaran: pengajuan_tempo.jadwal_bayar = jadwal_tukar_invoice_pembayaran dokumen_kirim = [ 'Surat Tanda Terima Barang (STTB)', 'Good Receipt (GR)', 'Surat Terima Barang (STB)', 'Lembar Penerimaan Barang (LPB)' ] dokumen_kirim_barang_ids = kw.get('dokumenPengiriman') dokumen_kirim_barang_input = kw.get('dokumenPengirimanInput', '') dokumen_kirim_barang = [] if dokumen_kirim_barang_ids: dokumen_kirim_ids = list(map(int, dokumen_kirim_barang_ids.split(','))) dokumen_kirim_barang = [dokumen_kirim[i] for i in dokumen_kirim_ids if 0 <= i < len(dokumen_kirim)] if dokumen_kirim_barang_input: input_items = [item.strip() for item in dokumen_kirim_barang_input.split(',')] dokumen_kirim_barang.extend(item for item in input_items if item and item not in dokumen_kirim_barang) if dokumen_kirim_barang: pengajuan_tempo.dokumen_pengiriman = ', '.join(dokumen_kirim_barang) dokumen = [ 'Invoice Pembelian', 'Surat Jalan', 'Berita Acara Serah Terima (BAST)', 'Faktur Pajak', 'Good Receipt (GR)' ] dokumen_invoice_ids = kw.get('dokumenPengirimanInvoice') dokumen_invoice_input = kw.get('dokumenPengirimanInvoiceInput', '') dokumen_invoice = "" if dokumen_invoice_ids: dokumen_ids = list(map(int, dokumen_invoice_ids.split(','))) dokumen_invoice = [dokumen[i] for i in dokumen_ids if 0 <= i < len(dokumen)] if dokumen_invoice_input: input_items = [item.strip() for item in dokumen_invoice_input.split(',')] dokumen_invoice.extend(item for item in input_items if item and item not in dokumen_invoice) if dokumen_invoice: pengajuan_tempo.dokumen_invoice = ', '.join(dokumen_invoice) form_dokumen_data = kw.get('formDocs', False) if form_dokumen_data: try: form_dokumen = json.loads(form_dokumen_data) for dokumen in form_dokumen: if dokumen['details']['base64'] != '': mimetype, _ = mimetypes.guess_type(dokumen['details']['name']) mimetype = mimetype or 'application/octet-stream' data = base64.b64decode(dokumen['details']['base64']) sppkp_attachment = request.env['ir.attachment'].create({ 'name': dokumen['details']['name'], 'type': 'binary', 'datas': base64.b64encode(data), 'res_model': 'user.pengajuan.tempo', 'res_id': pengajuan_tempo.id, 'mimetype': mimetype }) if dokumen['documentName'] == 'dokumenNib' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_nib = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenNpwp' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_npwp = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenSppkp' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_sppkp = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenAktaPerubahan' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_akta_perubahan = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenKtpDirut' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_ktp_dirut = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenAktaPendirian' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_akta_pendirian = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenLaporanKeuangan' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_laporan_keuangan = [(4, sppkp_attachment.id)] elif dokumen['documentName'] == 'dokumenFotoKantor' and dokumen['details']['base64'] != '': pengajuan_tempo.dokumen_foto_kantor = [(4, sppkp_attachment.id)] else: pengajuan_tempo.dokumen_tempat_bekerja = [(4, sppkp_attachment.id)] formatted_text = ''.join([' ' + char if char.isupper() and i != 0 else char for i, char in enumerate(dokumen['documentName'])]) teks = formatted_text.strip().title() pengajuan_tempo.message_post(body=teks, attachment_ids=[sppkp_attachment.id]) except json.JSONDecodeError: return http.Response(status=400, json_body={'error': 'Invalid JSON format for formDokumen'}) if tempo_request: tempo_request = request.env['user.pengajuan.tempo.request'].create({ 'user_id': user.id, 'pengajuan_tempo_id': pengajuan_tempo.id, 'user_company_id': partner_id.id, 'tempo_duration': pengajuan_tempo.tempo_duration.id, 'tempo_limit': pengajuan_tempo.tempo_limit, }) pengajuan_tempo.user_id = user_account.id template = pengajuan_tempo.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout') template.send_mail(pengajuan_tempo.id, force_send=True) # user_account.send_activation_mail() return self.response({ 'id': pengajuan_tempo.id, 'user_id': user_id, }) def get_user_by_email(self, email): return request.env['res.users'].search([ ('login', '=', email), ('active', 'in', [True, False]) ])