diff options
Diffstat (limited to 'indoteknik_custom/models/res_partner.py')
| -rw-r--r-- | indoteknik_custom/models/res_partner.py | 247 |
1 files changed, 240 insertions, 7 deletions
diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 7e574a72..ff07c94c 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -2,6 +2,7 @@ from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError from datetime import datetime from odoo.http import request +import re class GroupPartner(models.Model): _name = 'group.partner' @@ -39,6 +40,14 @@ class ResPartner(models.Model): estimasi_tempo = fields.Char(string='Estimasi Pembelian Pertahun') tempo_duration = fields.Many2one('account.payment.term', string='Durasi Tempo') tempo_limit = fields.Char(string='Limit Tempo') + minimum_amount = fields.Float( + string="Minimum Order", + help="Jika total belanja kurang dari ini, maka payment term akan otomatis menjadi CBD." + ) + minimum_amount_tax = fields.Float( + string="Minimum Amount Tax", + help="Jika total belanja kurang dari ini, maka tax akan otomatis menjadi 0%." + ) category_produk_ids = fields.Many2many('product.public.category', string='Kategori Produk yang Digunakan', domain=lambda self: self._get_default_category_domain()) @api.model @@ -58,6 +67,7 @@ class ResPartner(models.Model): # Pengiriman pic_name = fields.Char(string='Nama PIC Penerimaan Barang') + pic_mobile = fields.Char(string='Nomor HP PIC Penerimaan Barang') street_pengiriman = fields.Char(string="Alamat Perusahaan") state_id_pengiriman = fields.Many2one('res.country.state', string='State') city_id_pengiriman = fields.Many2one('vit.kota', string='City') @@ -65,6 +75,7 @@ class ResPartner(models.Model): subDistrict_id_pengiriman = fields.Many2one('vit.kelurahan', string='Kelurahan') zip_pengiriman = fields.Char(string="Zip") invoice_pic = fields.Char(string='Nama PIC Penerimaan Invoice') + invoice_pic_mobile = fields.Char(string='Nomor HP PIC Penerimaan Invoice') street_invoice = fields.Char(string="Alamat Perusahaan") state_id_invoice = fields.Many2one('res.country.state', string='State') city_id_invoice = fields.Many2one('vit.kota', string='City') @@ -73,6 +84,7 @@ class ResPartner(models.Model): zip_invoice = fields.Char(string="Zip") tukar_invoice = fields.Char(string='Jadwal Penukaran Invoice') jadwal_bayar = fields.Char(string='Jadwal Pembayaran') + dokumen_prosedur = fields.Many2one('ir.attachment', string="Dokumen Pengiriman", tracking=3, readonly=True) dokumen_pengiriman = fields.Char(string='Dokumen Tanda Terima yang Diberikan Pada Saat Pengiriman Barang') dokumen_pengiriman_input = fields.Char(string='Dokumen yang Dibawa Saat Pengiriman Barang') dokumen_invoice = fields.Char(string='Dokumen yang dilampirkan saat Pengiriman Invoice') @@ -124,8 +136,8 @@ class ResPartner(models.Model): ('PNR', 'Pareto Non Repeating'), ('NP', 'Non Pareto') ]) - email_finance = fields.Char(string='Email Finance') - email_sales = fields.Char(string='Email Sales') + email_finance = fields.Char(string='Email Finance Vendor') + email_sales = fields.Char(string='Email Sales Vendor') user_payment_terms_sales = fields.Many2one('res.users', string='Users Update Payment Terms') date_payment_terms_sales = fields.Datetime(string='Date Update Payment Terms') @@ -149,6 +161,86 @@ class ResPartner(models.Model): "this feature", tracking=3) telegram_id = fields.Char(string="Telegram") + # MERCHANT + # informasi perusahaan + name_merchant = fields.Char(string='Name') + pejabat_name = fields.Char(string='Pejabat Name') + pic_merchant = fields.Char(string='PIC Merchant', required=True) + pic_position = fields.Char(string='Jabatan PIC') + address_merchant = fields.Char(string='Alamat') + state_merchant = fields.Many2one('res.country.state', string='State') + city_merchant = fields.Many2one('vit.kota', string='Kota') + district_merchant = fields.Many2one('vit.kecamatan', string='Kecamatan') + subDistrict_merchant = fields.Many2one('vit.kelurahan', string='Kelurahan') + zip_merchant = fields.Char(string='Kode Pos') + bank_name_merchant = fields.Char(string='Nama Bank') + rekening_name_merchant = fields.Char(string='Nama Rekening') + account_number_merchant = fields.Char(string='Nomor Rekening Bank') + email_company_merchant = fields.Char(string='Email Perusahaan') + email_sales_merchant = fields.Char(string='Email Sales') + email_finance_merchant = fields.Char(string='Email Finance') + phone_merchant = fields.Char(string='No. Telepon Perusahaan') + mobile_merchant = fields.Char(string='No. Handphone') + bisnis_type = fields.Selection([ + ('1', 'PT'), + ('2', 'CV'), + ('3', 'Perorangan'), + ]) + website_merchant = fields.Char(string='Website') + category_perusahaan = fields.Selection([ + ('1', 'Principal (Pemegang merk/Produsen)'), + ('2', 'Sole Distributor (Distributor Tunggal)'), + ('3', 'Authorized Distributor (Distributor Resmi)'), + ('4', 'Importer (Pengimpor Barang)'), + ('5', 'Wholesaler (Pedagang Besar)'), + ]) + # Informasi Vendor + harga_tayang = fields.Char(string='Harga Tayang (HET)') + category_produk_ids_merchant = fields.Many2many( + 'product.public.category', + string='Kategori Produk Merchant', + domain=lambda self: self._get_default_category_domain(), + relation='res_partner_category_produk_ids_merchant_rel' # Nama tabel relasi berbeda + ) + + @api.model + def _get_default_category_domain(self): + return [('parent_id', '=', False)] + + merk_dagang = fields.Char(string='Merk Dagang') + is_pengajuan_tempo = fields.Boolean(string='Apakah anda memiliki Form Pengajuan Tempo?') + tempo_duration_merchant = fields.Many2one('account.payment.term', string='Durasi Tempo') + kredit_limit = fields.Char(string='Kredit Limit') + waktu_pengiriman = fields.Char(string='Waktu Pengiriman') + terhitung_sejak = fields.Selection([ + ('1', 'Terima PO'), + ('2', 'Barang Dikirimkan'), + ('3', 'Tukar Faktur'), + ]) + + # syarat dagang + is_kembali_barang = fields.Char(string='Syarat Pengembalian Barang') + tenggat_waktu = fields.Char(string='Tenggat Waktu Perubahan Harga') + sertifikat_produk = fields.Char(string='Dokumen/Sertifikat yang Dimiliki Oleh Brand') + custom_sertifikat_produk = fields.Char(string='Dokumen/Sertifikat Lainnya') + tempo_garansi = fields.Selection([ + ('1', '6 Bulan Garansi'), + ('2', '1 Tahun Garansi'), + ('3', '2 Tahun Garansi'), + ]) + explain_garansi = fields.Char(string='Garansi Yang Dimaksudkan') + is_order_quantity = fields.Char(string='Apakah Memiliki Minimum Order Quantity (MOQ)') + + # dokumen + file_npwp = fields.Many2one('ir.attachment', string="NPWP Perusahaan", tracking=3) + file_sppkp = fields.Many2one('ir.attachment', string="SPPKP Perusahaan", tracking=3) + file_dokumenKtpDirut = fields.Many2one('ir.attachment', string="KTP Dirut/Direktur", tracking=3) + file_kartuNama = fields.Many2one('ir.attachment', string="Kartu Nama", tracking=3) + file_suratPernyataan = fields.Many2one('ir.attachment', string="Surat Pernyataan Nomor Rekening", tracking=3) + file_fotoKantor = fields.Many2one('ir.attachment', string="Foto Gudang / Kantor Bagian Depan", tracking=3) + file_dataProduk = fields.Many2one('ir.attachment', string="Data Produk (Item Name, Gambar, Deskripsi)", tracking=3) + file_pricelist = fields.Many2one('ir.attachment', string="Pricelist", tracking=3) + @api.model def _default_payment_term(self): return self.env.ref('__export__.account_payment_term_26_484409e2').id @@ -188,15 +280,41 @@ class ResPartner(models.Model): def _check_duplicate_name(self): for record in self: if record.name: - # Mencari partner lain yang memiliki nama sama (case-insensitive) existing_partner = self.env['res.partner'].search([ - ('id', '!=', record.id), # Hindari mencocokkan diri sendiri - ('name', '=', record.name) # Case-insensitive search + ('id', '!=', record.id), + ('name', '=', record.name), + ('email', '=', record.email) ], limit=1) if existing_partner: raise ValidationError(f"Nama '{record.name}' sudah digunakan oleh partner lain!") + @api.constrains('npwp') + def _check_npwp(self): + for record in self: + npwp = record.npwp.strip() if record.npwp else '' + # Abaikan validasi jika NPWP kosong atau diisi "0" + if not npwp or npwp == '0' or npwp == '00.000.000.0-000.000': + continue + + # Validasi untuk NPWP 15 digit (format: 99.999.999.9-999.999) + if len(npwp) == 20: + # Regex untuk 15 digit dengan format titik dan tanda hubung + pattern_15_digit = r'^\d{2}\.\d{3}\.\d{3}\.\d{1}-\d{3}\.\d{3}$' + if not re.match(pattern_15_digit, npwp): + raise ValidationError("Format NPWP 15 digit yang dimasukkan salah. Pastikan format yang benar adalah: 99.999.999.9-999.999") + + # Validasi untuk NPWP 16 digit (hanya angka tanpa titik atau tanda hubung) + elif len(npwp) == 16: + pattern_16_digit = r'^\d{16}$' + if not re.match(pattern_16_digit, npwp): + raise ValidationError("Format NPWP 16 digit yang dimasukkan salah. Format yang benar adalah 16 digit angka tanpa titik atau tanda hubung.") + + # Validasi panjang NPWP jika lebih atau kurang dari 15 atau 16 digit + else: + raise ValidationError("Digit NPWP yang dimasukkan tidak sesuai. Pastikan NPWP memiliki 15 digit dengan format tertentu (99.999.999.9-999.999) atau 16 digit tanpa tanda hubung.") + + def write(self, vals): # Fungsi rekursif untuk meng-update semua child, termasuk child dari child def update_children_recursively(partner, vals_for_child): @@ -254,6 +372,7 @@ class ResPartner(models.Model): # Pengiriman vals['pic_name'] = vals.get('pic_name', self.pic_name) + vals['pic_mobile'] = vals.get('pic_mobile', self.pic_mobile) vals['street_pengiriman'] = vals.get('street_pengiriman', self.street_pengiriman) vals['state_id_pengiriman'] = vals.get('state_id_pengiriman', self.state_id_pengiriman) vals['city_id_pengiriman'] = vals.get('city_id_pengiriman', self.city_id_pengiriman) @@ -261,6 +380,7 @@ class ResPartner(models.Model): vals['subDistrict_id_pengiriman'] = vals.get('subDistrict_id_pengiriman', self.subDistrict_id_pengiriman) vals['zip_pengiriman'] = vals.get('zip_pengiriman', self.zip_pengiriman) vals['invoice_pic'] = vals.get('invoice_pic', self.invoice_pic) + vals['invoice_pic_mobile'] = vals.get('invoice_pic_mobile', self.invoice_pic_mobile) vals['street_invoice'] = vals.get('street_invoice', self.street_invoice) vals['state_id_invoice'] = vals.get('state_id_invoice', self.state_id_invoice) vals['city_id_invoice'] = vals.get('city_id_invoice', self.city_id_invoice) @@ -269,6 +389,7 @@ class ResPartner(models.Model): vals['zip_invoice'] = vals.get('zip_invoice', self.zip_invoice) vals['tukar_invoice'] = vals.get('tukar_invoice', self.tukar_invoice) vals['jadwal_bayar'] = vals.get('jadwal_bayar', self.jadwal_bayar) + vals['dokumen_prosedur'] = vals.get('dokumen_prosedur', self.dokumen_prosedur) vals['dokumen_pengiriman'] = vals.get('dokumen_pengiriman', self.dokumen_pengiriman) vals['dokumen_pengiriman_input'] = vals.get('dokumen_pengiriman_input', self.dokumen_pengiriman_input) vals['dokumen_invoice'] = vals.get('dokumen_invoice', self.dokumen_invoice) @@ -288,6 +409,60 @@ class ResPartner(models.Model): vals['dokumen_foto_kantor'] = vals.get('dokumen_foto_kantor', self.dokumen_foto_kantor) vals['dokumen_tempat_bekerja'] = vals.get('dokumen_tempat_bekerja', self.dokumen_tempat_bekerja) + # MERCHANT + # Informasi Perusahaan + vals['name_merchant'] = vals.get('name_merchant', self.name_merchant) + vals['pejabat_name'] = vals.get('pejabat_name', self.pejabat_name) + vals['pic_merchant'] = vals.get('pic_merchant', self.pic_merchant) + vals['pic_position'] = vals.get('pic_position', self.pic_position) + vals['address_merchant'] = vals.get('address_merchant', self.address_merchant) + vals['state_merchant'] = vals.get('state_merchant', self.state_merchant) + vals['city_merchant'] = vals.get('city_merchant', self.city_merchant) + vals['district_merchant'] = vals.get('district_merchant', self.district_merchant) + vals['subDistrict_merchant'] = vals.get('subDistrict_merchant', self.subDistrict_merchant) + vals['zip_merchant'] = vals.get('zip_merchant', self.zip_merchant) + vals['bank_name_merchant'] = vals.get('bank_name_merchant', self.bank_name_merchant) + vals['rekening_name_merchant'] = vals.get('rekening_name_merchant', self.rekening_name_merchant) + vals['account_number_merchant'] = vals.get('account_number_merchant', self.account_number_merchant) + vals['email_company_merchant'] = vals.get('email_company_merchant', self.email_company_merchant) + vals['email_sales_merchant'] = vals.get('email_sales_merchant', self.email_sales_merchant) + vals['email_finance_merchant'] = vals.get('email_finance_merchant', self.email_finance_merchant) + vals['phone_merchant'] = vals.get('phone_merchant', self.phone_merchant) + vals['mobile_merchant'] = vals.get('mobile_merchant', self.mobile_merchant) + vals['bisnis_type'] = vals.get('bisnis_type', self.bisnis_type) + vals['website_merchant'] = vals.get('website_merchant', self.website_merchant) + vals['category_perusahaan'] = vals.get('category_perusahaan', self.category_perusahaan) + + # Informasi Vendor + vals['harga_tayang'] = vals.get('harga_tayang', self.harga_tayang) + vals['category_produk_ids_merchant'] = vals.get('category_produk_ids_merchant', self.category_produk_ids_merchant) + vals['merk_dagang'] = vals.get('merk_dagang', self.merk_dagang) + vals['is_pengajuan_tempo'] = vals.get('is_pengajuan_tempo', self.is_pengajuan_tempo) + vals['tempo_duration_merchant'] = vals.get('tempo_duration_merchant', self.tempo_duration_merchant) + vals['kredit_limit'] = vals.get('kredit_limit', self.kredit_limit) + vals['waktu_pengiriman'] = vals.get('waktu_pengiriman', self.waktu_pengiriman) + vals['terhitung_sejak'] = vals.get('terhitung_sejak', self.terhitung_sejak) + + # Syarat Dagang + vals['is_kembali_barang'] = vals.get('is_kembali_barang', self.is_kembali_barang) + vals['tenggat_waktu'] = vals.get('tenggat_waktu', self.tenggat_waktu) + vals['sertifikat_produk'] = vals.get('sertifikat_produk', self.sertifikat_produk) + vals['custom_sertifikat_produk'] = vals.get('custom_sertifikat_produk', self.custom_sertifikat_produk) + vals['tempo_garansi'] = vals.get('tempo_garansi', self.tempo_garansi) + vals['explain_garansi'] = vals.get('explain_garansi', self.explain_garansi) + vals['is_order_quantity'] = vals.get('is_order_quantity', self.is_order_quantity) + + # Dokumen + vals['file_dokumenKtpDirut'] = vals.get('file_dokumenKtpDirut', self.file_dokumenKtpDirut) + vals['file_kartuNama'] = vals.get('file_kartuNama', self.file_kartuNama) + vals['file_npwp'] = vals.get('file_npwp', self.file_npwp) + vals['file_sppkp'] = vals.get('file_sppkp', self.file_sppkp) + vals['file_suratPernyataan'] = vals.get('file_suratPernyataan', self.file_suratPernyataan) + vals['file_fotoKantor'] = vals.get('file_fotoKantor', self.file_fotoKantor) + vals['file_dataProduk'] = vals.get('file_dataProduk', self.file_dataProduk) + vals['file_pricelist'] = vals.get('file_pricelist', self.file_pricelist) + vals['description'] = vals.get('description', self.description) + # Simpan hanya field yang perlu di-update pada child vals_for_child = { 'customer_type': vals.get('customer_type'), @@ -323,6 +498,7 @@ class ResPartner(models.Model): 'finance_mobile': vals.get('finance_mobile'), 'finance_email': vals.get('finance_email'), 'pic_name': vals.get('pic_name'), + 'pic_mobile': vals.get('pic_mobile'), 'street_pengiriman': vals.get('street_pengiriman'), 'state_id_pengiriman': vals.get('state_id_pengiriman'), 'city_id_pengiriman': vals.get('city_id_pengiriman'), @@ -330,6 +506,7 @@ class ResPartner(models.Model): 'subDistrict_id_pengiriman': vals.get('subDistrict_id_pengiriman'), 'zip_pengiriman': vals.get('zip_pengiriman'), 'invoice_pic': vals.get('invoice_pic'), + 'invoice_pic_mobile': vals.get('invoice_pic_mobile'), 'street_invoice': vals.get('street_invoice'), 'state_id_invoice': vals.get('state_id_invoice'), 'city_id_invoice': vals.get('city_id_invoice'), @@ -338,6 +515,7 @@ class ResPartner(models.Model): 'zip_invoice': vals.get('zip_invoice'), 'tukar_invoice': vals.get('tukar_invoice'), 'jadwal_bayar': vals.get('jadwal_bayar'), + 'dokumen_prosedur': vals.get('dokumen_prosedur'), 'dokumen_pengiriman': vals.get('dokumen_pengiriman'), 'dokumen_pengiriman_input': vals.get('dokumen_pengiriman_input'), 'dokumen_invoice': vals.get('dokumen_invoice'), @@ -356,7 +534,55 @@ class ResPartner(models.Model): 'dokumen_tempat_bekerja': vals.get('dokumen_tempat_bekerja'), # internal_notes - 'comment': vals.get('comment') + 'comment': vals.get('comment'), + + # Merchant + 'name_merchant': vals.get('name_merchant'), + 'pejabat_name': vals.get('pejabat_name'), + 'pic_merchant': vals.get('pic_merchant'), + 'pic_position': vals.get('pic_position'), + 'address_merchant': vals.get('address_merchant'), + 'state_merchant': vals.get('state_merchant'), + 'city_merchant': vals.get('city_merchant'), + 'district_merchant': vals.get('district_merchant'), + 'subDistrict_merchant': vals.get('subDistrict_merchant'), + 'zip_merchant': vals.get('zip_merchant'), + 'bank_name_merchant': vals.get('bank_name_merchant'), + 'rekening_name_merchant': vals.get('rekening_name_merchant'), + 'account_number_merchant': vals.get('account_number_merchant'), + 'email_company_merchant': vals.get('email_company_merchant'), + 'email_sales_merchant': vals.get('email_sales_merchant'), + 'email_finance_merchant': vals.get('email_finance_merchant'), + 'phone_merchant': vals.get('phone_merchant'), + 'mobile_merchant': vals.get('mobile_merchant'), + 'bisnis_type': vals.get('bisnis_type'), + 'website_merchant': vals.get('website_merchant'), + 'category_perusahaan': vals.get('category_perusahaan'), + 'harga_tayang': vals.get('harga_tayang'), + 'category_produk_ids_merchant': vals.get('category_produk_ids_merchant'), + 'merk_dagang': vals.get('merk_dagang'), + 'is_pengajuan_tempo': vals.get('is_pengajuan_tempo'), + 'tempo_duration_merchant': vals.get('tempo_duration_merchant'), + 'kredit_limit': vals.get('kredit_limit'), + 'waktu_pengiriman': vals.get('waktu_pengiriman'), + 'terhitung_sejak': vals.get('terhitung_sejak'), + 'is_kembali_barang': vals.get('is_kembali_barang'), + 'tenggat_waktu': vals.get('tenggat_waktu'), + 'sertifikat_produk': vals.get('sertifikat_produk'), + 'custom_sertifikat_produk': vals.get('custom_sertifikat_produk'), + 'tempo_garansi': vals.get('tempo_garansi'), + 'explain_garansi': vals.get('explain_garansi'), + 'is_order_quantity': vals.get('is_order_quantity'), + + 'file_dokumenKtpDirut': vals.get('file_dokumenKtpDirut'), + 'file_kartuNama': vals.get('file_kartuNama'), + 'file_npwp': vals.get('file_npwp'), + 'file_sppkp': vals.get('file_sppkp'), + 'file_suratPernyataan': vals.get('file_suratPernyataan'), + 'file_fotoKantor': vals.get('file_fotoKantor'), + 'file_dataProduk': vals.get('file_dataProduk'), + 'file_pricelist': vals.get('file_pricelist'), + 'description': vals.get('description'), } # Lakukan update pada semua child secara rekursif @@ -456,6 +682,8 @@ class ResPartner(models.Model): def _onchange_customer_type(self): if self.customer_type == 'nonpkp': self.npwp = '00.000.000.0-000.000' + elif self.customer_type == 'pkp': + self.npwp = '00.000.000.0-000.000' def get_check_payment_term(self): self.ensure_one() @@ -470,4 +698,9 @@ class ResPartner(models.Model): 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 + raise UserError("NITKU harus memiliki tepat 22 angka.") + + @api.onchange('name') + def _onchange_name(self): + if self.company_type == 'person': + self.nama_wajib_pajak = self.name
\ No newline at end of file |
