summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrisusilo48 <tri.susilo@altama.co.id>2025-01-20 09:27:06 +0700
committertrisusilo48 <tri.susilo@altama.co.id>2025-01-20 09:27:06 +0700
commit464292a0eb2b9353f499a541991e4d88a76c2d82 (patch)
treef8287645e73b4c23cad3e3dc50af177d34a51b94
parente3e7f29ad939a774878316e46e10a5c1370fda77 (diff)
parent1b2b27941fcdaa1b1b6ddf2a4851d358abb259eb (diff)
Merge branch 'odoo-production' into feature/integrasi_biteship
# Conflicts: # indoteknik_custom/security/ir.model.access.csv
-rw-r--r--indoteknik_api/controllers/api_v1/partner.py19
-rw-r--r--indoteknik_api/controllers/api_v1/user.py339
-rw-r--r--indoteknik_api/models/res_users.py10
-rw-r--r--indoteknik_custom/models/account_move.py14
-rw-r--r--indoteknik_custom/models/account_move_due_extension.py1
-rw-r--r--indoteknik_custom/models/automatic_purchase.py1
-rw-r--r--indoteknik_custom/models/coretax_fatur.py6
-rw-r--r--indoteknik_custom/models/manufacturing.py2
-rwxr-xr-xindoteknik_custom/models/purchase_order.py155
-rwxr-xr-xindoteknik_custom/models/purchase_order_line.py74
-rw-r--r--indoteknik_custom/models/res_partner.py8
-rwxr-xr-xindoteknik_custom/models/res_users.py10
-rwxr-xr-xindoteknik_custom/models/sale_order.py1
-rw-r--r--indoteknik_custom/models/sale_order_line.py6
-rw-r--r--indoteknik_custom/models/user_company_request.py4
-rw-r--r--indoteknik_custom/models/user_pengajuan_tempo_request.py2
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv1
-rw-r--r--indoteknik_custom/views/account_move.xml3
-rwxr-xr-xindoteknik_custom/views/purchase_order.xml48
-rw-r--r--indoteknik_custom/views/res_partner.xml3
-rw-r--r--indoteknik_custom/views/res_users.xml156
-rwxr-xr-xindoteknik_custom/views/sale_order.xml2
-rw-r--r--indoteknik_custom/views/user_company_request.xml6
-rw-r--r--indoteknik_custom/views/user_pengajuan_tempo.xml4
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" &lt;noreply@indoteknik.com&gt;</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" &lt;noreply@indoteknik.com&gt;</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" &lt;noreply@indoteknik.com&gt;</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" &lt;noreply@indoteknik.com&gt;</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" &lt;noreply@indoteknik.com&gt;</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 &amp; 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" &lt;noreply@indoteknik.com&gt;</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>